ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 怎样把药方中每种药材的数量,按多少重新排序

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-23 17:04 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
sunya_0529 发表于 2024-9-7 20:53
趁着周末研究了一下,着实有点头疼,字符串的构成规律有,但逻辑上要统一还是有点难度的,建议把药方先用表 ...

sunya_0529 老师好!
我今天再找了个电脑,重新下载了一个新版WPS软件试了下,由于未用过WPS,你写的JSA代码还是未找到,恳请你详教查看和运行该代码的具体步骤,感谢!

TA的精华主题

TA的得分主题

发表于 2024-9-23 17:12 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
相见是缘8 发表于 2024-9-14 18:12
让老师见笑了!
唉!人与人没有可比性,好多问题对老师来说,可能很简单,可对我来说很难!老师学习了二 ...

所以你的意思是我就是学不会,你们帮我就可以了是吧?

TA的精华主题

TA的得分主题

发表于 2024-9-23 17:47 | 显示全部楼层
相见是缘8 发表于 2024-9-23 17:04
sunya_0529 老师好!
我今天再找了个电脑,重新下载了一个新版WPS软件试了下,由于未用过WPS,你写的JSA ...

看图说话,只教一遍,这个是常识性内容了——

微信截图_20240923174118.png

微信截图_20240923174216.png

微信截图_20240923174306.png

微信截图_20240923174448.png

微信截图_20240923174557.png

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-23 18:34 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 相见是缘8 于 2024-9-23 18:42 编辑
sunya_0529 发表于 2024-9-23 17:47
看图说话,只教一遍,这个是常识性内容了——

sunya_0529老师好!
感谢!让你受累了,抱歉!
我也基本上是按照你图所教的步骤操作,只是我的第一张图中,未出现“宏的安全警告”,且到你第4张图中,未出现“宏代码”……不知那里没操作好,还请你指教!

2 (1).png
2.png
3.png

TA的精华主题

TA的得分主题

发表于 2024-9-23 19:07 | 显示全部楼层
相见是缘8 发表于 2024-9-23 18:34
sunya_0529老师好!感谢!让你受累了,抱歉!我也基本上是按照你图所教的步骤操作,只是我的第一张图中, ...

重新去16楼下载附件,同时看看电脑上有没有杀毒软件误把带宏的文件中宏代码给清除了。
https://club.excelhome.net/forum ... 54&pid=11578689

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-24 06:48 | 显示全部楼层
本帖最后由 相见是缘8 于 2024-9-25 05:32 编辑
  1. function 药方整理() {
  2.     const units = ['克', '枚', '粒', '片', '只', '条', '个', '寸', '毫升', '杯', '剂'].join('|');        //定义药方中用到的计量单位
  3.     const sortMaterials = (str) => { //定义一个函数,对传入的字符串解析后分组排序,并输出新字符串
  4.         let strStart = /^((\d+)|(.+?:)).+/.test(str) ? str.match(/^((\d+)|(.+?:)).+/)[1] : '';        //定义前导字符串
  5.         let materials = str
  6.             .replace(strStart, '')        //替换掉前导字符串
  7.             .replace('\r', '')        //替换掉换行符
  8.             .replace(/[。、,]$/, '')        //替换掉行末的“。、,”
  9.             .replace(new RegExp(`(\\d*\\.?\\d+(${units})(([^()]+))?)(?=[、,。])`, 'g'), '$1;')        //识别“*克(*)”并在其后插入“;”
  10.             .split(';');        //以“;”为分隔符,把字符串拆分成各组
  11.         let strEnd = materials[materials.length - 1];        //取分组中的最后一个元素,不包括“*单位”的话,就作为收尾字符串,加到结果字符串的后面
  12.         strEnd = new RegExp(`.*\\d*\\.?\\d+(${units}).*`).test(strEnd) ? '' : strEnd.replace(/^[、,。]|[、,。]$/g, '');
  13.         let arrTemp = [];        //定义临时数组,存储整理排序后的药材数据
  14.         if (materials) {
  15.             const obj = materials.reduce((a, c) => {        //在各组药材中循环
  16.                 let arr = c
  17.                     .replace(/^[。、,]/, '')        //替换掉行首的“。、,”
  18.                     .replace(/(,各)(?=\d*\.?\d+)/g, '|')        //将“,各”替换成“|”
  19.                     .replace(/(?<=(.+?)、(?=.+?))/g, '※')        //将“()”内的“、”替换为“※”
  20.                     .replace(/、/g, '|')                //将“、”替换为“|”
  21.                     .replace(/※/g, '、')         //将“()”内的“※”替换为“、”(还原)
  22.                     .replace(new RegExp(`((\\d*\\.?\\d+~)?\\d*\\.?\\d+(${units}))`, 'g'), `|$1`)        //在“[药材名][数量][单位]”的“[数量]”前插入“|”
  23.                     .split('|')        //以“|”为分隔符拆分字符串
  24.                     .filter(Boolean);        //过滤掉空值,将字符串拆分成“[药材名1,药材名2,...,*单位]”的数组
  25.                 let unit = String(arr[arr.length - 1])
  26.                     .replace(/(.+)/g, '')        //替换掉“(*)”
  27.                     .replace(new RegExp(`[^${units}]`, 'g'), '');        //获取单位
  28.                 let amount = String(arr[arr.length - 1]).split(unit)[0];        //获取数量
  29.                 a[unit] ??= {};        //以单位为键
  30.                 arr.slice(0, -1).forEach(v => {
  31.                     a[unit][amount] ??= [];        //以数量为二级对象的键,值为数组,用来储存对应的药材名
  32.                     a[unit][amount].push(v + String(arr[arr.length - 1]).split(unit)[1]);        //将药材名存入数组,同时“*单位”后的内容加在各药材后
  33.                 });
  34.                 return a;
  35.             }, {});
  36.             for (let o in obj) {        //在obj对象中循环               
  37.                 Object.keys(obj[o]).sort((a, b) => {        //对数量进行降序排序
  38.                     return (Number(b) ? b : b.slice(b.lastIndexOf('~') + 1)) - (Number(a) ? a : a.slice(a.lastIndexOf('~') + 1));
  39.                 }).forEach(n => {        //循环读取药材数组,写入临时数组arrTemp
  40.                     let brr = obj[o][n];
  41.                     arrTemp.push(brr.length > 1 ? `${brr.join('、')},各${n}${o}` : `${brr[0]}${n}${o}`);
  42.                 });
  43.             }
  44.             if (strEnd.length) arrTemp.push(strEnd);        //收尾字符串不为''的话,加入临时数组
  45.         }
  46.         return `${strStart}${arrTemp.join(';')}`;        //函数返回拼接完整的字符串
  47.     }

  48.     const res = [];        //定义结果储存数组
  49.     [...ActiveDocument.Paragraphs].forEach((p, i) => {        //在文档中各段落循环
  50.         let strPara = p.Range.Text;        //定义段落文本
  51.         if (strPara !== '\r' && !strPara.startsWith('【整理】')) {
  52.             res.push(strPara);
  53.             if (new RegExp(`(\\d*\\.?\\d+(${units}))+`).test(strPara) && !strPara.startsWith('替换为:')) {
  54.                 let strSub = strPara.match(new RegExp(`[^、,。)]+([^)]*(\\d*\\.?\\d+(${units}))[^(]*)(?=[、,。]?)`, 'g'));
  55.                 if (strSub) strSub = strSub.map(s => {        //剔除子配方的字符串
  56.                     strPara = strPara.replace(s, '');
  57.                     let str1 = s.slice(0, s.indexOf('(') + 1);
  58.                     if (!new RegExp(`.+\\d*\\.?\\d+(${units})($`).test(str1)) {                //调用函数,对“()”内的内容进行整理
  59.                         let str2 = s.slice(s.indexOf('(') + 1, s.indexOf(')'));
  60.                         return `${str1}${sortMaterials(str2)})`;
  61.                     } else {
  62.                         return s;
  63.                     }
  64.                 });
  65.                 res.push(`【整理】——${sortMaterials(strPara)}${strSub ? ';' + strSub.join(';') : ''}。\r`)
  66.             }
  67.         }
  68.     });
  69.     ActiveDocument.Content.Delete();        //清空文档内容
  70.     res.forEach(t => {
  71.         let myRange = ActiveDocument.Paragraphs.Last.Range
  72.         myRange.Text = t + '\r';
  73.         if (t.startsWith('【整理】')) myRange.Font.ColorIndex = 5;
  74.     });
  75. }
复制代码

sunya_0529 发表于 2024-9-23 19:07
重新去16楼下载附件,同时看看电脑上有没有杀毒软件误把带宏的文件中宏代码给清除了。
https://club.exc ...


sunya_0529 老师好!
可以了,真的有病毒,真心感谢你的付出和指教!万分感谢!

TA的精华主题

TA的得分主题

发表于 2024-10-1 09:54 | 显示全部楼层
中间还有一些方子缺了呢,为什么不补全,后面也应该还有呀,希望你全部发出来,为弘扬中医作贡献!

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-10-7 07:13 | 显示全部楼层
Meteor-渣渣 发表于 2024-9-23 17:12
所以你的意思是我就是学不会,你们帮我就可以了是吧?

我得罪过你吗?为啥你总是对我阴阳怪气地说三道四?
相帮是情分,不帮是本分,赠人玫瑰手留余香!没有人会无聊得上论坛找喷!你愿意帮,我感谢不尽,不愿意帮,也大可不必如此,没有人是万能的,不懂的总要求人,你说是不是这个道理?

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-10-7 07:48 | 显示全部楼层
yellowhawk 发表于 2024-10-1 09:54
中间还有一些方子缺了呢,为什么不补全,后面也应该还有呀,希望你全部发出来,为弘扬中医作贡献!

你好!中间有一些方子缺了吗?我拿到的就是这样的,请问缺了那些?

TA的精华主题

TA的得分主题

发表于 2024-10-8 22:31 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
相见是缘8 发表于 2024-10-7 07:48
你好!中间有一些方子缺了吗?我拿到的就是这样的,请问缺了那些?

例如这两个方子,后面就没有内容
药.png
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-19 07:45 , Processed in 0.043185 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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