找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 1456|回复: 5

[转载代码] 办公WPS中自定义功能区按钮,对接JSA

[复制链接]
发表于 2026-6-13 11:37:12 | 显示全部楼层 |阅读模式
本帖最后由 cutebe 于 2026-6-13 16:47 编辑

文件名:自定义功能区.xlsm
目录结构:内部文件一:_rels\.rels;内部文件二:customUI\customUI.xml        //重要文件两个

查看方法
方法一:改扩展名为.zip,用解压软件打开;
方法二:用Ribbon XML Editor v9.4汉化版打开,直接显示。

内部文件说明
第一点:内部文件名:.rels
类型为功能扩展:Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility"
界面文件路径为:Target="customUI/customUI.xml"        //第二点有说明
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  4.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  6.         <Relationship Id="customUI2007RelID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7. </Relationships>
复制代码


第二点:内部文件名:customUI.xml
界面文件:功能区自定义一个标签,下含三个按钮。其中第一个按钮与函数关联
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab id="tba" label="自定义功能区标签" >
  6.                                 <group id="g1" label="组">
  7.                                         <button id="b1" label="按钮一" onAction="检测ffi" />
  8.                                         <button id="b2" label="按钮二" />
  9.                                         <button id="b3" label="按钮三" />
  10.                                 </group>
  11.                         </tab>
  12.                 </tabs>
  13.         </ribbon>
  14. </customUI>
复制代码


//代码JSA:WPS宏编辑器        //开发工具》查询代码
  1. function 检测ffi(){测试外部函数接口ffi支持与否();}

  2. function 测试外部函数接口ffi支持与否(){        //测试ffi支持与否
  3.         //支持ffi开始:WPS 12.1.0.23542 版本及以上
  4.         console.log(ffi);        //若提示“引用错误:ffi is not defined”,则表示不支持!
  5.         //不支持原因:一、版本低;二、精简版删除了ffi或未开启。
  6. }
复制代码

评分

参与人数 1技术 +1 收起 理由
zzz19760225 + 1 感谢分享

查看全部评分

 楼主| 发表于 2026-6-13 11:42:23 | 显示全部楼层

基础中设置加载按钮,方便 添加/修改 界面功能

//基础.xlam:.rels
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  4.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  6.         <Relationship Id="rId5" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7.         <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/>
  8. </Relationships>
复制代码


//基础.xlam:customUI.xml
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab idMso="TabHome"><!--开始标签-->
  6.                                 <group id="gBase" label="系统自带" insertBeforeMso="ShowClipboard"><!--组在剪贴板前面-->
  7.                                         <button id="btLoad" label="加载" onAction="加载常用便捷" size="large" imageMso="FillUp" />
  8.                                 </group>
  9.                         </tab>
  10.                 </tabs>
  11.         </ribbon>
  12. </customUI>
复制代码


//基础.xlam:JSA
  1. function 加载常用便捷(){        //大按钮在 开始 标签末尾
  2.         let 常用便捷加载项=Application.AddIns.Add("D:\\Program Files (x86)\\功能区\\功能区JSA\\常用便捷.xlam");        //添加到列表
  3.         常用便捷加载项.Installed=true;        //打勾
  4. }
  5. function 卸去常用便捷(){
  6.         let 常用便捷加载项=Application.AddIns.Item("常用便捷");
  7.         常用便捷加载项.Installed=false;        //不打勾
  8. }
复制代码


//常用便捷..xlam:.rels
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  4.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  6.         <Relationship Id="rId5" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7.         <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/>
  8. </Relationships>
复制代码


//常用便捷.xlam:customUI.xml
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab idMso="TabHome"><!--开始标签-->
  6.                                 <group idQ="gBase" label="系统自带"><!--之前有的自定义组用idQ-->
  7.                                         <button idMso="ViewCode" label="代码查看" insertBeforeQ="btLoad" size="large" /><!--在加载前面-->
  8.                                 </group>
  9.                         </tab>
  10.                         <tab id="tab1" label="常用便捷">
  11.                                 <group id="sys" label="系统组">
  12.                                         <button idMso="ViewCode" label="查看代码" size="large" />
  13.                                         <button idMso="AlignCenter" label="水平居中" />
  14.                                         <button idMso="MergeCenter" label="合并居中" />
  15.                                         <button idMso="AlignMiddleExcel" label="垂直居中" />
  16.                                 </group>
  17.                                 <group id="g2" label="定制组">
  18.                                         <button id="b21" label="六位编码居中" onAction="六位编码居中" />
  19.                                         <button id="b22" label="新增黄底红字" onAction="新增黄底红字" />
  20.                                         <button id="b22" label="单元格不换行" onAction="单元格不换行" />
  21.                                 </group>
  22.                                 <group id="g3" label="检验组">
  23.                                         <button id="b31" label="外部函数接口" onAction="测试外部函数接口ffi" />
  24.                                         <button id="b32" label="检验条码" onAction="检验条码" />
  25.                                         <button id="b33" label="检验追溯码" onAction="检验追溯码" />
  26.                                         <button id="b34" label="卸去" onAction="卸去常用便捷" size="large" imageMso="FillDown" />
  27.                                 </group>
  28.                         </tab>
  29.                 </tabs>
  30.         </ribbon>
  31. </customUI>
复制代码


//常用便捷.xlam:JSA
  1. function 六位编码居中(){
  2.         var 选区=Selection;
  3.         选区.NumberFormat="000000";        //六位数字格式
  4.         选区.HorizontalAlignment=-4108;        //水平居中
  5.         选区.VerticalAlignment=-4108;        //垂直居中
  6. }
  7. function 新增黄底红字(){
  8.         选区=Selection;
  9.         选区.Value2="新增";
  10.         选区.Font.Color=0xFF;        //红色
  11.         选区.Interior.Color=0xFFFF;        //黄底
  12. }
  13. function 单元格不换行(){
  14.         选区=Selection;        //取消水平两端对齐(-4130)
  15.         if(选区.HorizontalAlignment==-4130){选区.HorizontalAlignment=1;}
  16.         选区.WrapText=0;        //取消自动换行
  17. }
  18. function 测试外部函数接口ffi(){        //测试ffi支持与否
  19.         //支持ffi开始:WPS 12.1.0.23542 版本及以上
  20.         console.log(ffi);        //若提示“引用错误:ffi is not defined”,则表示不支持!
  21.         //不支持原因:一、版本低;二、精简版删除了ffi或未开启。
  22. }
  23. function 检验条码(){
  24.         alert("条码13位,“69”开头");
  25. }
  26. function 检验追溯码(){
  27.         alert("追溯码20位,“8”开头,前七位为识别码");
  28. }
  29. function 卸去常用便捷(){        //方便修改功能区按钮
  30.         let 常用便捷加载项=Application.AddIns.Item("常用便捷");
  31.         常用便捷加载项.Installed=false;        //不打勾
  32. }
复制代码
 楼主| 发表于 2026-6-13 15:33:37 | 显示全部楼层

未调用WinAPI代码

函数JS
  1. function 随机整数(起始数,终止数){
  2.         return Math.floor(Math.random()*(终止数-起始数+1))+起始数;
  3. }
复制代码
 楼主| 发表于 2026-6-13 15:35:27 | 显示全部楼层

调用WinAPI的小功能代码

一个一个小功能
  1. function 设置剪贴板文本(文本内容){        //参数为字符串
  2.         let 执行宏调用=ExecuteExcel4Macro;        //调用系统应用接口。简化书写
  3.         if (执行宏调用(`CALL("User32","OpenClipboard","AJ",0)`)){        //打开剪贴板
  4.                 if(执行宏调用(`CALL("User32","EmptyClipboard","A")`)){        //清空剪切板
  5.                         const 内存句柄=字符串到内存(文本内容);        /*-----调用函数-----*/
  6.                         if(内存句柄){        //console.log("内存块大小:"+执行宏调用(`CALL("Kernel32","GlobalSize","JJ",${内存句柄})`));
  7.                                 let 剪贴板文本=执行宏调用(`CALL("User32","SetClipboardData","JJJ",1,${内存句柄})`);
  8.                                 执行宏调用(`CALL("Kernel32","GlobalFree","JJ",${内存句柄})`);        //释放内存
  9.                         }else{console.log("未能分配内存!");}        //数据放入剪切板,参数为1(CF_TEXT)则返回文本
  10.                 }else{console.log('未能清空剪贴板!');}
  11.                 执行宏调用(`CALL("User32","CloseClipboard","A")`);        //关闭剪贴板,以释放控制权。
  12.         }else{alert('无法打开剪贴板!');}
  13. }

  14. function 获取剪贴板文本(){        //返回字符串
  15.         const 执行宏调用=ExecuteExcel4Macro;
  16.         if(执行宏调用(`CALL("User32","OpenClipboard","JJ",0)`)){        //打开剪贴板
  17.                 const 内存句柄=执行宏调用(`CALL("User32","GetClipboardData","JJ",1)`);        //获取剪贴板文本,返回句柄。
  18.                 if(内存句柄){        //锁定全局内存对象,获取内存地址
  19.                         var 剪贴板文本=内存取字符串(内存句柄);        /*-----调用函数-----*/
  20.                 }else{console.log("未能获取剪贴板数据的内存句柄!");}
  21.                 执行宏调用(`CALL("User32","CloseClipboard","J")`);        //关闭剪贴板,让其它应用可以使用剪贴板
  22.                 return 剪贴板文本;        //返回字符串
  23.         }else{alert('无法打开剪贴板!');}
  24. }

  25. function 字符串到内存(字符串){        //返回内存句柄
  26.         const 执行宏调用=ExecuteExcel4Macro;
  27.         let 分段文本=[],分段字节=[],总字节=0,段长度=127;        //可申请256字节内存,结束符1字节,汉字最长127
  28.         for(let 起始=i=0;起始<字符串.length;起始+=段长度,i++){
  29.                 分段文本.push(字符串.slice(起始,起始+段长度));
  30.                 分段字节.push(分段文本[i].replace(/[^\x00-\xff]/g,'xx').length);        //一个汉字占两个字节
  31.                 总字节+=分段字节[i];
  32.         }        //分配内存        //分配GlobalAlloc对应销毁GlobalFree        //分配LocalAlloc对应销毁LocalFree
  33.         const 内存句柄=执行宏调用(`CALL("Kernel32","GlobalAlloc","JJJ",${0x42},${总字节+1})`);
  34.         if(内存句柄){        //内存分配成功,然后锁写解内存。        //锁定全局内存对象,会返回其内存地址
  35.                 const 内存地址=执行宏调用(`CALL("Kernel32","GlobalLock","JJ",${内存句柄})`);
  36.                 for(let 偏移字节=i=0;i<分段文本.length;i++){        //字符串(JS变量)分批复制到刚申请的内存中。分批是因为有限长
  37.                         执行宏调用(`CALL("Kernel32","lstrcpynW","JJFJ",${内存地址+偏移字节},"${分段文本[i].replace(/\"/g,'\"\"')}",${分段字节[i]})`);
  38.                         偏移字节+=分段字节[i];        //返回地址J。        //字符串中含双引号出错,因此替换成单引号
  39.                 }
  40.                 执行宏调用(`CALL("Kernel32","GlobalUnlock","JJ",${内存句柄})`);        //解锁全局内存对象,以释放资源
  41.                 return 内存句柄;
  42.         }else{console.log("未能分配内存!");}
  43. }

  44. function 内存取字符串(内存句柄){        //返回字符串
  45.         const 执行宏调用=ExecuteExcel4Macro,段长度=127;
  46.         const 内存地址=执行宏调用(`CALL("Kernel32","GlobalLock","JJ",${内存句柄})`);        //锁定,获取内存地址
  47.         if(内存地址){
  48.                 const 总字节=执行宏调用(`CALL("Kernel32","lstrlenA","JJ",${内存地址})`);        //内存文本字节数
  49.                 let 偏移字节=0,文本字符串=分段文本='';
  50.                 while(偏移字节<总字节){        //返回字符串F。        //返回超255字节时,也需要分段操作
  51.                         分段文本=执行宏调用(`CALL("Kernel32","lstrcpynW","FFJJ","",${内存地址+偏移字节},${段长度})`);
  52.                         //偏移字节+=执行宏调用(`CALL("Kernel32","lstrlenA","JC","${分段文本.replace(/["\n]/g,'x')}")`);
  53.                         偏移字节+=分段文本.replace(/[^\x00-\xff]/g,'xx').length;        //计算字符串字节数
  54.                         //偏移字节+=执行宏调用(`LENB("${分段文本.replace(/"/g,'x')}")`);
  55.                         文本字符串+=分段文本;
  56.                 }        //解锁全局内存对象,以释放资源
  57.                 执行宏调用(`CALL("Kernel32","GlobalUnlock","JJ",${内存句柄})`);
  58.                 return 文本字符串;
  59.         }else{console.log("未找到内存地址!");}
  60. }
复制代码
 楼主| 发表于 2026-6-13 15:36:36 | 显示全部楼层

调用WinAPI基础小单元

单个WinAPI函数对应一个JS函数
  1. function 打开剪贴板(){
  2.         const 执行宏调用=ExecuteExcel4Macro;
  3.         let 打开结果=执行宏调用(`CALL("User32","OpenClipboard","AJ",0)`);
  4.         return 打开结果;        //if(打开结果){console.log("成功打开剪贴板!");}else{console.log("剪贴板打开失败。");}
  5. }
  6. function 清空剪贴板(){
  7.         const 执行宏调用=ExecuteExcel4Macro;
  8.         let 清空结果=执行宏调用(`CALL("User32","EmptyClipboard","A")`);
  9.         return 清空结果;        //if(清空结果){console.log("成功清空剪贴板!");}else{console.log("剪贴板清空失败。");}
  10. }
  11. function 设置剪贴板(数据格式,数据句柄){
  12.         const 执行宏调用=ExecuteExcel4Macro;        //数据格式:位图2 文本1 统一文本0xD=13
  13.         let 数据内存句柄=执行宏调用(`CALL("User32","SetClipboardData","JJJ",${数据格式},${数据句柄})`);
  14.         return 数据内存句柄;        //if(数据内存句柄){console.log("成功设置剪贴板!");}else{console.log("剪贴板设置失败。");}
  15. }
  16. function 关闭剪贴板(){
  17.         const 执行宏调用=ExecuteExcel4Macro;
  18.         let 关闭结果=执行宏调用(`CALL("User32","CloseClipboard","A")`);
  19.         return 关闭结果;        //if(关闭结果){console.log("成功关闭剪贴板!");}else{console.log("剪贴板关闭失败。");}
  20. }
复制代码
 楼主| 发表于 2026-6-17 17:19:05 | 显示全部楼层

浏览器控制台自动入库/JS

自动入库[庚午].zip (7.87 KB)

  1. //自动入库.JS
  2. //版本庚午
  3. //问题:[有重复代码]

  4. /*更新:整理简化注释。
  5. 旧:
  6. 9、增加部分验证单据自动入库。
  7. 8、简化单据显示信息,只显示单据号、单位、日期等。
  8. 7、修正:部分分组不会选择。
  9. 6、修正:整页都是已入库而未验证状态时,会卡在勾选处。
  10. 5、监听与触发条件:切换标签触发。
  11. 4、查询后,先检查有无入库单据。
  12. 3、查询条件:从两年前到一周前,验证状态为未验证。
  13. 2、定位到最后一页,从最老的单据开始入库,逐页向前。
  14. 1、验证日期判断整理简化;添加干支查询表。
  15. */

  16. /*干支表
  17. 01.甲子 02.乙丑 03.丙寅 04.丁卯 05.戊辰 06.己巳 07.庚午 08.辛未 09.壬申 10.癸酉
  18. 11.甲戌 12.乙亥 13.丙子 14.丁丑 15.戊寅 16.己卯 17.庚辰 18.辛巳 19.壬午 20.癸未
  19. 21.甲申 22.乙酉 23.丙戌 24.丁亥 25.戊子 26.己丑 27.庚寅 28.辛卯 29.壬辰 30.癸巳
  20. 31.甲午 32.乙未 33.丙申 34.丁酉 35.戊戌 36.己亥 37.庚子 38.辛丑 39.壬寅 40.癸卯
  21. 41.甲辰 42.乙巳 43.丙午 44.丁未 45.戊申 46.己酉 47.庚戌 48.辛亥 49.壬子 50.癸丑
  22. 51.甲寅 52.乙卯 53.丙辰 54.丁巳 55.戊午 56.己未 57.庚申 58.辛酉 59.壬戌 60.癸亥*/

  23. //let 操作全区=document.getElementById('armsTraceFlag');        //document.querySelector('div#armsTraceFlag.content > div.upout-bill-entry');
  24. //let 标签区=操作全区.querySelector('div[role="tablist"].ant-tabs-top-bar');
  25. //let 操作面板区=操作全区.querySelector('div[role="tabpanel"].ant-tabs-tabpane');
  26. //let 查询区=操作面板区.querySelector('div.upPutBill-common-wrap > div.table-and-search-layout-search > form');
  27. //let 查询条件区=查询区.querySelector('div.expanded > div[data-spm-anchor-id].ant-row');
  28. //let 查询按钮区=查询区.querySelector('div.ant-form-item > div > div.ant-form-item-control > span > div.tracev3-search-form-button');
  29. //let 表单区=操作面板区.querySelector('div.table-and-search-layout-table > div');

复制代码

评分

参与人数 1技术 +1 收起 理由
zzz19760225 + 1 感谢分享

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-7-14 10:25

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表