简介:面向使用 Smartbi 制作电子表格报表的报表开发与数据分析人员,这份《Smartbi报表设置文档》围绕报表从建样式到发布的完整设置流程展开,适合需要快速上手或规范报表排版、参数逻辑的初中级使用者。资源包仅含1个docx文档,大小约1.05MB,内容按引用模板、页面设置、隔行不同颜色、列宽自适应、参数设置、参数排版、预览发布等模块组织,并给出宏脚本示例,便于对照实现列宽自适应、起止日期先后与90天跨度校验等常见需求。文档还说明冻结行范围、筛选项居左与每行参数数量控制等排版细节,可作为报表模板搭建和细节调优时的查阅材料。目前已有1305人学习下载,适合希望减少重复调试、补齐 Smartbi 报表设置操作细节的读者参考。
1. 照着 Smartbi 报表设置文档一步步点,模板开了、颜色刷了,预览时列宽还是挤成一团
照着《Smartbi 报表设置文档》一步步点,模板打开了、颜色也刷上了,预览的时候却一片空白,宏里那段列宽自适应的代码像是没长眼睛——这种现场我遇到过不止一次。问题基本不在步骤本身,而在装之前没人核对过 Excel 是 32 位还是 64 位、插件包跟服务器是不是同一套、宏安全级别有没有把脚本拦在门外。电子表格报表这套东西在企业里太常见了,财务日报、运营周报、生产看板,一大半固定格式报表都靠它出。装不顺的代价很直接:样式在本地调得漂漂亮亮,发布上去排版错位,参数校验形同虚设,用户能把结束日期选到开始日期前一年。下面按我实际装过的一套流程走:先对齐环境,再装插件、引模板,然后一层层把样式、宏、参数配上去,最后给出验证和救急的办法。第一次上手这套插件的人能照着走通,被叫去帮别人装的人也能看到几个容易忽略的取舍。
2. Excel 插件安装与登录:把客户端接到报表服务器上
这一章的目标很单一:让 Excel 的 Smartbi 页签正常出现、能登录、能拉到模板列表。三件事任何一件没成,后面所有样式和宏都是白搭。我一般把这一章拆成三轮做——环境核对、安装登录、引模板,每一轮都有可以逐条打勾的检查点,不靠感觉。
2.1 装之前先对齐的四项环境
插件装不上或者装上不生效,九成是环境项没对齐。最常见的四种翻车:Excel 位数跟安装包位数不一致,Smartbi 页签直接不出现或者点了没反应;机器上 .NET Framework 版本太低,安装程序跑到最后一步回滚;Excel 宏安全级别是默认的「禁用所有宏」,宏管理里写得再对也不会执行;账号对模板目录没有读权限,登录是成功的但模板列表一片空白。
先把这张表在纸上过一遍,比装完再回头查要省事得多。
| 环境项 | 建议取值 | 不满足会怎样 |
|---|---|---|
| Excel 位数 | 与插件安装包一致(同为 32 位或同为 64 位) | 页签不出现,或点按钮无响应 |
| .NET Framework | 4.x(加载项依赖的运行库) | 安装到最后一步回滚,报运行库缺失 |
| 宏安全级别 | 启用所有宏,或把模板目录加进受信任位置 | 宏不执行,参数校验完全失效 |
| 服务器连通性 | 能访问报表服务器地址与端口 | 登录长时间转圈,模板列表空白 |
| 账号权限 | 模板目录可读、宏管理可写 | 打开模板提示无权限,保存的宏丢失 |
位数这件事不要靠猜。即点即用方式安装的 Office,注册表里记着位宽;传统 MSI 安装的机器读不到,就靠 EXCEL.EXE 落在哪个 Program Files 目录来判断,这个办法最稳。
# 方法一:即点即用(ClickToRun)安装方式会记录位宽和版本 Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" -ErrorAction SilentlyContinue | Select-Object Platform, VersionToReport # 方法二:直接找 EXCEL.EXE 落盘路径 # 落在 "Program Files" 下是 64 位,落在 "Program Files (x86)" 下是 32 位 Get-ChildItem "C:\Program Files\Microsoft Office","C:\Program Files (x86)\Microsoft Office" ` -Filter EXCEL.EXE -Recurse -ErrorAction SilentlyContinue | Select-Object -First 3 FullName第一条命令读的是即点即用安装方式写进注册表的Platform字段,值一般是 x86 或 x64,MSI 安装的机器上这个键不存在,命令会静默返回空,所以要有第二条兜底。第二条命令是按磁盘路径反推,Program Files与Program Files (x86)的区分就是 32/64 位的分界线,输出里FullName前面那段路径就是答案。-Recurse会遍历整个 Office 目录,慢一点但不会漏;-ErrorAction SilentlyContinue是为了在某个目录不存在时不刷一屏红字。
运行库版本顺带一起看,避免装到一半才发现缺东西:
# 查 .NET Framework 4.x 是否已安装:Release 有值基本说明 4.x 在位 Get-ChildItem "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -ErrorAction SilentlyContinue | Get-ItemProperty -Name Release, Version | Select-Object Version, ReleaseRelease是个数值键,对照版本表能看出具体是小版本几,这里不展开列数字,判断标准简单:输出不是空、Version是 4.x 开头,就说明插件需要的运行库在位。输出为空的话,别硬装,先把运行库补齐,否则安装程序会在最后一步回滚,前面点的一堆下一步全白费。
还有一项容易被跳过:装之前把 Excel 进程彻底清掉。任务管理器里只要还挂着EXCEL.EXE,安装程序替换加载项文件时就会提示占用,即便点了忽略,装完打开 Excel 也可能还是旧版本。我一般直接结束所有 Excel 进程,再以管理员身份运行安装包。
2.2 插件安装与登录服务器
安装本身没什么技术含量,顺序错了才麻烦。步骤按下面这个顺序走,中间不要跳步:
- 结束所有 Excel 进程,任务管理器确认
EXCEL.EXE列表为空。 - 右键安装包,以管理员身份运行。
- 位数选择与上一步查到的 Excel 位数一致,不要选「自动检测」图省事。
- 装完首次启动 Excel,弹出加载项安全提示时选择启用。
- 打开 Excel,确认顶部出现 Smartbi 页签,按钮不是灰的。
- 点登录,填服务器地址、用户名、密码。
服务器地址这一步有讲究。填的是应用访问地址,一般是http://主机:端口/应用名这种形态,不要直接把浏览器里打开某张报表的完整长链接粘进去。长链接里带着报表 ID 和会话参数,插件解析不了,表现就是点登录后转很久然后报连接失败,但用浏览器打开同一个地址又是正常的,很容易误判成网络问题。
判断登录成功的标志不是弹窗提示,而是模板列表能正常拉出来。登录成功后点「模板」,列表里能看到目录树和模板条目,说明账号权限、服务器连通、插件版本三样都过了。列表空白但登录提示成功,基本就是账号对模板目录没有读权限,找管理员开权限比在本地反复重装有效。
2.3 引用模板:别从空报表开始设计
登录通了之后,第一件事是引用模板,不是新建空报表。这一步在《Smartbi 报表设置文档》里写得很靠前,但很多人会跳过,觉得空报表更干净。吃过一次亏就懂了:模板上已经绑好了数据集、参数定义和样式约定,从空报表开始,参数要自己一个个重新绑,绑漏一个,后面getParameterValue取到的就是 undefined,校验宏静默失效,排查起来能耗掉半天。
具体操作路径是固定的:
- 在 Excel 的 Smartbi 页签下点「模板」。
- 在模板目录里找到目标模板,双击打开。
- 打开后立刻另存为一份新的报表文件,改个能区分的名字。
- 在新的这份上设计报表样式,原始模板保持不动。
- 改完保存到服务器对应目录。
第三步的另存为不是洁癖。直接改原模板,一旦样式调坏了,回滚要靠服务器端的版本记录,而很多环境根本没开版本管理。另存一份,最差也就是删掉重来,后悔药提前备好。
打开模板后看到的界面跟普通 Excel 差别不大,区别在于多了一层 Smartbi 的数据绑定关系,单元格里显示的是数据集字段占位或者上一次刷新的缓存值。这时候直接改格式是安全的,删行删列要小心——删掉的可能是绑定了字段的行,刷新后数据对不上。我一般的做法是先在空白区域试排版,确认行列结构没问题,再往模板正式区域上套。
3. 样式层配置:页面设置、隔行变色与列宽自适应宏
样式这一层是给人看的,但坑往往是给机器挖的。页面设置影响打印和导出,隔行变色影响可读性,列宽自适应影响观感,三者有一个共同点:本地调好不等于发布后也对。这一章按「先定页面骨架、再上颜色、最后交给宏」的顺序推进,每一步都给出可对照的配置值。
3.1 页面设置:第一行空白行和冻结 1-5 行的账
模板的第一行是空白行,这个设计不是随手留的。它一般用来放报表标题、统计口径说明或者生成时间,也可能是给参数区预留的空间。副作用是:肉眼看到的第 1 行是空的,真正的表头从第 2 行开始,等到要冻结窗格的时候,行号账就对不上了。
冻结的目标是让表头在滚动时始终可见。既然表头占的是第 2 到第 5 行,冻结就要覆盖前 5 行。操作上不要一行行数,直接选中第 6 行的行号,再执行冻结,冻结的就是它上面的 5 行。这一点跟 Excel 的冻结窗格逻辑一致:冻结的是选中行之上、选中列之左的区域。
页面设置的其他项按下面这张表配,打印和导出的观感基本就稳了:
| 设置项 | 建议值 | 说明 |
|---|---|---|
| 纸张 | A4 | 大多数内部报表的输出尺寸 |
| 方向 | 横向 | 列数多时纵向必然被压缩到看不清 |
| 缩放 | 调整为 1 页宽 | 列多时自动压缩,避免出现半列跨页 |
| 冻结行数 | 5 | 对应第一行空白行 + 四行表头 |
| 打印标题行 | 第 1-5 行 | 多页输出时每页都带表头 |
缩放这一项尤其值得强调。列数一多,默认设置下最右边那列会被切到第二页,打印出来是一张缺角的报表,而且这种问题在预览界面不一定看得明显。设成「调整为 1 页宽」之后,列多的时候会自动压缩比例,虽然字会变小,但至少是完整的。
提示:第一行留空这个约定要写进模板说明里。换个人接手,看到第一行是空的,很可能顺手删掉或者往上顶一行,冻结行数就全错了,而且这种错误在滚动之前完全看不出来。
3.2 隔行不同颜色:条件格式的公式要跟着起始行偏移
隔行变色看着简单,做错的方式却不少。最省事的做法是用条件格式加公式,而不是手动一行行填色——手动填色在插入或删除行之后会整体错位,而且数据量一大,改一次颜色要重来一遍。
规则建在数据区的第一行上,公式写法是=MOD(ROW(),2)=0。这个公式的含义是:当前行号除以 2 余数为 0 时命中规则。听起来没问题,但真正落到报表上经常出现「从表头就开始染色」或者「相邻两行同色」的现象,原因是数据区不是从第 1 行开始的。
假设数据区从第 6 行开始,公式就要改成带偏移的写法:
=MOD(ROW()-6,2)=0ROW()返回当前单元格的行号,减去起始行号 6 之后,数据区第一行变成 0,第二行变成 1,奇偶就对齐了。如果起始行是第 7 行,就把 6 换成 7,这个数字必须跟着数据区首行改,不能照抄。
应用范围同样要注意,不要图快直接选整列。整列刷条件格式,Excel 会把一百万行都纳入计算,文件体积和打开速度都会受影响,导出时也会变慢。正确的范围是数据区实际的行列区间,比如$A$6:$H$200,行数留出余量即可。
颜色选择上,隔行色的对比度要低。深色交替会让整张表看起来像斑马线,打印成黑白后灰度差反而干扰阅读。浅灰、浅蓝这类低饱和度的填充色是常见做法,正文单元格保持白底,只给数据行交替上色。
3.3 列宽自适应宏:宏管理里那段脚本的参数含义
列宽靠手动拖,一百列的表能拖到怀疑人生。Smartbi 提供的方式是在宏管理里写一段脚本,让报表刷新时自动把列宽调到合适值。这段脚本是通用的,换个报表基本不用改:
function main(spreadsheetReport) { var sheet = spreadsheetReport.workbook.worksheets.get(0); if (sheet === "" || sheet === null) { return; } var counts = sheet.cells.maxDisplayRange.columnCount; //获取电子表格列数 sheet.autoFitColumns(0, counts); //从 0 开始,到 counts 列结束。 //sheet.autoFitColumn(3); //只对某列进行自适应,第一列为 0 }逐行拆开看。main是入口函数名,不能改,改成别的名字框架就找不到调用点,宏等于没写。spreadsheetReport.workbook.worksheets.get(0)取的是工作簿里的第一张表,参数 0 是索引,从 0 开始计数,多页签的报表要按实际顺序取对应索引。紧接着那个判空是为了防止取到空表时后面报错,虽然写法上跟空字符串比较看起来有点怪,但保留着没坏处。
sheet.cells.maxDisplayRange.columnCount拿的是当前显示区域的最大列数,注意是显示区域不是全部列,隐藏列不计入。如果报表有动态列,这个值在每次刷新时可能不同,所以不能写死。sheet.autoFitColumns(0, counts)是区间自适应,第一个参数是起始列索引(0 表示第一列),第二个参数是结束列索引,传counts表示一路处理到最后一列。
最后那行被注释掉的sheet.autoFitColumn(3)是单列自适应的写法,参数 3 表示第四列(索引从 0 起)。调试阶段特别有用:整表自适应之后发现某一列宽得离谱,可以先把全局那行注掉,只对可疑列单独处理,快速定位是哪一列的内容把宽度撑开了。
宏新建的位置在 Excel 的 Smartbi 页签下,点「宏管理」,新建宏,把上面这段贴进去,命名保存。保存后刷新报表看效果,没生效先别怀疑代码,去看宏的触发对象选没选对——选成了别的事件,代码再对也不会跑。
注意:这段宏和后面第 4 章的参数校验宏都叫
main。如果两张宏分开建,逻辑上不会互相覆盖,但都挂在同一个报表上时,执行顺序不受控。稳妥做法是把两段逻辑合并进同一个宏里,用不同的内部函数拆开,main里依次调用,避免出现「列宽生效了、校验失效了」这种灵异现象。
4. 参数层配置:日期区间校验宏与参数排版
样式层解决的是好看,参数层解决的是不出错。报表参数一旦放开,用户能选出来的组合远超设计时的假设,结束日期早于开始日期是最常见的一种。这一章把校验宏拆成两件事讲:先把参数名对齐,再讲重写刷新方法的写法,最后落到参数区的排版规则。
4.1 参数名必须先对齐,再谈校验
校验宏里取值靠的是参数名,名字差一个空格都会导致取到 undefined。看这段代码里的写法:getParameterValue("结束日期 2"),注意参数名里那个空格和末尾的数字 2,这是报表里参数的原始名称,不是随手编的。
所以配宏之前先做一件事:打开报表的参数面板,把开始日期、结束日期两个参数的名称原样抄下来,包括空格、括号、编号。抄完之后跟代码里的字符串逐字比对。中文参数名里还容易混进全角空格,肉眼看不出来,取值为空的时候优先怀疑这个。
另外,getParameterValue返回的可能是字符串,也可能因为参数类型是下拉框、区间而返回数组。稳妥写法是套一层字符串转换,避免拿到 undefined 之后replace直接抛错。原始代码没做这层保护,参数没选值时会有报错风险,可以按需补。
4.2 重写 doRefresh:为什么先存一个原函数
校验的关键在于「拦在刷新之前」。参数改完之后,用户点刷新,报表去拉数据,如果参数非法,应该在这一步就弹提示并中断,而不是等数据出来之后再提示。实现方式就是重写doRefresh:
function main(spreadsheetReport) { if (!spreadsheetReport._jhy_doRefresh) { spreadsheetReport._jhy_doRefresh = spreadsheetReport.doRefresh; } spreadsheetReport.doRefresh = function(fromButton, delayMask) { //根据参数名称获取参数值 //结束日期不早于开始日期 var endtime = new Date(spreadsheetReport.getParameterValue("结束日期 2").replace(/\-/g, "/")); var starttime = new Date(spreadsheetReport.getParameterValue("开始日期 2").replace(/\-/g, "/")); if (endtime < starttime) { setTimeout(function() { alert("结束时间不能早于起始时间"); }, 100); return; } //结束日期不大于开始日期 90 天 if (endtime.getTime() - starttime.getTime() > 1000 * 3600 * 24 * 90) { setTimeout(function() { alert("两个参数的差不能超过 90 天"); }, 100); return; } this._jhy_doRefresh(fromButton, delayMask); }; }开头那三行是整段代码的核心。_jhy_doRefresh是个自定义属性,用来暂存原始的doRefresh函数引用。为什么要存?因为下面把spreadsheetReport.doRefresh整个替换掉了,替换之后原函数就丢了,最后一行调用this._jhy_doRefresh(...)时如果没有前面这层保存,就会变成自己调自己,无限递归,页面直接卡死。前面加的if (!spreadsheetReport._jhy_doRefresh)判断是为了防止宏被重复执行时把已保存的原函数覆盖成包装后的版本,那样同样会递归。
new Date(...replace(/\-/g, "/"))这层替换不是多余的。日期字符串形如2024-01-01,在部分 JS 引擎里new Date解析这种带连字符的格式会返回 Invalid Date,换成2024/01/01就稳定了。正则/\-/g里的g表示全局替换,把所有的连字符都换掉,只换第一个的话,后面的连字符还在,照样解析失败。
第一条判断endtime < starttime直接比较两个 Date 对象,JS 会隐式转成时间戳比较,写起来最简洁。第二条判断用的是毫秒差:1000 * 3600 * 24 * 90,即 1000 毫秒 × 3600 秒 × 24 小时 × 90 天。这个公式在跨夏令时的地区会有一小时误差,国内环境不用考虑,但如果是跨国部署,建议改成按日期归一到零点再算天数差。
setTimeout(..., 100)包一层的原因值得说清楚。刷新动作触发时通常有一层遮罩或者加载提示,alert如果在遮罩还没铺开时同步弹出,有的环境下会被遮罩盖住,用户看到的是页面卡住而不是弹窗。延后 100 毫秒,等遮罩稳定了再弹,提示才看得见。return的作用是中断后续流程,不再调用原刷新函数,等于这次刷新被拦下来了。
最后this._jhy_doRefresh(fromButton, delayMask)把原始参数原样透传,保证参数合法时刷新行为和没装宏之前完全一致。
4.3 参数排版:一行不超过 6 个的落位规则
参数区是用户接触报表的第一屏,排版乱不乱直接影响使用体验。规则不复杂,但每条都要落到具体数字上:
- 一行最多放 6 个筛选项,超过就换行。
- 如果排成两行,第二行至少要保留 2 个,不能只剩孤零零一个挂在末尾。
- 筛选项整体居左对齐,不要居中也不要右对齐。
- 标签和输入框的宽度统一,不要一个宽一个窄。
- 参数较多时优先压缩间距,而不是缩小字号。
一行 6 个的上限是经验值。超过 6 个,每个筛选项分到的宽度就不够显示完整日期,用户看到的是被截断的2024-01-...,得点开才知道选没选对。第二行至少保留 2 个,是为了视觉平衡——第一行 6 个、第二行孤零零 1 个,看起来像排版事故,用户会怀疑是不是少加载了什么。
实际操作时先数参数总数,7 个就排成 5 + 2 或者 4 + 3,8 个就 4 + 4 或 5 + 3,不要机械地第一行塞满。日期区间类的参数(开始日期、结束日期)要挨着放,中间不要插别的筛选项,否则用户选完开始日期还要跳着找结束日期。
5. 避坑排查:装完不生效的五类现场
这一章记的是我实际遇到过、并且能复现的问题。每一条按「现象 → 原因 → 解决」写,遇到对得上的直接照着处理,比从头重装快得多。
现象一:Excel 顶部压根没有 Smartbi 页签。原因通常是插件位数跟 Excel 位数不匹配,或者加载项被 Excel 的安全策略禁用了。先按 2.1 的命令确认位数,位数一致的话去 Excel 的选项里看「加载项」和「禁用的应用程序加载项」,把被禁用的项重新启用,重启 Excel。还有一种情况是安装时 Excel 没关干净,文件被占用导致加载项注册失败,卸载重装一次,装之前确保任务管理器里没有EXCEL.EXE。
现象二:宏写好了,刷新时一点反应都没有。原因有三个层次:宏安全级别是「禁用所有宏」;宏的触发对象选错;宏没保存到服务器上,本地改了但刷新加载的是服务器版本。排查顺序从上往下:先看 Excel 宏设置,再看宏管理里触发事件配置,最后关掉本地文件重新从服务器打开一次,确认保存动作真的生效。第三条最隐蔽,本地改了直接点预览能看到效果,一发布就回到原样,因为发布走的是服务器上的宏。
现象三:参数校验弹窗没出现,非法的日期组合照样刷出数据。八成是参数名对不上。getParameterValue("结束日期 2")里的字符串跟报表参数名差一个空格、差一个全角字符,取到的就是空值,new Date(空值)得到 Invalid Date,比较运算永远为 false,两条校验全部放行,表面看就是「宏没生效」。把参数名复制出来跟代码里的字符串做逐字符比对,这类问题基本一次就定位。
现象四:列宽自适应在本地预览正常,发布后列还是挤在一起。检查宏是不是只建在了本地文件的宏管理里,没有随报表一起保存到服务器;另一个常见原因是自适应跑在数据加载之前,拿到的是空表,columnCount算出来偏小,只处理了前几列。解决方式是把自适应放在刷新完成之后执行,或者刷新后手动触发一次,观察宽度是否变化——变了就说明时机问题,没变就说明宏根本没跑。
现象五:冻结窗格之后,滚动时表头错位一行或者多冻结了一行。第一行空白行是罪魁祸首。有人看到第一行是空的,顺手删掉往上提,冻结行数还是按 5 配的,结果多冻了一行数据。处理办法是冻结配置跟模板结构绑死,改结构必须同步改冻结行数,并且改完上下滚动一次验证,不要只看首屏。
注意:这五条里有三条最终都指向「参数名/函数名/时机」这三个点。装这类插件,报错信息往往很含糊,与其猜,不如把能验证的地方先验证一遍——位数对不对、宏跑没跑、参数取到没取到,这三件事查完,剩下的才是代码逻辑问题。
6. 预览发布与验证:用三组极端参数确认这套报表真跑通了
预览发布是文档里的最后一步,但在我看来它只是开始——点发布按钮谁都会点,能证明它跑通才算数。我的习惯是发布前先做一轮参数回归,专挑边界值和非法值,因为正常范围内的组合几乎不会出问题,出问题的永远是边界。
回归就用三组参数,覆盖两个校验分支和一条正常路径:
| 组别 | 开始日期 | 结束日期 | 预期结果 |
|---|---|---|---|
| 第 1 组 | 当天 | 当天减 1 天 | 弹「结束时间不能早于起始时间」,刷新被拦截 |
| 第 2 组 | 当天 | 当天加 91 天 | 弹「两个参数的差不能超过 90 天」,刷新被拦截 |
| 第 3 组 | 当天 | 当天加 90 天 | 正常刷新,数据出得来 |
第 3 组是很多人漏掉的一组。只测非法值不测临界合法值,很容易把判断写成>=,导致刚好 90 天也被拦,用户反馈「差 90 天明明符合要求却报错」,回头改又得重新发布一轮。把 90 天和 91 天各测一次,边界就钉死了。
参数回归过了,接着看样式层的三件事,顺序别乱:
- 向下滚动到数据区中部,确认表头还在,冻结生效且没有多冻一行。
- 横向滚动到最右列,确认列宽没有挤成一团,也没有某一列宽到需要拖滚动条才能看到内容。
- 隔行变色从数据区第一行开始,表头没有被染色,相邻两行颜色不同。
第三件事容易被忽略,因为隔行色错位在屏幕上看不出大问题,但打印出来会很明显:表头一行灰、数据第一行白,整个节奏乱掉,看起来像是数据少了一行。
最后一步是导出和打印的验证,很多人到这一步才发现问题。在预览界面导出一次 PDF 或者直接打印预览,重点看两处:右边有没有列被切到第二页,每页顶部有没有重复表头。前者是缩放没设成「1 页宽」,后者是打印标题行没配。这两项在屏幕预览里都看不出来,非得走一次导出才暴露。
我踩过最深的一次坑,是把所有验证都做在本地文件上,样式、宏、参数全对,发布之后一切照旧。后来才想明白,本地验证的是本地那份文件,服务器上跑的是上一次保存的版本。从那以后我每次发完都强制走一遍「关掉本地文件 → 从服务器重新打开 → 再跑一遍三组参数」,多花五分钟,省掉的是用户那边的一轮返工。
这套流程不复杂,复杂的是每一步都有人觉得可以跳过。环境核对、宏的保存位置、参数名逐字比对、临界值测试,四件事做完,一份 Smartbi 报表基本就能稳定交付了。希望帮到你。
本文还有配套的精品资源,点击获取