15、报表边框设置与单元格颜色高亮技巧

报表边框设置与单元格颜色高亮技巧

在报表制作过程中,边框设置和单元格颜色高亮(Trafficlighting)是提升报表可读性和视觉效果的重要手段。下面将详细介绍如何进行报表边框设置以及不同场景下的单元格颜色高亮方法。

1. 报表边框设置
1.1 产品行值间插入边框

在某些情况下,我们可能需要在产品行(Product Line)的值之间插入边框,以区分不同的数据组。例如,在特定示例中, CUSTOMER_GENDER 的最后一个值在每个 PRODUCT_LINE 值中相同,但数据子集或新版本数据可能会改变这一情况。此操作的目的是演示如何确定 PRODUCT_LINE 分组的最后一行。示例中在 PRODUCT_LINE 的最后一行下方放置了边框,实际上该技术可用于对最后一行进行各种操作,如更改值、颜色或格式。

1.2 表头边框控制

控制报表表头部分的边框可能具有挑战性。表头通常有一行单元格,包含各列的标签。然而,跨距表头(Spanning Headers)和 ACROSS 变量会创建额外的行。 ACROSS 变量会创建一行包含变量值,另一行包含 ACROSS 变量的标签,且每个包含表头的单元格都可单独控制。关键在于明确单元格的创建来源,即变量值、变量标签还是跨距表头。

以下是几个相关示例:
- 示例 6.5:更改 ACROSS 变量表头的边框

proc report data=orders style(report)=[rules=groups]; ❶
column product_line customer_age_group
customer_gender,(quantity total_retail_price); ❷
define product_line / group;
define customer_age_group / group;
define customer_gender / across ”
style(header)=[borderbottomwidth=.1pt
borderbottomcolor=black]; ❸
define total_retail_price / ‘Total Retail Price’;
run;
- ❶ `Rules=groups` 会在表头和数据之间绘制水平边框。
- ❷ 在 `CUSTOMER_GENDER` 后加逗号,并将 `QUANTITY` 和 `TOTAL_RETAIL_PRICE` 置于括号内,会在 `CUSTOMER_GENDER` 的每个值下方放置 `QUANTITY` 和 `TOTAL_RETAIL_PRICE` 列。
- ❸ `Style(header)=` 控制 `CUSTOMER_GENDER` 表头单元格的属性。由于 `CUSTOMER_GENDER` 定义为 `ACROSS` 变量,虽无表头标签,但属性也适用于其值,会在 `M` 和 `F` 值下方绘制底部边框。
  • 示例 6.6:更改跨距表头的边框
ods escapechar=”^”; ❶
proc report data=orders style(report)=[rules=groups]; ❷
column product_line customer_age_group
(‘^{style [borderbottomwidth=.1pt
borderbottomcolor=black]Order value}’
quantity total_retail_price); ❸
define product_line / group;
define customer_age_group / group ;
define total_retail_price / ‘Total Retail Price’;
run;
- ❶ 声明 `ODS ESCAPECHAR`,以便在本例中使用内联格式绘制边框。
- ❷ `Rules=groups` 会在表头和数据之间绘制水平边框。
- ❸ 使用内联格式在跨距表头 “Order value” 下方绘制边框。
  • 示例 6.7:使用内联格式绘制垂直和水平边框
proc report data=orders style(report)=[rules=groups]; ❶
column (‘Product Line’ product_line) ❷
(‘^{style [borderrightwidth=.1pt borderrightcolor=black]}
Customer Age Group’ customer_age_group ) ❸
(‘^{style [borderbottomwidth=.1pt
borderbottomcolor=black]Order value}’ quantity
total_retail_price); ❹
define product_line / group ”; ❺
define customer_age_group / group ”
style(header)=[borderrightwidth=.1pt
borderrightcolor=black]; ❻
define total_retail_price / ‘Total Retail Price’;
run;
- ❶ `Rules=groups` 会在表头和数据之间绘制水平边框。
- ❷ “Product Line” 是跨距表头,会与其他跨距表头对齐。
- ❸ “Customer Age Group” 是跨距表头,会与其他跨距表头对齐。使用内联格式为单元格添加右边框,会在 “Customer Age Group” 和 “Order value” 之间绘制边框线。
- ❹ 使用内联格式在跨距表头 “Order Value” 下方绘制边框。
- ❺ `PRODUCT_LINE` 的列标题设置为空,意味着在第一个数据值上方会放置一个空白单元格。
- ❻ `CUSTOMER_AGE` 的列标题设置为空,意味着在第一个数据值上方会放置一个空白单元格。`Style(header)=` 在空白单元格右侧插入边框,会在 “” 和 “Quantity Ordered” 之间绘制边框线。

TIP :对于某些报表,获得理想的边框可能需要反复试验。可以先移除所有边框,再逐步添加特定边框,直至达到期望的外观。此外,在某些情况下,可能需要在特定位置指定边框,但可将颜色设置为与背景匹配,使其不可见。

以下是一个简单的 mermaid 流程图,展示表头边框设置的大致流程:

graph TD;
    A[开始] --> B[设置报表规则];
    B --> C[定义列和变量];
    C --> D[设置表头样式和边框];
    D --> E[运行报表];
    E --> F[查看结果];
    F --> G{是否满意};
    G -- 是 --> H[结束];
    G -- 否 --> I[调整边框设置];
    I --> B;
2. 单元格颜色高亮(Trafficlighting)

报表创建者常见的任务之一是对某些单元格的背景或前景应用颜色,使其突出显示,这称为单元格颜色高亮。所需的高亮类型取决于报表需求,可基于单元格自身值、其他单元格值来高亮单元格,也可高亮整行或按对角线模式为单元格着色。

2.1 基于单元格值的颜色设置

最常见的技术是根据单元格的值更改其前景或背景颜色,用于突出显示高于或低于特定阈值的值,也可简单区分不同组。颜色分配可在 DEFINE 语句和 CALL DEFINE 语句上进行,两种语句效果相同。

  • 示例 6.8:通过 DEFINE 语句应用背景颜色
proc format;
value pricefmt ❶
. = ‘red’
low - 0 = ‘red’
0 <- 10000 = ‘cxe0ecf4’
10000 <- 30000 =‘cxfe9929’
30000 <- high = ‘yellow’
;
run;
proc report data=orders;
column customer_country quantity costprice_per_unit
total_retail_price;
define customer_country / group format=$cntry.;
define total_retail_price / ‘Retail Price’
style(column)=[background=pricefmt.]; ❷
run;
- ❶ 创建具有所需范围的格式。指定的颜色可以是预定义的 SAS 颜色、RGB 值、HLS 值、RGBA 值或 CMYK 值。
- ❷ 在 `DEFINE` 语句的 `style(column)=` 选项中,设置 `BACKGROUND=` 属性并指定其值为第一步创建的格式名称。每次为 `TOTAL_RETAIL_PRICE` 生成一行时,会根据格式评估值并为背景分配相应颜色。
  • 示例 6.9:通过 CALL DEFINE 语句应用背景颜色
proc report data=orders;
column customer_country quantity costprice_per_unit
total_retail_price;
define customer_country / group format=$cntry.;
define total_retail_price / ‘Retail Price’;
compute total_retail_price;
call define(_col_,‘style’,‘style=[background=pricefmt.]’); ❶
endcomp;
run;
- ❶ 将属性名和值对放在 `CALL DEFINE` 语句的第三个参数中。对列中的每个单元格评估 `TOTAL_RETAIL_PRICE` 的值。

需要注意的是,通过 CALL DEFINE 语句应用样式比通过 DEFINE 语句使用更多的内存和 CPU。因此,如果内存是关注点,且样式可在 DEFINE 语句上应用, DEFINE 语句是更好的选择。

以下是不同颜色设置方式的对比表格:
| 设置方式 | 优点 | 缺点 |
| ---- | ---- | ---- |
| DEFINE 语句 | 内存和 CPU 使用少 | |
| CALL DEFINE 语句 | 灵活性高 | 内存和 CPU 使用多 |

2.2 基于其他报表项的颜色设置

可根据另一列的值为某一列分配颜色高亮。这种情况下,颜色分配必须在计算块内的 CALL DEFINE 语句中完成。要注意将哪个变量放在 COMPUTE 语句上,以及将哪一列作为 CALL DEFINE 语句的第一个参数引用。

  • 示例 6.10:使用 CALL DEFINE 语句更改属性
proc report data=orders;
column customer_country quantity costprice_per_unit
total_retail_price;
define customer_country / group format=$cntry.;
define total_retail_price / ‘Retail Price’;
compute total_retail_price; ❶
if customer_country in (‘US’ ‘DE’ ‘CA’) then ❷
call define(_col_,‘style’,‘style=[background=cxfe9929]’); ❸
else if customer_country = ‘AU’ then
call define(_col_,‘style’,‘style=[background=cxe0ecf4]’);
else
call define(_col_,‘style’,‘style=[background=yellow]’);
endcomp;
run;
- ❶ 将 `TOTAL_RETAIL_PRICE` 放在 `COMPUTE` 语句上,因为要对该列应用颜色,且它是 `COLUMN` 语句中的最后一个变量,其他列的值已填充。
- ❷ 编写 `IF/ELSE IF` 条件,将 `CUSTOMER_COUNTRY` 的值划分为所需的分组。
- ❸ 在 `CALL DEFINE` 语句中,由于 `TOTAL_RETAIL_PRICE` 在 `COMPUTE` 语句上,可使用 `_COL_` 引用作为第一个参数,该列的颜色将改变。在第三个参数中,为每个国家分组分配所需的颜色。
  • 示例 6.11:高亮特定行
proc report data=orders;
column customer_country quantity costprice_per_unit
total_retail_price;
define customer_country / group format=$cntry.;
define total_retail_price / ‘Retail Price’;
compute total_retail_price;
if quantity.sum < 50 then ❶
call define(_row_,‘style’,‘style=[foreground=red
font_weight=bold font_style=italic]’); ❷
endcomp;
run;
- ❶ `IF` 条件指定 `QUANTITY.SUM` 小于 50。`QUANTITY` 是分析变量,在计算块中必须通过变量名.统计量引用。此外,`TOTAL_RETAIL_PRICE` 在 `COLUMN` 语句中列在 `QUANTITY` 之后,因此在该计算块中可获取 `QUANTITY` 的值。
- ❷ `CALL DEFINE` 语句的第一个参数是 `_row_`,意味着样式属性将应用于满足 `IF` 条件的行中的每一列。在第三个参数中,列出三个属性名和值对,以更改前景颜色、字体粗细和字体样式。
  • 示例 6.12:基于颜色变量更改前景颜色
proc report data=orders;
column customer_country customer_group quantity costprice_per_unit
total_retail_price;
define customer_country / group format=$cntry.;
define customer_group / group;
define total_retail_price / mean ‘Mean Retail Price’;
compute total_retail_price; ❶
if index(customer_group,‘Gold’) then color = ‘cxcc4c02’; ❷
else color = ‘black’;
❸ call define(‘customer_group’,‘style’,
‘style=[foreground=’||color||’]’);
call define(‘quantity.sum’,‘style’,
‘style=[foreground=’||color||’]’);
call define(‘costprice_per_unit.sum’,‘style’,
‘style=[foreground=’||color||’]’);
call define(‘total_retail_price.mean’,‘style’,
‘style=[foreground=’||color||’]’);
endcomp;
run;
- ❶ 使用 `TOTAL_RETAIL_PRICE` 在 `COMPUTE` 语句上,因为它是 `COLUMN` 语句中的最后一个变量,且需要为多列分配前景颜色。
- ❷ 创建一个临时变量来保存所需的颜色值。如果 `CUSTOMER_GROUP` 包含 “Gold” 一词,则将颜色分配为金色;否则,将颜色分配为黑色。
- ❸ 对于要修改的每一列,都需要一个 `CALL DEFINE` 语句。根据变量类型(`GROUP` 或 `ANALYSIS`),在第一个参数中使用适当的变量引用。第三个参数使用连接(`||`)运算符构建。注意变量名 `COLOR` 不直接出现在引号内,因为 `COLOR` 是变量名,其值需要连接到字符串中。如果 `COLOR` 在引号内,将不会应用格式,因为 `FOREGROUND=COLOR` 对 `CALL DEFINE` 语句无意义。
2.3 对角线颜色设置

ORDERS 数据集不适合用于演示对角线单元格高亮的实际示例。为演示该技术,创建了一个小数据集。在 PROC REPORT 步骤中,将一列的变量值与另一列的表头进行比较,当值匹配时,相应单元格将被高亮显示。

  • 示例 6.13:按对角线模式为单元格着色
data test; ❶
input x $ a b c;
datalines;
a 1 2 3
b 4 5 6
c 7 8 9
;
run;
%macro rep(colvars);
%local word_cnt ordervar i;
%let word_cnt=%sysfunc(countw(&colvars)); ❷
%let ordervar=%scan(&colvars.,1,’ ‘); ❸
proc report data=test;
col &colvars dummy; ❹
define &ordervar / order;
define dummy / noprint;
compute dummy;
%do i=2 %to &word_cnt; ❺
%let chkvar=%scan(&colvars.,&i.,’ ‘); ❻
if &ordervar=”&chkvar” then call define(
“&chkvar..sum”,‘style’,‘style=[background=cxfe9929]’); ❼
%end;
endcomp;
run;
%mend;
%rep (x a b c) ❽
- ❶ 创建一个数据集,其中一个变量包含其他变量的名称。
- ❷ 计算宏参数 `&COLVARS` 中的变量数量。在本例中,`&WORD_CNT` 解析为 4。
- ❸ 将 `&COLVARS` 的第一个变量分配给宏变量 `&ORDERVAR`。`&ORDERVAR` 解析为 `x`,它是包含其他变量名称的字符变量。
- ❹ 将 `&COLVARS` 和一个 `DUMMY` 变量放在 `COLUMN` 语句中。`DUMMY` 变量将在计算块中使用,以便在按对角线添加颜色时所有值都已就位。
- ❺ `%DO` 循环将从第二列(2)到 `&WORD_CNT`(4)的值,即 `&COLVARS` 中的最后一个变量。
- ❻ 将 `&CHKVAR` 分配给列的名称。每次循环时,`&CHKVAR` 将改变。
- ❼ 使用 `IF` 条件确定 `&ORDERVAR`(`x`)的行值是否与当前列变量相同。当 `IF` 条件为真时,将该单元格的背景更改为橙色。`CALL DEFINE` 语句的第一个参数是 `&CHKVAR` 的当前值后跟 `.sum`,因为变量是数值型,因此默认为分析变量。
- ❽ 宏调用列出最终表中的变量,从包含其他变量名称的字符变量开始。

以下是一个简单的列表,总结对角线颜色设置的步骤:
1. 创建包含特定变量的数据集合。
2. 定义宏并计算变量数量。
3. 设置报表列和变量。
4. 在计算块中循环比较值。
5. 当值匹配时,设置单元格背景颜色。
6. 运行报表。

通过以上方法,我们可以灵活地设置报表的边框和单元格颜色,使报表更加清晰和美观。在实际应用中,可根据具体需求选择合适的方法和技巧。

3. ACROSS 变量下的单元格颜色高亮

在存在 ACROSS 变量的情况下,单元格颜色高亮的操作会更加复杂,因为需要为每个想要应用颜色的列都设置一个赋值语句。

3.1 基于单元格值的颜色设置

下面的示例展示了如何在存在 ACROSS 变量时,根据单元格的值为 TOTAL_RETAIL_PRICE 列设置背景颜色。

  • 示例 6.14:使用格式进行颜色高亮
proc format;
value pricefmt ❶
. = ‘red’
low - 0 = ‘red’
0 <- 10000 = ‘cxe0ecf4’
10000 <- 30000 =‘cxfe9929’
30000 <- high = ‘yellow’
;
run;
options missing=”;
proc report data=orders;
column customer_country customer_age_group,
(quantity costprice_per_unit total_retail_price);
define customer_country / group format=$cntry.;
define customer_age_group /across; ❷
define total_retail_price / ‘Retail Price’
style(column)=[background=pricefmt.]; ❸
run;
- ❶ 创建一个格式,与示例 6.8 中的格式创建方式相同。指定的颜色可以是预定义的 SAS 颜色、RGB 值、HLS 值、RGBA 值或 CMYK 值。
- ❷ 将 `CUSTOMER_AGE_GROUP` 定义为 `ACROSS` 变量,其值将成为表头,并且在每个值下方会有 `QUANTITY`、`COSTPRICE_PER_UNIT` 和 `TOTAL_RETAIL_PRICE` 列。
- ❸ 在 `DEFINE` 语句的 `style(column)=` 选项中,设置 `BACKGROUND=` 属性并指定其值为第一步创建的格式名称。每次为 `TOTAL_RETAIL_PRICE` 输出一行时,会根据格式评估值并为背景分配相应颜色,这会对 `TOTAL_RETAIL_PRICE` 的所有四列都进行操作。

需要注意的是,当添加了 ACROSS 变量后,可能只会看到部分颜色。例如,在这个例子中,缺失值显示为红色,而其他三种颜色可能只出现两种。在应用颜色时,要考虑到在更详细的表格中并非所有颜色都会被使用。

以下是一个 mermaid 流程图,展示在 ACROSS 变量下基于单元格值设置颜色的流程:

graph TD;
    A[开始] --> B[创建格式];
    B --> C[设置报表数据和列];
    C --> D[定义变量和 `ACROSS` 变量];
    D --> E[在 `DEFINE` 语句中设置背景颜色格式];
    E --> F[运行报表];
    F --> G[查看结果];
    G -- 不满意 --> B;
    G -- 满意 --> H[结束];

总结

本文详细介绍了报表制作中边框设置和单元格颜色高亮的相关技巧,包括不同场景下的具体实现方法和示例代码。以下是对这些内容的总结:

操作类型 具体场景 实现方法 示例代码
边框设置 产品行值间 确定分组最后一行并放置边框
表头边框 - ACROSS 变量表头 使用 Style(header)= 控制属性 示例 6.5
表头边框 - 跨距表头 使用内联格式绘制边框 示例 6.6
表头边框 - 垂直和水平边框 使用内联格式和 Style(header)= 组合设置 示例 6.7
单元格颜色高亮 基于单元格值 DEFINE 语句或 CALL DEFINE 语句 示例 6.8、示例 6.9
基于其他报表项 计算块内的 CALL DEFINE 语句 示例 6.10、示例 6.11、示例 6.12
对角线颜色设置 创建数据集并使用宏和计算块 示例 6.13
ACROSS 变量下基于单元格值 DEFINE 语句结合格式 示例 6.14

在实际应用中,可以根据报表的具体需求选择合适的方法。例如,如果对内存使用有要求,优先选择 DEFINE 语句进行颜色设置;如果需要根据复杂条件进行颜色高亮,可使用 CALL DEFINE 语句。同时,通过反复试验和调整,可以获得理想的报表边框和颜色效果,使报表更加清晰、美观且易于理解。

希望这些技巧和方法能帮助你在报表制作中更加得心应手,制作出高质量的报表。如果你在实践过程中遇到任何问题,欢迎随时交流探讨。

提供了基于BP(Back Propagation)神经网络结合PID(比例-积分-微分)控制策略的Simulink仿真模型。该模型旨在实现对杨艺所著论文《基于S函数的BP神经网络PID控制器及Simulink仿真》中的理论进行实践验证。在Matlab 2016b环境下开发,经过测试,确保能够正常运行,适合学习和研究神经网络在控制系统中的应用。 特点 集成BP神经网络:模型中集成了BP神经网络用于提升PID控制器的性能,使之能更好地适应复杂控制环境。 PID控制优化:利用神经网络的自学习能力,对传统的PID控制算法进行了智能调整,提高控制精度和稳定性。 S函数应用:展示了如何在Simulink中通过S函数嵌入MATLAB代码,实现BP神经网络的定制化逻辑。 兼容性说明:虽然开发于Matlab 2016b,但理论上兼容后续版本,可能会需要调整少量配置以适配不同版本的Matlab。 使用指南 环境要求:确保你的电脑上安装有Matlab 2016b或更高版本。 模型加载: 下载本仓库到本地。 在Matlab中打开.slx文件。 运行仿真: 调整模型参数前,请先熟悉各模块功能和输入输出设置。 运行整个模型,观察控制效果。 参数调整: 用户可以自由调节神经网络的层数、节点数以及PID控制器的参数,探索不同的控制性能。 学习和修改: 通过阅读模型中的注释和查阅相关文献,加深对BP神经网络PID控制结合的理解。 如需修改S函数内的MATLAB代码,建议有一定的MATLAB编程基础。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值