WPSJSA宏编程(JS):1.初识
⼀、简介
从 WPS 2021 版本开始,WPS 正式⽀持使⽤ JS 作为宏语⾔,官⽅称 JSA(报错时,⽤得就是这个名称),亦即 JS for Application 的缩写。根据官⽅⽂档()中的介绍,WPS 内嵌了⼀个 V8 引擎的 JavaScript 运⾏时,⽀持⼤部分 ES6 语法,实测⽀持到 ES2019:WPS宏编辑器集成了⼀个V8 引擎的 JavaScript 运⾏时,⽀持⼤部分ES6语法,因此宏编辑器⽀持JavaScript 标准内置对象,注意,JS
内置对象和浏览器的内置对象是不同的,WPS宏编辑器集成的是JavaScript 运⾏时,⽽不是浏览器,因此WPS宏编辑器不⽀持浏览器的内置对象。具体API参见。
JSA 也是 WPS 默认的宏语⾔,WPS 官⽅为之提供了 WPS 宏编辑器,以⽅便⼤家编辑 JSA 宏代码。
⼆、宏录制
如下⽰例是要给 B4 单元格字体颜⾊设为红⾊,背景⾊设置为黄⾊,录制的宏代码如下:
1/**
2 * Macro1 Macro
3 * 宏由 nutix 录制,时间: 2021/07/17
4*/
5function Macro1()
6 {
7 Range("B4").Select();
8 (obj=>{
9 obj.Color = 255;
10 obj.TintAndShade = 0;
11 })(Selection.Font);
12 (obj=>{
13 obj.Pattern = xlPatternSolid;
14 obj.Color = 65535;
15 obj.TintAndShade = 0;
16 obj.PatternColorIndex = -4105;
17 })(Selection.Interior);
18
19 }
第 8-11 和第 12-17 ⾏处的代码段,是定义箭头函数,以及对它们的调⽤。
宏录制器,总是会把对同⼀个对象的多个操作,以这种箭头函数的形式,录制出来。
这是复合写法,⼿⼯写 JSA 宏代码,肯定是不提倡这种写法的。
三、事件
这可能是⼤家打交道最频繁的,与 VBA 有所不同的是,现在没有⽂档模块了,WPS 宏编辑器只提供了⼀个⼊⼝来编写事,即
它订阅了当前⼯作簿Workbook的SheetChange事件,当第 1/2 表的第 4 列的值发⽣改变时,将单元格的字体颜⾊修改为蓝⾊,它的代码如下: 1function Workbook_SheetChange(Sh, rg)
2 {
3if ([1, 2].indexOf(Sh.Index) != -1) {
4//对第1、2表D列的单元格值变更进⾏处理js原型和原型链的理解
5 const blue = 12611584;
6if (rg.Column == 4) {
7 rg.Font.Color = blue;
8 }
9 }
10 }
与 VBA 的事件有所不同,WPS 中不内建⽂档模块,这⾥说的⽂档模块,就是你在 Office 的 VBE 中【⼯程管理器】⾥⾯的 Sheet1, Sheet2, ..., SheetN 和 ThisWorkbook,这 N+1 个内建的模块,VBE ⾥针对每⼀个打开的⼯作簿,都会内建⼀堆这样的⽂档模块,⼯作表及打开的⼯作簿如果⽐较多时,要查⾃⼰的模块,还得去拖滚动条。
WPS 则以⽐较巧妙的⽅式,规避了这个问题:WPS 不内建任何模块,⽤户想要订阅事件,直接在事件栏⾥⾯选中即可,事件处理程序名称与参数,会更好地协助你做你想做的事⼉。
四、⽤户窗体
WPS贴⼼地为⼤家新提供了⼏个控件,尤其是【⽔平布局控件】和【垂直布局控件】,有这两个控件,⼤家可以更好的设计窗体了。
要编写窗体及其控件的事件,和⽂档事件⼀样,通过事件栏,来指定要处理的控件的事件
由图可见WPS窗体的界⾯与代码是分离的,代码是写在普通模块⾥⾯的,绘制的窗体是在另⼀个模块
由上图可见,所有的对象,⽆论是Application(应⽤程序),Workbook(⼯作簿)、窗体、窗体控件、⼯作表控件,这些事件源,都是在同⼀个列表中,⼤家注意命名,以免混淆
五、⾃定义公式函数
为表格⾃定义公式函数是很简单的,只要返回常规类型(如⽂本,数字,⽇期,真假值即可),且是全局函数即可
1/*删除给定⽂本的某字符及后⾯的字符
2target : 要处理的⽬标
3from : 要删除的起始字符
4*/
5function DeleteFrom(target, from) {
6 let value;
7if (structor.name == 'Range') {
8//本公式只接受⼀个单元格引⽤
9if (target.Areas.Count > 1 ||
10 target.Areas.Item(1).Cells.Count > 1)
11throw new Error('本函数只能处理⼀个单元格');
12else
13 value = target.Value().toString();
14 } else
15 value = String();
16
17if (structor.name == 'Range') {
18if (from.Areas.Count > 1 ||
19 from.Areas.Item(1).Cells.Count > 1)
20throw new Error('当 from 参数是⼀个单元格' +
21 '引⽤时,请确保它只包含⼀个单元格');
22 from = from.Value().toString();
23 }
24else
25 from = String();
26
27
28 let index = value.indexOf(from);
29if (index == -1)
30return value;
31else
32return value.substr(0, index);
33 }
34
35/*将单元格区域数据转换成⼀个基于⽂本的表
36target : 要处理的单元格区域
37sep : 分隔符
38*/
39function ToTextTable(target, sep = ',') {
40if (structor.name != 'Range')
41throw new TypeError('target 参数必须是⼀个单元格区域');
42
43 sep = String();
44 let values = new Array();
45for (let iRow = 1; iRow <= target.Rows.Count; iRow++) {
46 let rowValues = new Array();
47for (let iColumn = 1; iColumn <= target.Columns.Count; iColumn++) {
48 rowValues.push(target.Cells.Item(iRow, iColumn).Value());
49 }
50 values.push(rowValues.join(sep));
51 }
52return values.join('\n');
53 }
六、WPS宏编辑器与代码调试
1. WPS 宏编辑器,提供了【⽴即窗⼝】,您可以直接在【⽴即窗⼝】执⾏单⾏的 JSA 语句,就像在写命令⾏,与 VBA 不同的时,这⾥不需要
前置问号才算求值
2. WPS 宏编辑器,允许你为 JSA 代码⾏设置断点,以⽅便对代码的调试,配套提供了【本地窗⼝】,以⽅便你了解断点处的运⾏状态
3. WPS 宏编辑器,同样提供了【逐语句】【逐过程】【跳出】功能,您可以以 VBA 熟悉的⽅式来调试 JSA 代码,不同的是它们的快捷键与
VBA 不同,与现在主流的 IDE 相同
4. WPS 宏编辑器,同样提供了【编译】⼯具,你可以在写完代码后,⽤它来做语法检查
5. WPS 宏编辑器,同样提供了【监视】功能,并配套提供了【监视窗⼝】,你可以借此设置中断条件,以进⾏复杂调试
6. 可以通过【⽂件】》【导⼊/出】,来导⼊/出代码模块
7. 可以在代码⾏通过:右键》【切换书签】的⽅式,来建⽴书签,使⽤ Ctrl + Shift + N(Next:下⼀个)/P(Previous:前⼀个)快捷键,快速地在
多个书签之间跳转,这对于调⽤⾃定义的库来实现具体应⽤时⽐较有⽤,可以⽅便地在库与调⽤代码之间来回切换,调整库代码与应⽤代码,以便可以有更可靠更⾼效的代码逻辑
8. 通过【插⼊】》【⽂件】,可以在光标所在处快速插⼊外部⽂件中的代码或数据
9. Console 对象是 JS 调试时的重要⼯具,JSA 环境下的 Console 是指向⽴即窗⼝的,你可以通过 Console.log(text) 向⽴即窗⼝写数据,也可以
通过 Console.clear() 清除它的内容,这控制⼒⽐ VBE 强多了
10. Debug 对象,可以通过 Debug.GC(),要求引擎进⾏变量垃圾回收;通过 Debug.Print(...) 实现与 Console.log(text) 相同的功能
七、对象成员访问⽅式上的⼀些变动
1. 有参数的属性,在 JSA 中变成了⽅法,须得在后⾯加 "()" ,才能正确访问,⽐如Address在 VBA 中是属性,因为 VBA ⽀持带参数的属性,但
JSA 不⽀持,所以在 JSA 中Address成员,被识别为⽅法,必须以执⾏函数的⽅式来访问;当你参考 Office ⽂档来写 JSA 代码时,要注意,只要需要传递参数,即便⼿册说它是属性,在 JSA 中也应被当然⽅法来对待。
2. VBA 中⽅法和属性不使⽤参数时,括号是可以省略的,⽐如Worksheet.OLEObjects(...)⽅法,VBA 中得到OLEObjects集合的⽅式是Set objs =
Sheet1.OLEObjects,不加括号,可以正确访问;但 JSA 中必须加括号才能访问,即应写成let objs = Worksheets.Item('Sheet1').OLEObjects();
3. VBA 调⽤⽅法或有参属性时,如果某个参数有默认值,可以直接省略该位置的参数,⽐如ActiveCell.Address(,,xlR1C1),JSA 中不允许这么做,如
果想使⽤默认值,则应写成ActiveCell.Address(undefined, undefined, xlR1C1)
4. VBA 可以以命名参数的⽅式,向⽅法或属性传递参数,如ActiveCell.Address(ReferenceStyle:=xlR1C1),这种语法在 JSA 中是不⽀持的,你必须写成
ActiveCell.Address(undefined, undefined, xlR1C1);
5. 当参数⽐较多,你⼜只想传递⼀个参数,其它都⽤默认值的时候,怎么办呢,可以这样:ActiveCell.Address(...[,,xlR1C1]);
6. 可能你⼜要说,如果参数⼏⼗个,只想传递某个参数呢?也可以,⽐如ThisWorkbook.SaveAs(/*有 12 个参数*/),每个参数都有默认值,我们想传递
第 9 个参数,也即AddToMru参数,可以这样写:
1function Save() {
2 let args = [];
3 args[8] = true;
4 ThisWorkbook.SaveAs(...args);
5 }
⼋、JSA 相较于 VBA 的优势
1. JSA 基于原型链的⾯向对象,灵活性⾮常强,但毕竟动态⼀时爽,重构⽕葬场,其⼯程性差,好在它所⾯临的业务 99.99% 的场
景,是弱⼯程性的,所以正好适⽤
2. JSA 背靠 JS,后者有国际性的标准化组织,每年推动语⾔改进,JS 只会越来越强⼤,越来越⽅便,经典 class 的引⼊就是明证
3. JSA 背靠 JS,后者有最活跃的社区,由全球⼈才发⼒,各种⼯具与库层出不穷,可以为 JSA 提供助⼒,⽐如我使⽤了来⾃ github
的linq.js库,它极⼤地⽅便了⼀些查询⼯作
4. VBA 长久没有语⾔层⾯的更新,语⾔特性早已过时;⽽现⾏的 VBA 标准,其语⾔特性呆板、⽣硬,基本没什么灵活性,⽐如不能
愉快地相互传递函数,来灵活地配置功能(借助奇技淫巧曲线救国的,⼀边去)
5. VBE 宏编辑器,长久没有得到更新,编程体验奇差:
1. 在编辑的模块窗⼝是 MDI 窗⼝模式,⽽不是便利的标签页模式,关闭与切换都很⿇烦
2. 标识符命名具有穿透性,写得好好的库 API 命名,会因为其它模块同名标识符的⼤⼩写,被⾃动修改,真是⽇了狗了
3. Excel 表格太多时,⼯程管理器⾥⾯内建的⽂档模块能排到“天边”
6. JSA 安全性好,没有对乱七⼋糟的外部库的⽀持,你做好 Office ⾃动化这个本职⼯作就好,调⽤Win32API?,你想⼲嘛
7. JSA 跨平台,JS 能跨,JSA 就能跨,基于 V8 好破浪(乘凉)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论