一、JSA 宏映像
- JSA 基于原型链的面向对象,灵活性非常强,但毕竟动态一时爽,重构火葬场,其工程性差,好在它所面临的业务 99.99% 的场景,是弱工程性的,所以正好适用
- JSA 背靠 JS,后者有国际性的标准化组织,每年推动语言改进,JS 只会越来越强大,越来越方便,经典 class 的引入就是明证
- JSA 背靠 JS,后者有最活跃的社区,由全球人才发力,各种工具与库层出不穷,可以为 JSA 提供助力,比如我使用了来自 github 的
linq.js
库,它极大地方便了一些查询工作 - VBA 长久没有语言层面的更新,语言特性早已过时;而现行的 VBA 标准,其语言特性呆板、生硬,基本没什么灵活性,比如不能愉快地相互传递函数,来灵活地配置功能(借助奇技淫巧曲线救国的,一边去)
- VBE 宏编辑器,长久没有得到更新,编程体验奇差:
- 在编辑的模块窗口是 MDI 窗口模式,而不是便利的标签页模式,关闭与切换都很麻烦
- 标识符命名具有穿透性,写得好好的库 API 命名,会因为其它模块同名标识符的大小写,被自动修改,真是日了狗了
- Excel 表格太多时,工程管理器里面内建的文档模块能排到“天边”
- JSA 安全性好,没有对乱七八糟的外部库的支持,你做好 Office 自动化这个本职工作就好,调用
Win32API
?,你想干嘛 - JSA 跨平台,JS 能跨,JSA 就能跨,基于 V8 好破浪(乘凉)
除了语言本身的灵活性,JSA 支持 eval,可以用来构建动态代码
二、JSA 建议
提供内置的 DateTime 类型,以规避与 Excel 日期时间类型数据的交互问题;或者,也可以在 COM 交互层面做工作,规避可能雷区;宏编程,本身是面向应用程序宿主的,也是面向终端消费者的,所以含时区固然是可国际化、强工程性的,但是对于终端用户,这完全是多余的
- 需要对 JDE 对象的引用,WPS 的
Application
对象没有提供这个入口 Env/FileSystem
对象不可用,Open/FileCopy
等这些离散的函数,又没有文档说明将多个单元格的值读到一个数组中时,如
let values = rngData.Value2
,它总是按先列后行的方式遍历单元格,这与 VBA 使用者的习惯相悖,也不符合通常的处理逻辑(致命)三、WPS 宏编辑器优点
宏编辑器支持块输入,Alt + 鼠标框选,可对块内所有字符作出修改
- 代码块可折叠,极大的方便了编写代码
- 标签页式的模块编辑体验比 VBA 的 MDI 窗口式编辑体验要好得多
- 为标签页提供的菜单,真是省事儿
【切换行注释
Ctrl + /
】与【切换块注释Ctrl + Shift + /
】真是注释好帮手,当然这也得语言本身支持四、WPS 宏编辑器建议
记忆文档窗口与宏编辑器窗口的大小与位置
- 希望能这样进行工程管理:
- 内建【文档】模块,专用于放置
Application
/文档对象
相关的事件代码 - 内建【文档控件】模块,专用于放置文档控件对象的相关事件代码
- 内建【自定义公式函数(可名为 Formulas)】模块,以避免其它全局函数对公式的编辑,造成干扰
- 将窗体代码收缩进窗体 UI 模块中,免得代码位置混乱,引起麻烦;现行的方案是 UI 与代码分离,这的确符合工程化原则,但 JSA 本身工程性弱,窃以允许散乱放置代码,会极大的降低用户体验,使用户修改代码很麻烦;控件数量很多时,【事件源】对象列表将非常长,用户要去订阅某窗体控件的事件得查找很久
- 希望为【属性窗口】提供一个搜索器,以方便检索控件,如果用户的窗体很复杂(成百上千的控件),那么没有检索功能,会非常麻烦
- 内建【文档】模块,专用于放置
- 在宏编辑器窗口中提供一个工具,方便切换成文档与宏编辑器并排(竖直或水平并排)布局,这会在有的时候给编写宏代码提供极大便利(幸福感 +100)
- 提供对选中的代码进行格式化的支持,包括缩进与空格(幸福感 +100)
- 支持使用
Alt + 上/下箭头键
,上下移动代码行(幸福感 +100) - 支持使用
Ctrl + X
在没有任何选中时,剪切整行(幸福感 +100) - 支持使用
Ctrl + U/L
对选中的标识符进行大小写转换(幸福感 +100) - 现行的查找替换窗口,不支持 tab 跳转,这太不方便替换字符了(幸福感 +100)
Ctrl + Enter
在光标所在行的下面添加一行,并将光标放置到缩进位置(幸福感 +100)Shift + Enter
在光标所在行的上面添加一行,并将光标放置到缩进位置(幸福感 +100)Ctrl + M
代码折叠与打开(幸福感 +100)【现在代码折叠后,光标定位会出错】- 提供反转条件语句逻辑的重构工具(幸福感 +100)
- 提供提取函数的工具(幸福感 +100)
- F1 展开光标所在位置字符的文档(幸福感 +100)(致命)
- 希望为函数方法,提供一套标准的注释格式(参考 C# 的注释语法)
- 这样自定义公式函数的作者,可以提供参数/异常相关的消息,辅助用户更好地使用自定义的公式函数
- 库作者也可以更好地为调用者提供参考信息;
- 语言是严谨的,注释却是自由的,那么我认为可以使用良好的注释,对代码块进行类型标注,为 IDE 的智能提示提供助力
- Home 键的定位,首选应该是第一个有意义的字符
- 从备份中恢复文件时,宏代码模块数据被清除掉了,这简直是…
- 添加监视,暂时不可用,因为条件表达式通常会使用当前执行环境的变量,但这里根本没有支持,环境变量不可见(致命)
- 没有【运行到光标所在行】,既然断点功能都支持了,这功能为啥不支持
- 符号自动配对无法通过设置关闭,有时我在字符串中包含引号,会非常麻烦,如果有这个设置,我一定关闭它(幸福感 +100),有配对高亮即可很好指导符号配对,强制输入反而蛋疼
- F2 重命名(幸福感 +100)
- 模块按模块名排序就好,不需要按插入时间排序
- 转到定义F12(幸福感 +100)
- 对选中对象查找所有引用,这将方便用户替换代码,修正代码
- 【立即窗口】不支持 Ctrl + Enter,即【换行不执行】操作
- 提供基于良好审核与安全签名的云端宏:如若如此,将成倍提振 WPS 的用户粘滞性
现行提供的【用户窗体】,从类型设计,到模块代码组织形式,到事件订阅机制,都太差劲了,建议推倒重新设计。可以参考.NET WinForm 那套 UI 风格。
五、宏录制 Bug
对数据有效性相关操作,宏录制无反应
- 对图表相关的操作,宏录制不全面
- 对数据透视表的排序操作,宏录制无反应
对某些操作,宏录制录下的代码是错误的,尤其是返回集合的无参方法的调用代码,比如下面
PivotCaches
实际上是一个方法,所以如下录制的代码是错误的:ActiveWorkbook.PivotCaches.Create(xlDatabase, "=试验!R3C2:R13C7", xlPivotTableVersion15);
对切片器的相关操作,宏录制无反应
- 如下代码是对图表不同区域进行选中操作时,录制的宏,语句都不完整:
```javascript
/**
- Macro1 Macro
- 宏由 nutix 录制,时间: 2021/08/21 */ function Macro1() { Range(“H15”).Select(); .Select(); .Select(false); .Select(false); Range(“I19”).Select();
六、类型系统 Bug
- 有些枚举常数是缺失的,比如数据有效性类型枚举 XlDVType
- JS
Date
类型与 Excel 日期时间类型不对等,主要有两个差别:JS 的Date
有毫秒,Excel 的没有,这会为宏代码中日期时间的比较运算出问题,读写 Excel 日期时间值,也会出现精度丢失;JS 的Date
有时区,Excel 的没有,读写数据时若不注意,就会翻船。建议提供一个内置的类型,或者在 Com 交互过程上做工作。 - 为支持 MsgBox 函数,提供了
JSMsgBoxStyle
,但是JSMsgBoxResult
枚举是缺失的 RGB
这种宏常用函数,不存在- 当 WPS 软件处于最小化状态时,调用
Application.InputBox(...)
方法时,弹出的对话框不可见 -
七、宏编辑器 Bug
不知是不是有输入法控制,中英文切换失灵,大多数情况下只能输入英文
- 【立即窗口】中输入
Console.log('better?' + false);
解析时会报错,关键是”?”,但是在模块中又是正确的 - 【工程资源管理器】的菜单不对口,对于工程项可以有【工程属性】菜单,对于【文件夹】和【模块】项,不应该有这个功能;【模块】项应该有单独【导出】菜单项
- 【属性方法列表】很多时候不管用,当然这也有语言本身的问题
- 【常数列表】基本不可用
- 【快速信息】不可用,对注释的呈现根本没有
- 【参数信息】不可用,对注释的呈现根本没有
- 【添加监视】基本不可用
八、VBA 槽点
- 引用类型与值类型赋值方式不同本来应是编译器的事儿,搞成了人为区分,带来两个麻烦:给变量赋值与编写可写属性 Property Set/Let;
- 数组下标巨大的灵活性,本是为了更好的适应用户思维,却同时造成了处理一个数组对象在逻辑上的复杂性;
- 数组动态性有什么存在的必要性么,非要用数组来兼顾集合的可增删性,有必要么;
- 集合 Collection 功能方法设计上的不足(对我说的是没有 Replace 方法),使集合的使用不够方便,本来应该是数组外的第二常用的对象类型的,结果成了这个样子;
- Function/Sub 强制差异化,并没有带来实质性好处;
- 不必要的省略括号机制,本是为了方便用户输入,却也使语义上属性与方法极易混淆;
- 允许属性带多余的参数,使复杂属性与方法混为一团,复杂性陡升,带来的好处却几乎没有,还不如将复杂属性写成方法;
- static 不是块级,而是局部的,直接就导致根本不存在静态成员;
- 难用的异常处理机制;
- 标准模块的存在,不伦不类,虽然可以用来模拟静态类型(如果将模块名看作类名的话),却造成了巨大的命名污染;
- 基于对象,而不完全的面向对象;
- 默认传递引用,必须手写 ByVal 才能按值传递,与习惯相悖,徒增工作量;
- 没有真正的构造函数,初始化事件并不能很好的控制对象的创建,因为此时对象内部状态还没有定下来;
- 类在外部工程中的可创建性,不是由代码来表述,而是由模块属性来描述;
- 没有转义字符,有特殊字符的字符串拼接非常麻烦;
- 殊少进化,权重无限大;
- 语义式的语句块结构,书写起来很费力;
- 标准库:
- 面向过程式的标准库设计,增加了标准库的学习与使用负担,因为功能是离散的,而不是以对象为中心的;
- 标准库函数、语句、关键字,没有清晰的界限,比如 IO 相关的标准库,设计成函数即可,却白占关键字;
- 正则表达式这么重要的东西,没有标准库支持,依赖外部库;
- IO 相关的标准库,还不如外部库 Scripting.FileSystemObject;
- 未提供内置的 Dictionary 这种重要类型,依赖外部库 Scripting.Dictionary;
九、VBA 优点
- Select Case 设计得很好,不穿透比穿透更方便组织逻辑;
- Is 运算符,在范围比较中,真的很贴心;
- 语言是静态类型,非常好;
- 智能提示,这方面权重无限大;
- 有 Enum 枚举,这种类型用于声明常数组,非常方便,也方便传递参数时 IDE 智能提示;
- 有轻量的 Type 结构体,好用