ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 2524|回复: 33

[原创] 用纯VBA方式写JSA代码,超简单(会VBA就会用JSA)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2024-8-4 20:55 | 显示全部楼层 |阅读模式
本帖最后由 lizhipei78 于 2024-8-4 21:41 编辑

    一、前言

    国产化办公是未来的趋势,现在好多机关单位已经只能用国产系统了,办公也只有WPS可选了,VBA没法派上用场了,所以很多同志开始学习JSA。刚开始学习JSA发现好像挺简单的,可是一到应用就头大了,特别是大神写的那些代码,压根不知道什么意思,好比如网上的笑话,教会我1+1=2,可是考试就成了大学微积分了。可能这个时候就有很多人跟我当初一样,入门就是放弃。这里面最大的原因是我们没有能把JSA应用到我们的日常中去,想着我用VBA能解决问题就好了,还可能是年纪大的原因,也不想去深入研究了。后来我发现用纯VBA的方式打开JSA,会有不一样的效果,就像很多东西如果我们不按原厂出场的方式去用它,会发现得到意外的结果。用纯VBA思维去写JSA代码,真的是超简单,一看就懂得,拿来就能用,基本上不用学习什么新方法,对于我们习惯了VBA的同志来说如果想尝试一下新鲜,偶尔想秀一下技能,我觉得完全没有问题。当然了JSA有很多方法,能十分轻松的解决日常中的数据,我十分推荐大家花心思去学习,不过我还是觉得先有兴趣,才会有动力去深入学习。
     对于此,我把这个想法告诉网友,免不了遭到鄙视,我也不想误导大家,纯粹就当玩玩吧,所以才发到VBA版块,没有发到JSA版块,以免于版主说发错了。最后我想告诉你的是,用纯VBA方式写JSA代码,真的超简单,不信来试试。

   
二、VBA的三大法宝
    本人觉得VBA的三大法宝就是数组、字典、循环,这是学习VBA逃不过的,同样的如果我们能熟悉JSA中这三大法宝,那么解决问题不就得心应手了么,其实JSA的方法非常多,单数组就有34种方法,字符串也有几十种,字典的话也有好几种方式实现,所以JSA难就难在方法太多了。但是如果我们用纯VBA方式打开JSA,那就简单多了,那些啥方法的不用就是了,我就耍无赖,就是要写屎山代码,我就是用双循环拿到想要的结果,这样子的话,就是会VBA就会JSA。

   三、认识JSA数组
    JSA数组都是一维数组,或者说没有真正的二维数组,当初就是因为这个我差点弃JSA,我写VBA代码习惯就是,用一个Arr数组取得数据源,定义一个结果数组Brr,然后把符合条件的数据写入Brr中,最后输出就是了。但是JSA中你没法定义一个空的有大小的二维数组,后来我跳过定义这一个,我直接从单元格赋值一个很大的区域给结果数组那不就可以了,这样子我一下子就打开了新大陆。下面用实例来跟大家对比一下,用VBA方式写JSA,不是说一样,简直是一模一样好不。

二维转一维例子.png

数组方法.png


      如上图所示,二维转一维,下面的两个代码,左边是VBA,右边是JSA,大家对着看,是不是非常相似。JSA 数组都是从0下标开始的,VBA中的arr(1,1)即是表格中的Range("A1")的单元格,在JSA中是arr[0][0],大家知道这样子就行了,至于JSA中数组那些方法什么的,不学貌似对我们用VBA方式来说也没啥影响。在平时用VBA的时候,可以先定义一个结果数组,如Dim brr(1 To 1000, 1 To 4),而在JSA中没法这么定义,你至多可以定义一个空的二维数组,如var brr[[]];但是没法定义大小,所以对于习惯使用VBA的人来说,往结果中放符合的数据就比较麻烦,当然JSA中数组的方法很多,对于新手来说,咱们不会,那么我们就是没有条件也要创建条件来硬搞一个有大小的结果数组出来,其实非常简单,直接拿数组赋值给单元格即可,如var brr=Range("A1").Resize(1000,4)();这样子就跟VBA一样了,有了二维数组,那么要丢数据,就是遍历的问题了,这些都是我们VBA惯用的方式啊,没有难度是不是。


   四、字典
    字典是VBA的精华,没有字典VBA很多东西就很难搞了,在JSA中没有字典的说法,它有好几种实现方式,它的数组也可以判断某元素是否在数组中,JSA中有集合,new Map,Object对象都是唯一性的,其中new Map有的网友说这个就是类似VBA的字典,但我更喜欢Object对象,是因为我在VBA中比较喜欢使用dic(s)=dic(s)+1这种方式,在JSA中就是dic=dic+1,基本上一致,可能有的同志喜欢用dic add s,item方式的,那么跟new Map就很类似,这个看个人习惯吧,我强烈推荐使用Object对象来当VBA中的字典使用。看例子吧,用字典提取第一次金额。
字典提取第一次金额.png
字典取值.png
   大家看看,是不是非常简单。还是上面二维转一维的例子,我们用字典写一遍作对比。


字典方法.png

大家看出来了吧,用法都是一样的。再举例一个例子,字典取值一整行,示例大家随便拿一个有数据的表格就行。
字典取一整行.png
  在JSA 中有一个非常好用的数组相连的方式,就是把数组放入中括号加三点就可以了,如图中第9行代码var brr=[...Object.values(dic)];表示的意思就是字典的键值赋给brr数组,并打平,打平即是VBA中嵌套数组,给整成一维数组的意思,如果是相连几个数组的话,也很简单,如var res=[...arr, ...brr]这样子两个数组就结合在一起了,这个在多表格中取值非常方便。好了,字典也聊得差不多了,我觉得大家上手应该不是问题了,末了给大家上个字典嵌套字典在JSA中是如何实现的,其实跟VBA差不多,这个字典嵌套字典,我本人非常喜欢使用,第一层字典取得关键词,第二层用行号来作为字典的键,这样子有了行号,再遍历一下,那就得出结果了。大家可以看一下我之前写的教程https://club.excelhome.net/thread-1672918-1-1.html
字典嵌套字典.png
   这里非常感谢论坛大神,@今铭昔 同志,是他教会的字典嵌套字典。



   五、结言
     写到这里也差不多要结束了,大家看完应该对JSA有信心了吧,不过话说回来有能力的同志,想以后走的更远还是好好学习JSA的知识,我这里是走野路子,不过我始终认为,先有兴趣,懂了一点皮毛,能自己动手写JSA代码解决问题了,这个才是入门的第一步关键,才不会一入门就放弃,后面自己用的多了,自然会去了解相关的知识。后面我会放一些JSA相关的表达方式,大家看着应该能写JSA代码了,当然有空还是看一下这两篇扫盲文。
https://club.excelhome.net/thread-1627461-1-1.html
https://club.excelhome.net/thread-1632020-1-1.html


   江湖再见,后面想到什么再更新吧。

评分

6

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-4 22:07 | 显示全部楼层
这里再给大家讲一个JSA中数组非常实用的功能,那就是数组筛选,这个大家不必要理解多少,对着弄就行了

2024-08-04_215641.png
   如上图所示,brr即是从arr数组中筛选出含有关键词“金建"的条目,就是一句代码就搞定var brr=arr.filter((v)=>v[3]=="金建") ,这里我们只需要更改上面标红的两个地方就是了,v[3] 表示表格中的第四列,之前我有说过JSA中,数组是从0下标开始的,后面 ==是关键词,有了数组筛选,再遍历就简单多了,大家是不是又学到一个实用的技能。
    其实我想说的是,在JSA中好多都是回调函数,但是代码少,不一定代表效率高,这里面它也是循环的,也并没有比我们双循环来得快多少,所以说咱们用纯VBA方式并不输大神的一句话代码。

TA的精华主题

TA的得分主题

发表于 2024-8-4 21:38 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
怎么没看到图呢?

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-4 21:43 | 显示全部楼层
常用代码:
1)Application.ScreenUpdating=false;//关闭屏幕刷新
2)Application.ScreenUpdating=true; //打开屏幕刷新
3)Range("A65536").End(xlUp).Row;  //A列末行向上第一个有值的行数(xlDown)最大行
4)Range("IV1").End(xlToLeft).Column;//第一行末列向左第一列有数值之列数(xlToLeft)最大列
5)Worksheets.Add();//新建工作表
6)ActiveSheet.Name="hao123";   //当前工作表改名为"hao123"
7)Worksheets.Item("hao123").Activate();   //把工作表hao123设置为当前工作表,注意不要忘记括号
8)Cells.Item(4,5).Select(); //选中当前工作表的第4行第5列的单元格,另外一种表示法:Range("E5").Select();
9)var v=Cells.Item(1,1).Value2;//把A1单元格的值赋值给变量V
10)Cells.Item(3,2).EntireRow.Hidden=true;  //隐藏第3行
11)Cells.Item(3,2).EntireRow.Hidden=false;  //取消隐藏第3行
12)Cells.Item(3,2).EntireColumn.Hidden=true;  //隐藏第2列
13)Worksheets.Count;//获取当前工作薄中的工作表数量
14)Application.DisplayAlerts=false; //关闭系统提示对话框
15)Application.DisplayAlerts=true; //打开系统提示对话框
16)Sheets.Item("Sheet1").Delete();   //删除指定的工作表
17)Workbooks.Open("D:\\新建文件夹\\工作簿1.xlsx");  //打开H盘中的新建文件夹中的工作薄1文件(注意JS中的\\)
18)Application.ActiveWorkbook.Name   //获取工作薄的名字,即文件名
19)Range("a1").CurrentRegion.Columns.AutoFit();//自动调整列宽
20)object.keys(arr);//数组是一种特殊的object对象,键名固定是从0开始的整数。
21)arr.push(a);//在数组arr的末尾添加数组元素
22)arr.push.apply(arr,brr); //把数组brr一次性追加到数组arr中
23)var arr=sht.Range("A3:R12").Value2; //单元格区域变数组
24) Range("A2").Resize(brr.length,6).Value2=brr;//把二维数组一次性写入单元格区域中
25)Object.entries(obj)//把对象的属性和属性值转化为一个二维数组
26) Object.keys(obj)  //把对象的属性转化为一维数组
27)Object.values(obj)//把对象的属性值转换为一维数组
28-1)ActiveWorkbook.Name  //激活工作簿名字,即当前工作簿名称
28-2)ThisWorkbook.Name//这个工作簿的名字(只有在加载项的时候才和ActiveWorkbook.Name有区别)
28-3)Workbooks.Item(1).Name
28-4)Workbooks(1).Name
28-5)Workbooks("工作簿1.et").Name//注意各自的表达
29-1)ActiveSheet.Name   //当前工作表名称
29-2)Worksheets("Sheet1").Name
29-3)Worksheets.Item(1).Name
29-4)Worksheets(2).Name
29-5)Sheets(2).Name //注意大小写的写法,初学者最容易出错的点
30-1)Range("a1").Select()   //选择A1单元格
30-2)Cells(2,1).Select() //选择第二行,第一列的单元格,即选择A2单元格
30-3)Cells.Item(3,4).Select()   //D3单元格被选择的另外一种表达法
30-4)Range("a1:E5").Select()
30-5)Columns("D").Select()
30-6)Columns("c:d").Select()
30-7)Range("c:c").Select()
30-8)Range("D1").EntireColumn.Select()
30-9)Range("A:A,C:C").Select()
30-10)Rows("3").Select()
30-11)Rows(3).Select()
30-12)Range("A4").EntireRow.Select()
30-13)Rows("1:5").Select()
30-14)Range("2:2,5:5").Select()
ThisWorkbook.Name//这个工作簿的名字(只有在加载项的时候才和ActiveWorkbook.Name有区别)
var wb=Workbooks.Add();   //新建工作薄
wb.SaveAs(文件路径+文件名);   //保存工作薄
wb.Close();   //关闭工作薄,如果里面参数是true,保存改变
Workbooks.Open(文件路径+文件名)//打开文件,注意js中的文件路径的表达
var shn=ActiveSheet.Name;//把激活工作表的表明赋值给变量shn
注意下面的几种表达方式,基本和VBA差不多,学习的时候多比较.
var shn=Worksheets("Sheet1").Name;
var shn=Worksheets.Item(1).Name;
var shn=Worksheets(2).Name;
var shn=Sheets(2).Name;
单元格或单元格,列或行操作:
// Range("A1").Select()
// Cells(1,1).Select()
// Range("A1:D5").Select()
// Columns("B").Select()
// Columns("B:D").Select()
// Range("E:E").Select()
// Range("C1").EntireColumn.Select()
// Range("A:A,C:C").Select()
// Rows("3").Select()
// Rows(3).Select()
// Range("A3").EntireRow.Select()
// Rows("3:7").Select()
Range("3:3,5:5").Select()
单元格读取
var s=Range("A1").Value();
var s1=Range("A1").Value2;
var s2=Range("A1").valueOf();
var s3=Cells(1,1).Value();
var s4=Cells.Item(1,1).Value2;
单元格区域继续读取:
var arr=Worksheets("原始数据").Range("A1").CurrentRegion.Value2;
var arr=Range("A1:E999").Value();
var arr=Range("A1").Resize(999,5).Value2;
var arr=Range("A1:E"+Range("A65536").End(xlUp).Row).Value();
注意:Value2与Value()的区别,我测试,在日期字段比较明显.
写入工作表中的表达:
Range("A1").Value2=123;  //不可以Range("A1").Value=123,因为Value只读
Range("A2:C2").Value2=[1,2,3];
var arr=[1,2,3] //一维数组的表示法
//下面是数组一次性写入工作表中
Range("a3").Resize(1,arr.length).Value2=arr; //注意Value2不要忘记了
Range("a4").Resize(arr.length,1).Value2=WorksheetFunction.Transpose(arr);
WPS JS中工作簿的表达方式有四种:
ThisWorkbook,表示代码所在的工作簿
ActiveWorkbook,表示活动工作簿
Workbooks.Item(1),用索引表示第几个工作簿
也可以省略Item,直接写为:Workbooks(1)
还可以用工作簿名称表达(记得要带扩展名):
Workbooks.Item("工作簿1.et")或者是:Workbooks("工作簿1.et")
获取工作簿的路径也是用工作簿对象的Path属性,获取到的路径格式中斜杠为单反斜杠:
但是在用Workbooks的Open方法打开文件时,地址中要用双反斜杠:
Workbooks.Open("C:\\Users\\Administrator\\Desktop\\工作簿2.et")
或者用单正斜杠:
Workbooks.Open("C:/Users/Administrator/Desktop/工作簿2.et")
在WPS JS宏中工作表该怎么表达呢?
1、ActiveSheet表示活动工作表
2、Worksheets("工作表名称")表示具体的工作表
3、Worksheets.Item(索引号)表示第几个工作表,最小索引号为1
4、如同工作簿的表达一样,用索引号表示工作表时,Item可以省略,比如Worksheets(索引号)
5、3和4中的Worksheets也可以省略为Sheets(索引号)
不管时VBA还是WPS JS学起来都没想象的那么难,但首先是你得感兴趣,动手去操练,才有可能学会。
WPS JS宏中单元格区域该怎么表达
Range("a1").Select();Cells(1,1).select() //选择A1单元格
Range("a1:d5").Select() 选择A1:D5区域
Columns("c").Select() ;Range("C:C").Select()选择C列
Range("C1").EntireColumn.Select() 选择C列
Columns("a:c").Select() //选择A到C列
Range("A:A,C:C").Select() //分别选择A列,C列
Rows("3").Select();Rows(3).Select();Range("A3").EntireRow.Select()//选择第3行
Rows("3:7").Select() //选定3到5行
Rows("3:3,5:5").Select() //分别选定第3行和第5行

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-4 21:44 | 显示全部楼层
JSA例子.rar (34.3 KB, 下载次数: 38)

我也是新手,希望大家多多指教,有不对的地方请指出。

TA的精华主题

TA的得分主题

发表于 2024-8-5 08:20 | 显示全部楼层
使用VBA的原因,是它的代码容易读懂,最接近人类的语言

TA的精华主题

TA的得分主题

发表于 2024-8-5 08:47 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-8-5 09:04 | 显示全部楼层
兴趣,实用,学习。向楼主学习

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-5 09:33 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
f8b1987 发表于 2024-8-5 08:20
使用VBA的原因,是它的代码容易读懂,最接近人类的语言

现在JSA也可以用人类的语言来写了

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-5 09:35 | 显示全部楼层
ykcbf1100 发表于 2024-8-5 08:47
先收藏,也许以后用得到。

建议你学习一下吧,JSA真的是好多方法可用,VBA我觉得你是到头了,真的没有东西给你学了,就算有那些也是不实用的,对于处理表格来说
你这么热心,我希望看你的代码,还是你来带我上手JSA吧
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-19 03:29 , Processed in 0.049505 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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