1234

ExcelHome技术论坛

用户名  找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

求助:JSA或者VBA将一维转三维

[复制链接]

TA的精华主题

TA的得分主题

发表于 2025-1-2 21:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Again123456 发表于 2025-1-2 18:04
明白你的不用排序

类似铭佬的原理吧?
铭佬的核心原理是,每个类别相当于1个子表,reduce后,再合并子表,因此不需要排序。
大体上就是,把每一行,扔到对应的字典中,而该字典是个复杂的数组结构,里面又有数组,又有小字典
最后合并字典中的数组,就是最终结果了,自然而然就已经是排序后的结果。

TA的精华主题

TA的得分主题

发表于 2025-1-2 21:07 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Again123456 发表于 2025-1-2 19:23
优化了一下新加一行的逻辑,速度上去了。

这个逻辑好呀,if 块中代码只执行1次,效率高多了。

TA的精华主题

TA的得分主题

发表于 2025-1-2 21:19 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Again123456 发表于 2025-1-2 19:23
优化了一下新加一行的逻辑,速度上去了。

铭佬的好多技巧,在这个贴子有有详细的注释,就像您的注释一样,毫无保留。大家的问题,铭佬也都耐心解答。
我常常会去温习这个贴子的内容,有太多的知识盲点,好像懂了,应用的时候又无法自如掌控。
https://club.excelhome.net/threa ... tml?_dsign=92b76fb0

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-2 21:27 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
lizhipei78 发表于 2025-1-2 20:22
经测试,如果要排序,始终没有我的快,把计算时间放在排序后比我的快一点

可能数组就是这样,排序,插入等操作,效率就是低。
因为题目是排好序的就不考虑了。
再说,如果题就是不要求排序,而是每连续区域合并呢?

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-2 23:57 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2025-1-3 10:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

非常感谢,又学到新知识,这个比之前的简易懂多了,铭大那个我至今都不清楚写的啥

TA的精华主题

TA的得分主题

发表于 2025-1-3 15:21 | 显示全部楼层


既然数组 p 已经兼任字典了,索性在数组 p 中再增加一个字典取代原来的字典 dic
  1. function  testA(){
  2.         let data = Sheets('区').Range('a2').CurrentRegion().slice(1);
  3.         let res = data.reduce((p, [sn, name, type, count], row) => {
  4.                 let col = count + 1, colDic = type + col;
  5.                 p[0][col] ??= count; //优化了冗余赋值
  6.                 row = p[colDic] ??= (p[type] ??= p.push([type]) - 1); //p[colDic]、p[type],由数组 p 兼任的2个字典
  7.                 (p[row] ??= [type])[col] = sn + name;
  8.                 return p[colDic]++, p;
  9.         }, [['类别']])
  10.         let sht = Sheets('区三维');
  11.         sht.UsedRange.Clear();
  12.         sht.Range('a1').Resize(res.length, res[0].length).Value2 = res;
  13.         sht.UsedRange.Columns(1).RangeEx.MergeSame();
  14.         sht.UsedRange.Borders.LineStyle = xlContinuous;
  15. }
复制代码

上次的代码是:
  1. function  test(){//本方法为直接写数组元素法
  2.         let data = Sheets('区').Range('a2').CurrentRegion().slice(1)//原始数据已按类型排序,就不写排序了
  3.         let startRow, dic//定义2个变量,每一种类型起始行,记录类别初始行号的字典
  4.         let linkcells = []
  5.         let res = data.reduce((p,[sn,name,type,count],i) => {
  6.                 let col = count + 1 //要写入的列
  7.                 p[0][col] = count  //写入列标题
  8.                 /*下行代码的作用是,首次扫描到类别 type 时:
  9.                   1、字典 dic 赋初值 {},记录列号对应的行号
  10.                   2、把类别 type 压入数组 p 的新行
  11.                   3、把该类的初始行号,赋值给p[type],即数组p又兼任字典,同时,初始行号赋值给startRow*/
  12.                 let startRow = p[type] ??= (dic = {}, p.push([type]) - 1)
  13.                 let row = dic[col] ??= startRow; //dic[col]赋初值startRow,dic记录的是col对应的row
  14.                 /*圆括号中的表达式含义是:数组p的row行不存在,type压入新行,否则保持原来的p[row]
  15.                 (p[row] ??= [type]) 结果是 p[row],后面跟[col],最终左侧就是 p[row][col],接着就是赋值*/
  16.                 (p[row] ??= [type])[col] = sn + name;
  17.                 return dic[col]++, p; //dic[col]自加1,表示下次col列的行号是新的一行,最后返回数组p
  18.         },[['类别']])//结果初始值就一个单元格
  19.         let sht = Sheets('区三维')
  20.         sht.UsedRange.Clear()
  21.         sht.Range('a1').Resize(res.length , res[0].length).Value2 = res
  22.         sht.UsedRange.Columns(1).RangeEx.MergeSame()
  23.         sht.UsedRange.Borders.LineStyle = xlContinuous
  24. }
复制代码

代码确实更简练了,不过也更难看懂了

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2025-1-3 15:37 | 显示全部楼层
lizhipei78 发表于 2025-1-3 10:47
非常感谢,又学到新知识,这个比之前的简易懂多了,铭大那个我至今都不清楚写的啥

你的思路也很敏捷啊,构思新颖
铭佬的思路是一样的,把铭佬代码中的 ??= 展解开了,就容易理解了。比如:
Snipaste_2025-01-03_15-36-09.png

TA的精华主题

TA的得分主题

发表于 2025-1-3 15:53 | 显示全部楼层

把 startRow,dic 变量移入 reduce 块,dic 用 p['r'] 兼任,尽量减少外部变量的定义,占赞!

TA的精华主题

TA的得分主题

发表于 2025-1-3 18:25 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 lizhipei78 于 2025-1-3 18:41 编辑
一江春水1688 发表于 2025-1-3 15:37
你的思路也很敏捷啊,构思新颖
铭佬的思路是一样的,把铭佬代码中的 ??= 展解开了,就容易理解了。比如 ...

你们太拼了吧,为了一道题目,精益求精,没办法了,我也只能继续优化了
01.png
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

1234

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

GMT+8, 2025-4-9 11:22 , Processed in 0.026763 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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