『JSA神助攻之二』使用外部程序/VSTO插件执行JSA宏

2024-06-27 19:58:35 浏览数 (2)

此乃旧文,题目改一下,有点系统性,JSA助攻第一波:可以通过Application.Run接口,让外部程序或VSTO/ExcelDNA项目可以调用JSA的宏代码。

以下是历史内容:

在WPS的个人版上,默认只有JSA宏,没有VBA宏,虽说在VSTO/ExcelDNA项目里或者外部程序如C#/python等可以使用COM通信来调用WPS的COM开放的接口。

但是WPS的COM接口,表面是和Excel通用,但也有许多bug存在。暂时没有测试到是否存在JSA宏正常而VBA宏不正常的情况。

反正WPS也就躺平了,在二次开发里有bug,不管怎么反馈,也是懒洋洋的,不当一回事。

通常情况下,使用COM接口来调用WPS个人版也足够了。但事实是,在JSA宏里有的一些接口,WPS没有开放同步到VBA接口上。例如插入嵌入的单元格图片(这个还偷偷的有个接口,没见WPS文档里有说明,估计用来卖会员批量功能,防止大家二开来调用了)、插入webshape网页控件(这个是笔者最想要的接口),打开右侧任务窗格(不记得有没有这个能力)等。

如果使用外部程序或VSTO插件可以调用这些接口,是比较完美的。例如使用RPA工具,可以全自动化地对其进行单元格图片插入,最后形成报告结果。在VSTO里可以调出webshape网页控件等,非常广阔的应用场景。

现如今,还真可以了。稍有点曲折,但总算是可以做到在windows环境下实现调用JSA宏的愿景。

如何调用,答案和FreeScript类似,仍然使用了Application.Run方法,在外部程序或VSTO插件里,调用这个方法,同样可以运行JSA宏。

【支持R脚本】FreeScript给数据分析工作者带来无限惊喜,在Excel/WPS环境上做专业数据分析不是梦

有了这个口子后,接下来,就是想办法把自己要实现的jsa宏放到一个xlsm文件里,然后使用外部程序打开这个xlsm文件,就可以使用Application.Run方法来调用了。

例如简单实现一下,打开网页控件

代码语言:javascript复制
function 打开网页(urlStr)
{
  var sht= Application.ActiveSheet;
  sht.Shapes.AddWebShapeEx(urlStr)
}

用外部程序例如C#来调用它,代码如下:

代码语言:javascript复制
        static void Main(string[] args)
        {
            Type etAppType = Type.GetTypeFromProgID("Ket.Application");
            if (etAppType == null)
            {
                Console.WriteLine("WPS ET (Spreadsheets) application not found.");
                return;
            }

            Excel.Application app =(Excel.Application) Activator.CreateInstance(etAppType);
            //Excel.Application app= (Excel.Application)Marshal.GetActiveObject("Ket.Application");

            // 设置应用程序可见
            app.Visible = true;

            Excel.Workbook workbook = app.Workbooks.Open("C:\Users\19026\Desktop\testjsa.xlsm");
            var newwkb = app.Workbooks.Add();
            newwkb.Activate();
            app.Run("打开网页", "https://www.baidu.com");
            // 清理
            Marshal.ReleaseComObject(workbook);
            Marshal.ReleaseComObject(app);
        }

最后,就可以得到自己想要的结果了,xlsm文件打开后,里面的JSA宏是程序级别的,可以用到其他工作薄中。当然代码写得简陋,只是测试,还可以做更多精细化控制。

同样地,插入嵌入图片,代码如下,可以再封装成有参数的方法。

代码语言:javascript复制
function 插入嵌入单元格图片()
{
  var rng=Application.Selection
  var func= rng.RangeEx;
  func.InsertCellPicture("C:/Users/19026/Desktop/Snipaste_2024-06-18_15-33-31.png")
}

需要注意的是:Application.Run只能传入文本参数,不能是对象参数。例如你不能传一个Range对象,但你可以自己传入一些工作表名、单元格地址等,自己在JSA宏里根据这些参数得到一个Range对象。

总结

WPS在二次开发上的支持,真的出了名的糟糕,WPSJS加载项、JSA宏,一开始觉得开了个不错的头,但几年下来,毫无进展。

有什么样的菜做什么样的饭,既然没有了,保能自己想办法创造,利用现有的可行的方案,自己再慢慢堆积了,例如笔者给WPS扩展了调用主流开发语言的FreeScript插件,和本篇的可以调用JSA宏,有了这两样的加持,相信在WPS的二次开发上,能够得到很大的改进和提升。

0 人点赞