ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WorkBuddy+JSA脚本实战:WPS表格数据清洗去重去空

WorkBuddy+JSA脚本实战:WPS表格数据清洗去重去空 在实际办公自动化场景里真正消耗时间的往往不是复杂的业务逻辑而是数据清洗这类基础工作。比如一份从业务系统导出的 Excel 表格里面可能混着重复行、空白单元格、格式不一致的文本手动处理既枯燥又容易漏。最近在 WPS 表格里用 JSAWPS 宏编辑器支持的 JavaScript 语法写脚本处理这类问题时结合 WorkBuddy 的“语音指令转操作”能力基本做到了“靠嘴编程”——不需要手动一行行敲代码而是用自然语言描述需求由 WorkBuddy 生成或修改 JSA 脚本再回到 WPS 宏编辑器运行。这篇文章从一个真实工作实例出发完整拆解如何用 WorkBuddy 辅助编写 JSA 脚本删除数据区域中的重复值和空值覆盖需求拆解、脚本实现、运行验证和踩坑记录。这个实例适合正在用 WPS 表格处理数据清洗的办公人员也适合刚接触 JSA 但不想从零啃文档的开发者。文章不会停留在“WorkBuddy 很强大”这种泛泛介绍而是以“删除重复值和空值”这个具体任务为主线说明每一步的思路、代码和验证方式。读完以后你可以把同样的方法迁移到去空格、格式统一、批量替换等常见清洗场景。1. 先理解 WorkBuddy 和 WPS-JSA 是怎么配合工作的在写脚本之前有必要先厘清两个工具的定位。WPS-JSA 是 WPS 表格内置的宏脚本环境语法基于 JavaScript和 VBA 相比更接近现代前端开发者的习惯。WorkBuddy 则是一款偏 AI 辅助的编程工具支持通过自然语言对话生成代码、解释代码、修改代码。两者结合的工作方式不是“插件集成”而是“人用嘴描述需求AI 输出脚本人再把脚本粘贴到 JSA 编辑器运行”。1.1 WorkBuddy 在“靠嘴编程”流程里承担的角色WorkBuddy 本质上是一个 AI 编程助手它的输入是自然语言提示词输出是代码片段或完整脚本。在 WPS-JSA 的场景里WorkBuddy 不直接操作 WPS也不直接运行宏。它解决的是“脚本怎么写的速度问题”。你只需要告诉它数据在第几列、空值是什么形态、重复值按哪几列判断、删除后是否需要保留表头它就能生成对应的 JSA 代码。这里有一个容易被误解的点“靠嘴编程”不等于完全不用看代码。WorkBuddy 生成的脚本仍然需要你确认逻辑是否符合预期尤其是表格区域的范围、表头位置、删除方向这些细节。AI 生成代码的质量取决于提示词的清晰程度这也是为什么后面会专门花一节讲提示词怎么写。1.2 WPS-JSA 处理数据清洗的基本对象和语法JSA 操作表格的核心对象是Workbook、Worksheet、Range、Cells。删除重复值和空值的需求本质上是两个操作扫描指定区域找出内容完全重复的行删除多余行。扫描指定区域找出内容为空的单元格删除整行或清空内容。工程上推荐“先处理空值再处理重复值”。原因是空值行会让“重复”的判断变得不稳定。如果一行关键列为空它和另一行空值行可能被认为是重复的删除逻辑会变得奇怪。所以先删除空行再按非空区域去重结果更可控。1.3 为什么要用脚本而不是手动操作手动去重可以用 WPS 的“数据”菜单里的“删除重复项”空值也可以用定位条件来处理。但脚本的价值在于可重复和可批量化。同一个清洗逻辑下个月再来一份新数据只需要重新运行宏如果数据量达到几万行手动操作会非常卡脚本执行则快得多。从工程角度看脚本还有日志和检查点。你可以把删除的行数、保留的行数、处理耗时输出到单元格或立即窗口方便验证处理结果。这是手动操作很难做到的。2. 环境准备和最小脚本结构在开始写 JSA 脚本之前先确认环境是否满足要求。WPS-JSA 的入口在 WPS 表格的“开发工具”选项卡里不同版本位置略有差异。WorkBuddy 的安装和使用方式以官方渠道为准不同版本生成的代码风格可能不同本文用到的思路和提示词仍然适用。2.1 环境清单下表列出这个实例需要的最小环境学习环境按最低要求准备即可生产环境再考虑数据量和备份。检查项要求说明WPS Office 版本2019 及以上Windows 平台JSA 宏功能需要开发工具菜单宏安全设置启用宏否则无法运行脚本WorkBuddy 版本可用版本即可需要支持自然语言生成代码数据文件一份包含重复值和空值的表格建议先用几十行测试数据备用方案原始数据备份脚本删除操作不可撤销时能恢复实际项目中如果原始材料没有给出明确版本落地前要先确认依赖版本。WPS 的宏功能在不同版本里默认状态不同有的需要手动打开开发者模式。2.2 进入 JSA 宏编辑器在 WPS 表格里打开测试文件点击“开发工具”选项卡找到“WPS 宏编辑器”。打开后左侧是工程资源管理器右侧是代码编辑区。第一次打开时建议先创建一个空模块避免函数写在ThisWorkbook等对象代码区里造成执行时机混乱。创建模块后在代码区粘贴脚本按 F5 或点击工具栏的“运行”按钮可以执行当前函数。建议把每次执行的函数名统一成一个入口函数例如CleanData()方便反复调用。2.3 WorkBuddy 生成脚本前的提示词模板WorkBuddy 的输入质量直接决定代码质量。同样的需求用“删除重复值”这种模糊描述和用“遍历 A1:D100 区域从第 2 行到最后一行先删除 C 列为空的整行再根据 A、B、C 三列判断重复并保留第一条”这种具体描述生成的代码差异很大。推荐使用以下提示词结构请在 WPS JSAJavaScript for Application的语法下写一个函数 CleanData 功能是 1. 获取当前工作表的已用区域 2. 从最后一行向上遍历删除指定列为空的整行 3. 再从最后一行向上遍历根据指定多列组合判断重复保留第一次出现的行 4. 在立即窗口输出删除的空行数量和重复行数量 5. 不要影响第一行的表头。这个提示词把区域、方向、判断列、表头、输出要求都约束清楚了。后面如果发现代码不符合预期可以继续让 WorkBuddy 修改不需要重新描述完整需求。3. 用 JSA 实现删除空值和重复值这一节是实例的核心。先从一个最简单、最直接的脚本入手再逐步加入备份、统计输出和范围自适应能力。代码都用 JSA 语法可以直接粘贴到 WPS 宏编辑器测试。3.1 先删除空值行从下往上遍历删除空值行时最容易犯的错误是从上往下遍历。如果从第 2 行开始判断发现第 3 行为空并删除原来的第 4 行会变成新的第 3 行但循环变量已经继续往下了导致跳行。所以工程上统一采用从下往上遍历的顺序。下面这段脚本演示了如何删除指定列为空的整行function DeleteEmptyRows() { var sheet ActiveSheet; var lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; // -4162 对应 xlUp表示从底部向上找第一个非空行 var checkCol 3; // 假设用 C 列判断是否为空 for (var i lastRow; i 2; i--) { var cellValue sheet.Cells(i, checkCol).Value; if (cellValue null || cellValue undefined || String(cellValue).trim() ) { sheet.Rows(i).Delete(); } } }这里的关键点有三个。第一End(-4162)的-4162是xlUp的枚举值用来获取有效数据区域的最后一行。第二trim()能处理“看起来是空格但实际不是空”的情况避免漏删。第三sheet.Rows(i).Delete()删除的是整行如果只想清空内容而不是删除行则不要使用Delete。需要注意WPS-JSA 的枚举值有时不支持和 VBA 相同的常量名直接用数值-4162是更稳定的写法。3.2 再删除重复值行按多列组合去重删除重复行的逻辑是从下往上遍历每一行把判断列的取值拼接成一个字符串作为 key如果 key 已经出现过说明这一行是重复行删除如果 key 没出现过记录到对象里。function DeleteDuplicateRows() { var sheet ActiveSheet; var lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; var lastCol sheet.Cells(1, sheet.Columns.Count).End(-4159).Column; // -4159 对应 xlToLeft表示从右向左找第一个非空列 var keyCols [1, 2, 3]; // 按 A、B、C 三列组合判断重复 var seen {}; var deleteCount 0; for (var i lastRow; i 2; i--) { var keyParts []; for (var k 0; k keyCols.length; k) { var col keyCols[k]; var val sheet.Cells(i, col).Value; keyParts.push(val null ? : String(val).trim()); } var key keyParts.join(|); if (seen[key]) { sheet.Rows(i).Delete(); deleteCount; } else { seen[key] true; } } Debug.Print(删除重复行数: deleteCount); }这段代码把Object当作哈希表来记录已经出现过的 key。列数从第 1 列开始不需要处理表头因为循环从lastRow到i 2默认跳过第一行。有一点必须明确这个版本的脚本只保存在内存里没有把“第一次出现的行”做额外标记。如果需要保留的是最后一行而不是第一行遍历方向要反过来处理。多数去重需求默认保留第一次出现的行如果实际场景不是这样需要调整。3.3 组合脚本一个函数完成空值和重复值清理把两个步骤合到一个函数里先清理空值再去重避免重复定义变量名同时保留统计输出。function CleanData() { var sheet ActiveSheet; var lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; var emptyCount 0; var duplicateCount 0; // 第一步删除 C 列为空的行从下往上 var checkCol 3; for (var i lastRow; i 2; i--) { var v sheet.Cells(i, checkCol).Value; if (v null || v undefined || String(v).trim() ) { sheet.Rows(i).Delete(); emptyCount; } } // 第二步重新获取最后一行按 A、B、C 三列去重 lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; var keyCols [1, 2, 3]; var seen {}; for (var j lastRow; j 2; j--) { var keyParts []; for (var k 0; k keyCols.length; k) { var val sheet.Cells(j, keyCols[k]).Value; keyParts.push(val null ? : String(val).trim()); } var key keyParts.join(|); if (seen[key]) { sheet.Rows(j).Delete(); duplicateCount; } else { seen[key] true; } } Debug.Print(空值处理完成删除空行数: emptyCount); Debug.Print(重复值处理完成删除重复行数: duplicateCount); }这个组合脚本可以直接跑通一个简单测试表。注意两次遍历之间重新计算了lastRow因为第一次删除操作后数据区域已经变化如果不更新最后一行第二次循环可能漏掉新的最后一行或访问越界。3.4 为什么先处理空值而不是先处理重复值不少初学者会把“删除重复值”和“删除空值”当成两个独立步骤顺序无所谓。实际上顺序会影响结果。假设两行数据都是空行先做去重时两行的 key 都是|其中一行会被当作重复删除先做空值处理时两行都会被删除。对于“清理数据后用于汇总统计”这种目标先清空行更合理。工程上还经常遇到另一种情况某一列部分单元格有值部分为空你想删除“整行所有单元格都为空”的行而不是“某列为空”的行。这时候需要用WorksheetFunction.CountA来判断整行是否完全空白。下面代码演示了这种变体function DeleteCompletelyEmptyRows() { var sheet ActiveSheet; var lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; var lastCol sheet.Cells(1, sheet.Columns.Count).End(-4159).Column; for (var i lastRow; i 2; i--) { var rowRange sheet.Range(sheet.Cells(i, 1), sheet.Cells(i, lastCol)); if (Application.WorksheetFunction.CountA(rowRange) 0) { sheet.Rows(i).Delete(); } } }CountA统计非空单元格数量等于 0 说明整行都是空单元格。这个变体适合“不知道空值具体在哪一列”的脏数据。4. 用 WorkBuddy 生成脚本的正确提示词思路很多人在用 AI 编程工具时生成的代码不可用不是因为工具不行而是提示词没有说清楚场景。WPS-JSA 是相对小众的环境AI 容易生成 VBA 或通用 JavaScript 代码粘贴进来后语法不通。这一节给出几组可直接参考的提示词。4.1 第一次生成需求描述到函数级别第一轮提示词不必写完整代码关键是让 WorkBuddy 理解任务边界。可以参考这个版本你是 WPS 表格的 JSA 脚本专家。 请写一个名为 CleanData 的 JSA 函数作用于当前工作表ActiveSheet。 功能包括两步 1. 从最后一行向上遍历到第 2 行删除第 3 列C 列为空的整行 2. 重新计算最后一行从最后一行向上遍历到第 2 行根据第 1、2、3 列三列值拼接字符串判重重复的行保留第一次出现的那一行删除后续重复行。 要求使用 JavaScript 标准语法不要使用 VBA 的 With 或 Dim 关键字。 在脚本最后用 Debug.Print 输出两段统计信息。这段提示词包含了角色定位、函数名、作用对象、行遍历顺序、判断列、保留规则、语法限制、输出要求。生成结果大概率可以直接使用。4.2 修改迭代告诉 AI 哪里不符合预期第一次生成的代码可能不符合预期。比如判断空值的条件只写了cellValue 没有处理空格字符串。这时候不要整体重写需求而是局部修改在上一个脚本里判断 C 列为空时只判断了 null 和空字符串。 请改成当值等于 null、undefined、或者去除首尾空格后长度为 0 时都视为空值。 其他逻辑保持不变。这种“增量修改”方式比反复重写完整需求更稳定。WorkBuddy 能记住上下文中的代码局部调整的风险更低。4.3 脚本生成后的检查清单AI 生成的代码不能直接信任运行前先按清单检查是否使用了ActiveSheet而不是硬编码工作表名。是否有sheet.Rows(i).Delete()这类删除操作且循环方向是从下往上。是否跳过了第 1 行的表头。是否处理了null、undefined、空格三种空值情况。是否有Debug.Print输出统计信息。是否在函数边界使用了function关键字而不是Sub或Dim。如果 WorkBuddy 生成的代码里出现了Sub、End Sub、Dim基本可以判断它用了 VBA 语法需要让它按 JSA 语法重新生成。5. 运行验证和结果检查脚本写好后不能直接拿正式数据测试。建议先用一个十几行的模拟表格验证逻辑确认无误后再处理正式数据。下面给出验证步骤和预期结果。5.1 准备测试数据在 WPS 表格里手动构造一份表格结构如下姓名部门日期备注张三技术部2025-01-01正常李四市场部2025-01-02正常张三技术部2025-01-01重复王五技术部缺日期赵六财务部2025-01-03正常李四市场部2025-01-02重复这份数据里有三种问题重复行张三、李四各重复一次、空值行王五的日期为空、表头需要保留。运行CleanData()后预期结果删除空行 1 行王五那行。删除重复行 2 行。最终保留 3 行有效数据。5.2 运行脚本并观察立即窗口在宏编辑器点击运行后打开视图里的“立即窗口”或按快捷键调出能看到类似输出空值处理完成删除空行数: 1 重复值处理完成删除重复行数: 2如果输出结果和预期一致说明脚本逻辑正确。如果输出为空先检查是否启用了立即窗口或者宏是否真的执行了当前模块。5.3 验证数据完整性脚本执行完后建议做三个检查表头是否还在。是否还有空单元格。是否还有重复行。检查重复行可以选中数据区域用 WPS 的“删除重复项”功能反向验证如果系统提示“没有找到重复值”说明脚本已经清理干净。注意这里只是验证方式实际删除操作已经在脚本里做完了。5.4 正式数据处理前的保护措施删除行操作一旦执行CtrlZ不一定能完整恢复尤其是脚本里循环执行了多次Delete()。正式处理前先把原始工作表复制一份保存为备份文件或者把数据复制到新工作簿再运行脚本。推荐做法是复制当前工作表function BackupSheet() { var sheet ActiveSheet; sheet.Copy(/* 无参数表示复制到新工作簿 */); }在测试环境里可以先不执行这条熟悉后放入正式流程。备份的优先级高于脚本效率数据丢一次的成本远超过脚本运行几秒的成本。6. 常见问题排查链路JSA 脚本报错时不要直接搜索整段报错文本而是先判断报错发生在哪个阶段。下面按出现频率从高到低列出常见问题。6.1 运行按钮是灰色或快捷键无反应现象宏编辑器的运行按钮不可用按 F5 没反应。 可能原因当前没有处于函数内部或者活动窗口是对象资源管理器而不是代码区。 检查方式点击代码区任意位置确认光标在函数代码内部确认模块已保存。 处理建议在模块代码里点击一下再按 F5。如果仍然不行可能是宏安全设置禁用了。6.2 脚本报“对象不支持此属性或方法”现象运行到Range(...).Delete()或End(-4162)时报错。 可能原因使用了 VBA 的属性和方法但 JSA 环境不识别。 检查方式看报错行是否有Dim、Sub、With等 VBA 关键字。 处理建议让 WorkBuddy 以 JSA 语法重新生成。可以明确提示“不要使用 VBA 语法请使用 JavaScript 语法访问 WPS 对象模型”。6.3 删除行后遗漏了部分重复行现象脚本运行后手动查重复仍有重复数据。 可能原因第一次删除操作改变了表格最后一行但代码没有重新计算lastRow。 检查方式在循环前Debug.Print(lastRow)删除后再次Debug.Print对比两次值。 处理建议删除空行后重新执行sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row更新最后一行。6.4 空值没有被识别出来现象日期列为空的单元格没有删除。 可能原因该单元格不是真正的空而是包含不可见字符、空格或#N/A错误值。 检查方式选中单元格在公式栏查看是否真的没有内容用Len函数判断长度。 处理建议判断条件里使用String(cellValue).trim() 必要时把#N/A等错误值也加入清理条件。异常类型表现处理方式真正的空白单元格单元格没有任何内容value null空格字符串单元格显示为空但有空格String(value).trim() 错误值单元格显示#N/AIsError(value)判断公式返回空字符串单元格有公式但结果为空用value值判断必要时清理公式6.5 WorkBuddy 生成的代码粘贴后中文变量名乱码现象WorkBuddy 生成的代码里中文注释或中文日志输出变成乱码。 可能原因编码不一致WorkBuddy 端和 WPS 宏编辑器对文本编码处理不同。 处理建议优先使用英文或拼音作为变量名注释和日志输出尽量用英文。如果必须中文确认粘贴时没有经过会改变编码的中间软件。这个问题和 WPS 本身的宏编辑器编码支持有关不做绝对保证实际以你的版本表现为准。6.6 删除速度很慢几万行数据处理不过来现象数据量超过一万行后脚本运行明显卡顿。 可能原因Delete()在循环里逐行触发单元格移动越往后越慢。 处理建议不要循环删除改为标记后一次性删除。思路是先从下往上标记要删除的行号然后使用Union合并区域一次性删除。示例见下一节。7. 面向生产环境的脚本优化如果脚本只是自己临时用前面几节已经足够。如果要把这个清洗流程交给同事使用或者每月批量处理数据需要做三件事批量删除、范围自适应、保留原始数据。7.1 用一次性删除替代循环删除循环删除的小数据量没问题遇到大数据量就慢。生产环境推荐改为“先标记再一次性删除”。function CleanDataFast() { var sheet ActiveSheet; var lastRow sheet.Cells(sheet.Rows.Count, 1).End(-4162).Row; var rowsToDelete []; // 第一步标记空值行 for (var i lastRow; i 2; i--) { var v sheet.Cells(i, 3).Value; if (v null || v undefined || String(v).trim() ) { rowsToDelete.push(i); } } // 第二步标记重复行 var seen {}; for (var j lastRow; j 2; j--) { if (rowsToDelete.indexOf(j) 0) { continue; // 已经标为删除不用再判断重复 } var key [sheet.Cells(j, 1).Value, sheet.Cells(j, 2).Value, sheet.Cells(j, 3).Value].join(|); if (seen[key]) { rowsToDelete.push(j); } else { seen[key] true; } } // 第三步一次性删除行号从大到小排序 rowsToDelete.sort(function(a, b) { return b - a; }); var deleted 0; for (var k 0; k rowsToDelete.length; k) { sheet.Rows(rowsToDelete[k]).Delete(); deleted; } Debug.Print(总删除行数: deleted); }虽然这里仍然是一个循环里多次Delete()但避免了“删除空值时顺便改变表结构导致重复判断错乱”的情况。如果要再彻底优化可以把所有行号合并后使用sheet.Range一次性删除但代价是代码复杂度增加入门阶段先用标记法足够。7.2 让脚本适应任意列数前面的脚本把去重列写死为[1, 2, 3]实际项目可能列数不固定。可以先读取第一行每个单元格的标题再让用户或配置决定用哪些列。function GetHeaderMap(sheet, lastCol) { var map {}; for (var c 1; c lastCol; c) { var header String(sheet.Cells(1, c).Value).trim(); map[header] c; } return map; }调用时可以这样使用var headerMap GetHeaderMap(sheet, lastCol); var nameCol headerMap[姓名]; var dateCol headerMap[日期];这么做的好处是脚本不再依赖固定的第 1、2、3 列表结构变动时改动很小。代价是表头不能重复且必须和代码里的字符串完全匹配。7.3 加入确认弹窗防止误操作正式场景里脚本执行前加一个确认对话框避免误触发后数据被删。JSA 中使用MsgBox或Confirm都可以下面用MsgBox做简化示例var userChoice MsgBox(即将删除空值行和重复行是否继续, 1, 确认); if (userChoice ! 1) { Debug.Print(用户取消操作); return; }MsgBox的第二个参数 1 表示“确定/取消”按钮组合返回 1 表示确定。这属于 JSA 对象模型调用具体常量值在不同版本可能不同以你的实际运行环境为准。7.4 学习环境和生产环境的差异总结环境数据处理量脚本要求备份要求学习测试几行到几十行逻辑正确即可不强求日常办公几百到几千行循环删除可接受建议备份生产批量数万行需要一次性删除或分批处理必须备份并记录执行日志生产环境还要考虑另一个问题脚本执行耗时。如果超过几十秒建议在界面状态栏输出进度提示或把数据分成多个区域处理。WPS-JSA 在多线程方面限制较多不应在脚本里尝试异步处理。8. 最佳实践和扩展方向把“删除重复值和空值”这个实例完成之后可以总结出几条通用经验。这些经验不限于当前题目会直接影响你后续使用 WorkBuddy 和 JSA 处理其他办公自动化任务。8.1 写提示词时把“范围、顺序、保留规则”一次说清楚WorkBuddy 这类工具最怕的输入是“写个脚本删除重复值”。它缺少太多关键约束。一次合格的提示词至少要包含四个部分操作对象哪个工作表、哪些列、遍历顺序从下往上还是从上往下、保留规则保留第一条还是最后一条、输出要求统计信息、日志。可以先写一段“伪需求”再让 WorkBuddy 转成 JSA 代码。这样即使生成的代码不完全正确至少方向是对的。不要指望一句模糊描述直接生成生产级脚本。8.2 永远把原始数据放在第一步备份删除操作不像修改单元格误删后恢复成本高。无论脚本多简单正式运行前都要复制一份原始工作表或保存一份原始文件。可以在函数开头调用BackupSheet()也可以手动另存为一个带时间戳的新文件。备份逻辑虽然简单却是整个清洗流程里最重要的一道防线。数据丢了脚本写得再漂亮都没有意义。8.3 用“先清空再去重”的顺序处理脏数据当数据里同时有空值和重复值时先删除空值行再根据多列组合去重。这样能避免空值行参与去重判断导致结果不稳定。判断空值时要把null、undefined、纯空格字符串都视为空值不要只判断。8.4 从当前实例可以扩展出去的任务WordBuddy 加 WPS-JSA 的组合不止能实现“删除重复值和空值”。学会这个流程后下面这些常见清洗任务可以按同样思路完成批量删除指定列中所有空格字符。根据条件批量替换文本例如把“技术部”替换成“研发中心”。按月份拆分数据到多个工作表。把一列里的日期格式统一为标准日期。删除指定关键词所在行。根据某列值汇总统计并生成结果表。这些任务都是“人用 WorkBuddy 生成 JSA 脚本再回到 WPS 宏编辑器执行”的模式。关键是在提示词里把数据区域、判断条件、处理方向、输出要求说清楚。8.5 给新手的练习建议如果第一次接触 JSA不建议直接拿复杂业务跑。先做一个最小练习创建一个 20 行的测试表包含 3 个空行和 3 个重复行运行本文第二版CleanData()脚本观察立即窗口输出再手动核对结果。跑通之后再尝试用 WorkBuddy 改需求比如把去重列从 3 列改成 2 列或者把“保留第一次出现”改成“保留最后一次出现”。这个练习的价值在于让你同时理解两个层面的问题一是 JSA 操作表格对象模型的基本语法二是 WorkBuddy 生成代码时对上下文的需求。两者结合熟练后办公场景里的重复性清洗工作基本都可以交给脚本完成不需要每天手动点菜单。
返回列表