ARTICLE · 1313684
WPS表格JSA之21:单元格写入数据的6种方法
WPS表格JSA之21:单元格写入数据的6种方法
在统信UOS系统中,WPS表格提供了基于JavaScript的宏能力(简称 JSA),它的对象模型与VBA高度一致,但写法更简洁、数组处理更灵活。日常做批量取数、跨表复制、报表填充时,选择正确的写入方式直接决定了代码是“1秒跑完”还是“1分钟还在转”。 宝哥把最常用的6种写入方法整理出来,每一种都给出完整可运行的JSA示例,并在最后附性能对比和常见坑点。 最直接的方式:把源区域原样复制到目标位置,连同格式、公式、列宽一起复制。适合"整张表搬过去"的场景。 也可以用索引引用工作表: 特点:一行代码搞定,格式完整;但会把源区域的公式也一起复制(公式中的相对引用会随目标位置偏移),如果只想要值,请用下面的方法二。 先用 Copy 把区域放进剪贴板,再用 PasteSpecial 选择性粘贴。这是"只要值不要格式"最常用的写法。 常用的 Paste 常量对照:
小技巧:粘贴完一定要 Application.CutCopyMode = false,否则剪贴板一直保留大块内容,UOS下WPS偶尔会卡顿。 不经过剪贴板,直接把源区域的值读出来再写进目标区域。比Copy+Paste更快,因为完全绕开了剪贴板。 也可以给单个单元格赋值: Value vs Value2: Value2 对货币和日期类型返回底层数值(Double),做计算时不会被格式干扰; Value 会按单元格格式返回带格式的字符串。批量做数值计算时优先用 Value2。 这是大批量数据写入的首选。先在JS里拼好一个二维数组,再用 Resize 一次性丢给单元格区域,速度比循环逐格写入快几十到上百倍。 从已有区域读出数组、处理后再写回(银行最常见的"清洗-回填"场景): 需要在单元格里放公式时,用 Formula 或 FormulaR1C1。JSA同样支持R1C1引用,做批量公式时极方便。 跨表公式: 初学者最容易写的方式:用 Cells(i,j) 在循环里一格一格写。数据量小(几十行)看不出问题,上万行时会非常慢。 为什么慢:每写一个单元格,JSA就要和WPS表格引擎做一次COM通信,1万行就是3万次通信。同样的数据改用方法四的数组一次写入,耗时从几十秒降到毫秒级。 如果非要循环,至少加上 ScreenUpdating 关掉屏幕刷新:

关键词:WPS宏 JSA、
方法一:Range.Copy 整区域复制(带格式)
// 把 Sheet1 的 A4:D5 整块复制到 Sheet2 的 A1 起始位置function CopyBlock() {Sheets("Sheet1").Range("A4:D5").Copy(Sheets("Sheet2").Range("A1"));}
// Sheets(1) 即第一个工作表Sheets(1).Range("A4:D5").Copy(Sheets(2).Range("A1"));
方法二:Copy + PasteSpecial 选择性粘贴
function PasteValuesOnly() {var src = Sheets("Sheet1").Range("A4:D5");var dst = Sheets("Sheet2").Range("A5");src.Copy();// xlPasteValuesAndNumberFormats = 值 + 数字格式dst.PasteSpecial(xlPasteValuesAndNumberFormats);// 清空剪贴板Application.CutCopyMode = false;}
常量 | 含义 |
xlPasteAll | 全部(默认) |
xlPasteValues | 只粘贴值 |
xlPasteValuesAndNumberFormats | 值 + 数字格式 |
xlPasteFormats | 只粘贴格式 |
xlPasteFormulas | 只粘贴公式 |
xlPasteColumnWidths | 粘贴列宽 |
方法三:Value2 直接赋值(跨表取值)
function AssignValue() {// 把 Sheet1!A4:D5 的值,一次性写入当前表 A9:D10Range("A9:D10").Value2 = Sheets("Sheet1").Range("A4:D5").Value;}
// 单值Range("A1").Value2 = "2026年11月银行内控月报";Range("B1").Value2 = 1250000.50;// 从另一个单元格取值Range("C1").Value2 = Sheets("源表").Range("Z99").Value2;
方法四:数组批量写入(性能最优)
function WriteByArray() {// 构造一个 5行 x 3列 的二维数组var data = [["序号", "科目", "金额"],[1, "利息收入", 1250000],[2, "手续费", 86000],[3, "营业外收入", 12000],["合计", "", 1348000]];// 从 A1 开始,按数组行列数自动扩展区域var rng = Range("A1").Resize(data.length, data[0].length);rng.Value2 = data;}
function ReadProcessWrite() {var arr = Sheets("明细").Range("A2:C10000").Value2;// 在JS数组里做处理(这里把第三列金额乘以汇率)for (var i = 0; i < arr.length; i++) {arr[i][2] = arr[i][2] * 7.2;}// 一次性写回Range("E2").Resize(arr.length, arr[0].length).Value2 = arr;}
性能关键:读出来的二维数组在JSA里是"行优先"的,arr[i][j] 表示第 i 行第 j 列(下标从0开始),不要和VBA的从1开始混淆。
方法五:写入公式 Formula
function WriteFormula() {// 给 E2:E100 写入 =D2*1.13 这种公式Range("E2:E100").Formula = "=D2*1.13";// 用 R1C1 写法,相对引用会自动按行变化Range("F2:F100").FormulaR1C1 = "=SUM(RC[-3]:RC[-1])";}
Range("B2").Formula = "=VLOOKUP(A2,源表!A:B,2,0)";方法六:Cells 循环逐格写入(反例)
// 不推荐:10000行就要访问10000次Range对象function SlowWrite() {for (var i = 2; i <= 10001; i++) {Cells(i, 1).Value2 = i - 1;Cells(i, 2).Value2 = "科目" + i;Cells(i, 3).Value2 = i * 100;}}
function BetterButStillSlow() {Application.ScreenUpdating = false;for (var i = 2; i <= 10001; i++) {Cells(i, 1).Value2 = i - 1;}Application.ScreenUpdating = true;};
6种方法横向对比
方法 | 是否带格式 | 是否走剪贴板 | 速度 | 适用场景 |
① Range.Copy | 是 | 是 | 中 | 整张表/整块原样搬运 |
② Copy+PasteSpecial | 可选 | 是 | 中 | 只要值/只要格式 |
③ Value2直接赋值 | 否 | 否 | 快 | 跨表取值、单格赋值 |
④ 数组+Resize | 否 | 否 | 极快 | 万行以上批量写入 |
⑤ Formula/R1C1 | — | 否 | 快 | 批量生成公式 |
⑥ Cells循环逐格 | 否 | 否 | 极慢 | 仅小数据量、临时脚本 |
写代码前必做的3件事
关闭屏幕刷新:脚本开头 Application.ScreenUpdating = false,结尾再恢复,能省下大量时间。 显式引用工作表:不要在循环里反复写 Sheets("xxx"),先用 var ws = Sheets("xxx"); 缓存下来。 数据先在JS数组里算完:所有循环计算、清洗、汇总都在JS侧做完,最后一次性 Value2 = 数组 写回,这是UOS下WPS JSA性能优化的核心思路。
一句话总结:小数据怎么写都行;数据量一上来,记住"读出来、数组里算、一次写回"这三步,性能问题基本就解决了。
如果你有具体场景或疑问,欢迎在评论区留言,宝哥会尽力解答!















































































