WPS JS宏入门案例集锦

打印 上一主题 下一主题

主题 623|帖子 623|积分 1869

JS宏官方API文档:https://qn.cache.wpscdn.cn/encs/doc/office_v19/index.htm
批量创建工作表/簿

批量创建工作表:
  1. function 批量创建工作表(){
  2.         for (var city of ["成都","上海","北京"]){
  3.                 let sht = Worksheets.Add();
  4.                 sht.Name = city;
  5.         }
  6. }
复制代码
批量创建工作簿:
  1. function 批量创建工作簿(){
  2.         for (var city of ["成都","上海","北京"]){
  3.                 book = Workbooks.Add();
  4.                 book.SaveAs(`E:/tmp/${city}`);
  5.                 book.Close();
  6.         }
  7. }
复制代码
若book.SaveAs不传入全路径,则默认大概保存到我的文档文件夹中。
批量拆分工作表到工作簿

数据如下:

执行代码:
  1. function 批量拆分工作表(){
  2.         for (var sh of Sheets){
  3.                 // 如果既不指定 Before 也不指定 After,则新建一个工作簿,其中包含复制的工作表。
  4.                 sh.Copy();
  5.                 ActiveWorkbook.SaveAs(`E:/VBA/wps/${sh.Name}.xlsx`);
  6.                 ActiveWorkbook.Close();
  7.         }
  8. }
复制代码
分解出3个独立的文件:

批量判断处置惩罚单元格数据

数据和需求如下:

简朴的方法就是直接筛选再复制粘贴,但是现在我们必要完全基于js宏的语法实现:
  1. function 分数筛选(){
  2.         var Arr1=[];
  3.         var Arr2=Range("a2:b13").Value();
  4.         for (var row of Arr2){
  5.                 if (row[1]>=100){
  6.                         Arr1.push(row);
  7.                 }
  8.         }
  9.         Range("d4").Resize(Arr1.length,2).Value2=Arr1
  10. }
复制代码
运行后:

工资条制作

数据如下:

执行如下代码:
  1. function 工资条制作()
  2. {
  3.         Application.DisplayAlerts=false;
  4.         let src=Sheets("工资表");
  5.         for(let sht of Sheets){
  6.                 if(sht.Name=="结果") sht.Delete();
  7.         }
  8.         Application.DisplayAlerts=true;
  9.         var sht=Worksheets.Add();
  10.         sht.Name="结果";
  11.         for(i=0;i<10;i++) {
  12.                 src.Range("a1:m4").Copy();
  13.                 sht.Cells.Item(5*i+1,1).PasteSpecial();
  14.                 src.Range(`A${i+5}:M${i+5}`).Copy();
  15.                 sht.Cells.Item(5*i+5,1).PasteSpecial();
  16.         }
  17.         sht.Activate()
  18. }
复制代码
拆分效果:

   注意:假如原表不止10人,则修改循环次数即可。
  假如答应直接在原表上修改,可以利用相对引用录制宏得到代码:
  1. function 工资条制作2()
  2. {
  3.         Range("a1:m4").Select();
  4.         for (var i=1;i<=9;i++){
  5.                         Selection.Copy();
  6.                         ActiveCell.Offset(5, 0).Range("A1:M4").Insert(xlShiftDown, undefined);
  7.                         Application.CutCopyMode = false;
  8.                         ActiveCell.Offset(5, 0).Range("A1:M4").Select();
  9.         }
  10. }
复制代码
任意多列SN号合并到一列

原数据都是如下格式的SN号:

下面我们思量通过宏代码合并到一列,代码如下:
  1. function 单表多列合并到一列新文件()
  2. {
  3.         var vs=Range("A1").CurrentRegion.Value().flat();
  4.         // 过滤掉空值并去重
  5.         vs=Array.from(new Set(vs.filter(v=>v!=undefined)));
  6.         // 一维数组默认赋值给一行,赋值给一列需要先转置二维
  7.         vs = WorksheetFunction.Transpose(vs);
  8.         var wb = Workbooks.Add();
  9.         wb.Sheets(1).Range("A1").Resize(vs.length,1).Value2 = vs;
  10. }
复制代码
  注意:上面的代码利用JavaScript的语法对数组举行了去重。
  1. Array.from(new Set(arr))
复制代码
过滤空值:
  1. arr.filter(v=>v!=undefined)
复制代码
最终得到一列:

批量合并工作表并添加来源表名

原数据:

执行代码:
  1. function 合并工作表数据(){
  2.         var NewArr=[],n=1;
  3.         for (var ws of Sheets){
  4.                 var Arr=ws.Range("a1").CurrentRegion.Value();
  5.                 if (n++ ==1){var title=Arr[0].concat("工作表名")};
  6.                 delete Arr[0]
  7.                 Arr.forEach(ar=>NewArr.push(ar.concat(ws.Name)));
  8.         }
  9.         NewArr.unshift(title);
  10.         var wb=Workbooks.Add();
  11.         wb.Sheets(1).Range("a1").Resize(NewArr.length,NewArr[0].length).Value2=NewArr;
  12. }
复制代码
乐成合并得到如下效果:

语音朗读

代码如下:
  1. function Workbook_Open()
  2. {
  3.     Application.Speech.Speak("美好的一天就从这一刻开始吧!",true)
  4. }
  5. function Workbook_NewSheet(Sh)
  6. {
  7.     Application.Speech.Speak("果然狠人老表,区区几张sheet是不够你消遣的!",true)
  8. }
  9. function Application_WorkbookBeforeClose(Wb, Cancel)
  10. {
  11.     Application.Speech.Speak("就想问老板,可以下班了吗?")
  12. }
  13. function Application_SheetSelectionChange(Sh, Target){
  14.         if(Sh.Name!="词汇"|Target.Value()==undefined) return;
  15.         Application.Speech.Speak(Target.Value());
  16. }
复制代码
保存上面的代码后,当打开或关闭该文件或新建工作表都会朗读对应的文字。
对于词汇这张工作表,点击任何有值的单元格都会对其举行朗读。
Application.Speech.Speak第二个参数传入true表示异步,默认为同步。
富文本弹窗

alert函数支持传入HTML:
  1. function testAlert_CSS(){
  2.         let foo = `
  3.                 <h3 style="color:red">Hi</h3>
  4.                 <p style="color:green;text-shadow: 1px 1px 2px red, 0 0 1em blue, 0 0 0.2em blue;">
  5.                         Hi ${new Date().toLocaleDateString()}
  6.                 </p>`;
  7.         alert(foo)
  8. }
复制代码
执行效果:

判断目标是否在指定区域内

  1. function _m_isInArea(uArea,cell){
  2.     uArea = typeof(uArea) =="string" ? Range(uArea):uArea;
  3.     cell = typeof(cell) =="string" ? Range(cell):cell;
  4.     if(uArea.Parent.Name!=cell.Parent.Name) return false;
  5.     let s_row=uArea.Row,e_row=s_row+uArea.Rows.Count-1;
  6.     let s_col=uArea.Column,e_col=s_col+uArea.Columns.Count-1;
  7.     let t_row = cell.Row,t_col = cell.Column;
  8. //        Console.log(`${s_row}-${e_row},${s_col}-${e_col},(${t_row},${t_col})`);
  9.         return s_row<=t_row && t_row<=e_row && s_col<=t_col && t_col<=e_col;
  10. }
  11. function _m_test(){
  12.     Console.log(_m_isInArea("A2:C20","B3"));
  13.     Console.log(_m_isInArea("A2:C20","D3"));
  14. }
复制代码
效果:
  1. true
  2. false
复制代码
当地文件读写

  1. function read_write_data_txt(){
  2.         let txtFile = "E:/tmp/a.txt";
  3.        
  4.     let f = FreeFile() ;
  5.         Open(txtFile,f,jsOutput,jsWrite);
  6.         Write(f,"123");
  7.         Write(f,"456,789");
  8.         Write(f,"aaa,bbb");
  9.     Close();
  10.    
  11.     Console.clear()
  12.     let fNumber = FreeFile()
  13.     Open(txtFile, fNumber,jsInput)
  14.     while(!EOF(fNumber)) {
  15.             let p=LineInput(fNumber);
  16.             Console.log(p)
  17.     }
  18.     Close(fNumber)
  19. }
复制代码
  1. "123"
  2. "456,789"
  3. "aaa,bbb"
复制代码
生成文件:

JavaScript语法补充

undefined和null的区别

undefined和null的区别(值相称,但类型不等) :
  1. typeof undefined             // undefined
  2. typeof null                  // object
  3. null === undefined           // false
  4. null == undefined            // true
复制代码
typeof操作符

typeof 操作符可以检测变量的数据类型 :
  1. typeof "John"                 // 返回 string
  2. typeof 3.14                   // 返回 number
  3. typeof NaN                    // 返回 number
  4. typeof false                  // 返回 boolean
  5. typeof [1,2,3,4]              // 返回 object
  6. typeof {name:'John', age:34}  // 返回 object
  7. typeof new Date()             // 返回 object
  8. typeof function () {}         // 返回 function
  9. typeof myCar                  // 返回 undefined (如果 myCar 没有声明)
  10. typeof null                   // 返回 object
复制代码
解构赋值

  1. var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
  2. console.log('x = ' + x + ', y = ' + y + ', z = ' + z);
  3. // x = hello, y = JavaScript, z = ES6
  4. [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
  5. console.log('x = ' + x + ', y = ' + y + ', z = ' + z);
  6. // x = hello, y = JavaScript, z = ES6
复制代码
数组常用方法

方法描述concat()连接两个或更多的数组,并返回效果。copyWithin()从数组的指定位置拷贝元素到数组的另一个指定位置中。entries()返回数组的可迭代对象。every()检测数值元素的每个元素是否都符合条件。fill()利用一个固定值来填充数组。filter()检测数值元素,并返回符合条件全部元素的数组。find()返回符合传入测试(函数)条件的数组元素。findIndex()返回符合传入测试(函数)条件的数组元素索引。forEach()数组每个元素都执行一次回调函数。from()通过给定的对象中创建一个数组。includes()判断一个数组是否包含一个指定的值。indexOf()搜刮数组中的元素,并返回它地点的位置。isArray()判断对象是否为数组。join()把数组的全部元素放入一个字符串。keys()返回数组的可迭代对象,包含原始数组的键(key)。lastIndexOf()搜刮数组中的元素,并返回它最后出现的位置。map()通过指定函数处置惩罚数组的每个元素,并返回处置惩罚后的数组。pop()删除数组的最后一个元素并返回删除的元素。push()向数组的末尾添加一个或更多元素,并返回新的长度。reduce()将数组元素盘算为一个值(从左到右)。reduceRight()将数组元素盘算为一个值(从右到左)。reverse()反转数组的元素次序。shift()删除并返回数组的第一个元素。slice()选取数组的的一部门,并返回一个新数组。some()检测数组元素中是否有元素符合指定条件。sort()对数组的元素举行排序。splice()从数组中添加或删除元素。unshift()向数组的开头添加一个或更多元素,并返回新的长度。 splice:
splice()方法可以从指定的索引开始删除多少元素,然后再从该位置添加多少元素:
  1. var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
  2. // 从索引2开始删除3个元素,然后再添加两个元素:
  3. arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
  4. arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
  5. // 只删除,不添加:
  6. arr.splice(2, 2); // ['Google', 'Facebook']
  7. arr; // ['Microsoft', 'Apple', 'Oracle']
  8. // 只添加,不删除:
  9. arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
  10. arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
复制代码
concat:
concat()方法把当前的Array和另一个Array连接起来,并返回一个新的Array:
  1. var arr = ['A', 'B', 'C'];
  2. var added = arr.concat([1, 2, 3]);
  3. added; // ['A', 'B', 'C', 1, 2, 3]
  4. arr; // ['A', 'B', 'C']
复制代码
请注意,concat()方法并没有修改当前Array,而是返回了一个新的Array。
实际上,concat()方法可以吸收任意个元素和Array,而且主动把Array拆开,然后全部添加到新的Array里:
  1. var arr = ['A', 'B', 'C'];
  2. arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]
复制代码
join:
join()方法把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
  1. var arr = ['A', 'B', 'C', 1, 2, 3];
  2. arr.join('-'); // 'A-B-C-1-2-3'
复制代码
假如Array的元素不是字符串,将主动转换为字符串后再连接。
map函数碰到的问题

map的语法:
  1. array.map(function(currentValue,index,arr), thisValue)
复制代码


  • currentValue: 当前元素的值
  • index : 当前元素的索引值
  • arr : 前元素属于的数组对象
  • thisValue:用作 “this” 的值。假如省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
利用map()把字符串变成整数 :
  1. var arr = ['1', '2', '3'];
  2. var r = arr.map(parseInt);
  3. console.log(r);
  4. //结果却是1, NaN, NaN
复制代码
这是由于parseInt接受两个参数(string, radix),第二个参数指定被转换的“数字”多少进制。
当arr = [1,2,3]时,arr.map(parseInt)实际为:
  1. parseInt('1', 0);  // 按十进制转换'1'
  2. parseInt('2', 1);  // 按一进制转换'2',但一进制中只有0没有1
  3. parseInt('3', 2);  // 按二进制转换3,但二进制中只有0和1没有2
复制代码
办理办法:
  1. var arr = ['1', '2', '3'];
  2. var r = arr.map(str=>parseInt(str));
  3. console.log(r);
  4. // 结果:1,2,3
复制代码
模板字符串

  1. var name = '小华';
  2. var age = 20;
  3. var message = `你好, ${name}, 你今年${age}岁了!`;
复制代码
循环语句

for循环

语法:
  1. for (语句 1; 语句 2; 语句 3) {
  2.     被执行的代码块
  3. }
复制代码


  • 语句1 (代码块)开始前执行
  • 语句2 定义运行循环(代码块)的条件
  • 语句3 在循环(代码块)已被执行之后执行
  1. for (var i=0,len=cars.length; i<len; i++)
  2. {
  3.     document.write(cars[i] + "<br>");
  4. }
  5. // 或
  6. var i=2,len=cars.length;
  7. for (; i<len; i++)
  8. {
  9.     document.write(cars[i] + "<br>");
  10. }
复制代码
for…in循环

for/in 语句循环遍历对象的属性:
  1. var person={fname:"John",lname:"Doe",age:25};
  2. for (x in person)  // x 为属性名
  3. {
  4.     txt=txt + person[x];
  5. }
复制代码
循环遍历Array的索引:
  1. var a = ['A', 'B', 'C'];
  2. for (var i in a) {
  3.     console.log(i); // '0', '1', '2'
  4.     console.log(a[i]); // 'A', 'B', 'C'
  5. }
复制代码
  注意:for ... in对Array的循环得到的是String而不是Number。
  for…of循环

具有iterable类型的聚集还可以通过for ... of循环来遍历,它是ES6引入的新的语法。
  1. var a = ['A', 'B', 'C'];
  2. var s = new Set(['A', 'B', 'C']);
  3. var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
  4. for (var x of a) { // 遍历Array
  5.     console.log(x);
  6. }
  7. for (var x of s) { // 遍历Set
  8.     console.log(x);
  9. }
  10. for (var x of m) { // 遍历Map
  11.     console.log(x[0] + '=' + x[1]);
  12. }
复制代码
for of循环和for in循环的区别

for ... in循环遍历的实际是对象的属性名称,手动给Array对象添加了额外的属性后:
当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的不测效果:
  1. var a = ['A', 'B', 'C'];
  2. a.name = 'Hello';
  3. for (var x in a) {
  4.     console.log(x); // '0', '1', '2', 'name'
  5. }
复制代码
for ... of循环则只循环聚集自己的元素:
  1. var a = ['A', 'B', 'C'];
  2. a.name = 'Hello';
  3. for (var x of a) {
  4.     console.log(x); // 'A', 'B', 'C'
  5. }
复制代码
iterable内置的forEach方法

  1. var a = ['A', 'B', 'C'];
  2. a.forEach(function (element, index, array) {
  3.     // element: 指向当前元素的值
  4.     // index: 指向当前索引
  5.     // array: 指向Array对象本身
  6.     console.log(element + ', index = ' + index);
  7. });
  8. var s = new Set(['A', 'B', 'C']);
  9. //Set没有索引,因此回调函数的前两个参数都是元素本身
  10. s.forEach(function (element, sameElement, set) {
  11.     console.log(element);
  12. });
  13. var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
  14. //Map的回调函数参数依次为value、key和map本身
  15. m.forEach(function (value, key, map) {
  16.     console.log(value);
  17. });
复制代码
回调函数可以省略参数:
  1. var a = ['A', 'B', 'C'];
  2. a.forEach(function (element) {
  3.     console.log(element);
  4. });
复制代码
while 循环

语法:
  1. while (条件)
  2. {
  3.     需要执行的代码
  4. }
  5. // 或
  6. do
  7. {
  8.     需要执行的代码
  9. }
  10. while (条件);
复制代码
例子:
  1. while (i<5)
  2. {
  3.     x=x + "The number is " + i + "<br>";
  4.     i++;
  5. }
  6. do
  7. {
  8.     x=x + "The number is " + i + "<br>";
  9.     i++;
  10. }
  11. while (i<5);
复制代码
箭头函数与装饰器

ES6 新增了箭头函数,语法 :
  1. (参数1, 参数2, …, 参数N) => { 函数声明 }
  2. 单一参数 => {函数声明}
  3. () => {函数声明}
复制代码
例子:
  1. const x = (x, y) => x * y;
  2. const x = (x, y) => { return x * y };
复制代码
箭头函数简化了函数定义,假如只包含一个表达式,可以省略{ ... }和return。
假如要返回一个对象,单表达式会报错:
  1. // SyntaxError:
  2. x => { foo: x }
复制代码
由于和函数体的{ ... }有语法冲突,所以要改为:
  1. // ok:
  2. x => ({ foo: x })
复制代码
箭头函数看上去是匿名函数的一种简写,但有个显着的区别:箭头函数内部的this是词法作用域,由上下文确定。
箭头函数的this总是指向词法作用域,也就是外层调用者obj:
  1. var obj = {
  2.     birth: 1990,
  3.     getAge: function () {
  4.         var b = this.birth; // 1990
  5.         var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
  6.         return fn();
  7.     }
  8. };
  9. obj.getAge(); // 25
复制代码
由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this举行绑定,即传入的第一个参数被忽略:
  1. var obj = {
  2.     birth: 2000,
  3.     getAge: function (year) {
  4.         var b = this.birth; // 1990
  5.         var fn = (y) => y - this.birth; // this.birth仍是2000
  6.         return fn.call({birth:2010}, year);
  7.     }
  8. };
  9. obj.getAge(2015); // 15
复制代码
在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window。
要指定函数的this指向哪个对象,可以用函数自己的apply方法,它吸收两个参数,第一个参数就是必要绑定的this变量,第二个参数是Array,表示函数自己的参数。
用apply修复getAge()调用:
  1. function getAge() {
  2.     var y = new Date().getFullYear();
  3.     return y - this.birth;
  4. }
  5. var xiaoming = {
  6.     name: '小明',
  7.     birth: 1990,
  8.     age: getAge
  9. };
  10. xiaoming.age(); // 25
  11. getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
复制代码
利用apply()可实现装饰器,比如想统计一下代码一共调用了多少次:
  1. 'use strict';
  2. var count = 0;
  3. var oldParseInt = parseInt; // 保存原函数
  4. window.parseInt = function () {
  5.     count += 1;
  6.     return oldParseInt.apply(null, arguments); // 调用原函数
  7. };
  8. parseInt('10');
  9. parseInt('20');
  10. parseInt('30');
  11. console.log('count = ' + count); // 3
复制代码
call()与apply()类似,唯一区别是:


  • apply()把参数打包成Array再传入;
  • call()把参数按次序传入。
比如调用Math.max(3, 5, 4),分别用apply()和call()实现如下:
  1. Math.max.apply(null, [3, 5, 4]); // 5
  2. Math.max.call(null, 3, 5, 4); // 5
复制代码
对普通函数调用,通常把this绑定为null。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

金牌会员
这个人很懒什么都没写!

标签云

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