ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 修改次序混乱不同的数量单位和重复的数量单位

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-8-28 18:26 | 显示全部楼层
本帖最后由 413191246se 于 2022-8-28 18:35 编辑

sylun 老师的代码,在我的 Win10-x64 + Word 2019 中运行完全正常,但处理结果不正确!(我未改一字。)
相见:请你将老师的代码,放在标准模块 NewMacros 中、强制声明语句 Option Explicit 下面试试。因为有一个变量是全局变量。

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-29 06:23 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
413191246se 发表于 2022-8-28 18:26
sylun 老师的代码,在我的 Win10-x64 + Word 2019 中运行完全正常,但处理结果不正确!(我未改一字。)
...

老师好!
把代码放到下图,这两个红箭头,所指的里面都试了,运行不了!
另外,你说的“强制声明语句 Option Explicit 下面”,是指???
3.png

TA的精华主题

TA的得分主题

发表于 2022-8-29 08:03 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
* 相见:因为 sylun 老师 和我,都是使用 Win10-x64 + Office2019 系统,所以,我们运行完全正常(结果不正确),但在你的 Word 2003 中可能运行有问题!
   
* 我未把老师的代码放到 2003 中运行,虽然去年年底买了一个二手笔记本电脑,就是为了使用 Word 2003,我昨晚突发奇想,也在 Word 2019 中写了一个宏,初步实现了对照修改功能,当然算法无法和老师相比了!
   
* 请你先不要着急!待我今天早饭后,我用二手笔记本电脑运行一下老师的代码,并修改一下我写的宏的代码,作为抛砖引玉给老师借鉴一下(我的宏是在原段落下面复制一段,再修改,这样可以一点一点地对照修改。满意就删除原段落,不满意就对照修改)。
   
* 下面是我昨晚写的 Word 2019 下运行正常的宏的运行快照:
(早饭后我再在 2003 下面改一下。蓝色段落为原稿,绿色突出显示段落是处理段落,粉红色是处理结果)
drugsort (1).jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-29 10:36 | 显示全部楼层
413191246se 发表于 2022-8-29 08:03
* 相见:因为 sylun 老师 和我,都是使用 Win10-x64 + Office2019 系统,所以,我们运行完全正常(结果不正 ...

老师好!
好,万分感谢!期待……!
这个三千多页的文档(还有几本电子书),也是我弟要我帮他搞的,我用手工改了几晩,连一百页都不到……,不得不上论坛向老师求助!

TA的精华主题

TA的得分主题

发表于 2022-8-29 11:38 | 显示全部楼层
本帖最后由 413191246se 于 2022-8-31 07:52 编辑

略。。。。

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-29 18:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
413191246se 发表于 2022-8-29 11:38
* 相见:sylun 老师 的代码,不必新建模块,直接放到标准模块 NewMacros 中最后面即可。
  
* 但 sylun  ...

老师受累了!感谢!
我在“附件”上,测试了一下,排序基本正常,但发现二处有问题,一个是半斤应该排在一斤的后面;另一个是四两排在了一两后面。
我也试着在一个9百多页的文档上,试跑了一下,在60多页的地方,代码就卡住了。
1.png
2.png
3.png

TA的精华主题

TA的得分主题

发表于 2022-8-29 22:31 | 显示全部楼层
4楼程序基本是按楼主1楼截图所编,确实有错漏。这样的文本处理复杂,主要是多重要求,文档格式需要归纳总结,分析逻辑结构,以我目前的分析,认为要求与文本层次结构似有冲突。可试试以下代码,是以另一种思路编写。按楼主附件文档简单测试基本通过。楼主可在此基础上修改,或解释其合理的编辑思路,处理要点,看看能否作进一步修改。
num是模块级数组变量,可在多个相关过程时方便调用,只是需要初始化,原主程序没有对其初始化。
  1. Private num(0 To 99) As String
  2. Sub test2()
  3.     Dim i%, j%, k%, m%, n%, n1%, n2%, r%
  4.     Dim data$, code$, info$(), info1$(), info2$(), data1&(), data2$()
  5.     Dim RegExp As Object
  6.     Dim Match As Object
  7.     Dim RegExp2 As Object
  8.     Dim Match2 As Object
  9.    
  10.     Call NumToCnNum
  11.     data = IIf(Selection.Type = wdSelectionIP, ActiveDocument.Content.Text, Selection.Text)
  12.     code = "斤两钱分厘枚粒片"  '数量单位据此先后排序
  13.     Set RegExp = CreateObject("VBScript.RegExp")
  14.     Set RegExp2 = CreateObject("VBScript.RegExp")
  15.     With RegExp
  16.         .Global = True
  17.         .Pattern = "([用方]:|;)([^。;:]+[十九八七六五四三二一半][斤两钱分厘枚粒片])(。|,[^。;:]+?。)"
  18.         If .test(data) = False Then
  19.             MsgBox "找不到匹配,程序退出!", vbCritical
  20.             Exit Sub
  21.         End If
  22.         
  23.         For Each Match In .Execute(data)  '获取匹配方剂各药材配伍文本相关定位参数
  24.             ReDim Preserve data1(5, m)
  25.             With Match
  26.                 data1(0, m) = .firstindex
  27.                 data1(1, m) = .Length
  28.                 data1(2, m) = data1(0, m) + data1(1, m)
  29.                 data1(3, m) = .firstindex + Len(.submatches(0))
  30.                 data1(4, m) = Len(.submatches(2))
  31.                 data1(5, m) = data1(2, m) - data1(4, m) + 1
  32.             End With
  33.             m = m + 1
  34.         Next
  35.         
  36.         With IIf(Selection.Type = wdSelectionIP, ActiveDocument.Content, Selection.Range)
  37.             For i = 0 To UBound(data1, 2)
  38.                 If Selection.Type = wdSelectionIP Then
  39.                     .SetRange data1(0, i), data1(2, i)
  40.                 Else
  41.                     .SetRange Selection.Start + data1(0, i), Selection.Start + data1(2, i)
  42.                 End If
  43.                 .HighlightColorIndex = wdYellow  '在原文档突出显示匹配文本
  44.             Next
  45.         End With
  46.         
  47.         For n = UBound(data1, 2) To 0 Step -1  '按倒序处理方剂药材配伍文本
  48.             With RegExp2
  49.                 .Global = True
  50.                 For i = 1 To Len(code)
  51.                     .Pattern = "([^、:。]+?([十九八七六五四三二一半]+)" & Mid(code, i, 1) & ")[、。]"
  52.                     ReDim info(Len(code))
  53.                     If .test(Mid(data, data1(3, n), data1(1, n))) = True Then
  54.                         For Each Match2 In .Execute(Mid(data, data1(3, n), data1(1, n)))
  55.                             info(i - 1) = info(i - 1) & Match2.Value
  56.                             ReDim Preserve info1(3, n1)
  57.                             info1(0, n1) = Match2.submatches(0)
  58.                             info1(1, n1) = Match2.submatches(1)
  59.                             info1(2, n1) = Match2.firstindex
  60.                             info1(3, n1) = Match2.firstindex + Match2.Length
  61.                             n1 = n1 + 1
  62.                         Next
  63.                         
  64.                         For k = 99 To 0 Step -1  '对提取的药材以剂量大小进行排序
  65.                             For j = 0 To UBound(info1, 2)
  66.                                 If info1(1, j) = num(k) Then
  67.                                     ReDim Preserve info2(n2)
  68.                                     info2(n2) = info1(0, j)
  69.                                     n2 = n2 + 1
  70.                                 End If
  71.                             Next
  72.                         Next
  73.                         ReDim Preserve data2(r)
  74.                         data2(r) = data2(r) & Join(info2, "、")  '对匹配文本的中药材重新排序后的文本
  75.                         r = r + 1
  76.                         
  77.                         Erase info1
  78.                         Erase info2
  79.                         n1 = 0
  80.                         n2 = 0
  81.                     End If
  82.                 Next
  83.             End With
  84.             
  85.             For i = 1 To Len(code)  '处理判断为相同数量及单位的药材
  86.                 If Join(data2, "") <> Empty Then
  87.                     For j = 0 To UBound(data2)
  88.                         RegExp2.Pattern = "([^、。]+?)各?([十九八七六五四三二一半]+" & Mid(code, i, 1) & ")[、。]([^、。]+?)\2([、。])"
  89.                         If InStr(data2(j), Mid(code, i, 1)) Then
  90.                             Do While RegExp2.test(data2(j)) = True
  91.                                 data2(j) = RegExp2.Replace(data2(j), "$1,$3各$2$4")  '此处与原处理要求有所不同
  92.                             Loop
  93.                         End If
  94.                     Next
  95.                 End If
  96.             Next
  97.             If Join(data2, "") <> Empty Then
  98.                 data = Left(data, data1(3, n)) & "△" & Join(data2, "、") & Mid(data, data1(5, n), data1(4, n)) & "▲" & Mid(data, data1(2, n) + 1)
  99.             End If
  100.             
  101.             Erase info
  102.             Erase data2
  103.             r = 0
  104.         Next
  105.         
  106.         With Documents.Add(ActiveDocument.FullName).Content.Find
  107.             .Parent.Text = data  '将处理结果输出到以原文档为模板的新文档
  108.             .Replacement.Highlight = True
  109.             .Execute "△*▲", MatchWildcards:=True, Replace:=wdReplaceAll
  110.         End With
  111.     End With
  112.     MsgBox "共处理了" & m & "条,处理条目见原文档、结果文本见新文档突出显示部分。"
  113. End Sub

  114. Sub NumToCnNum()
  115.     '生成百位内汉字小写数字
  116.     Const a As String = "一二三四五六七八九"
  117.     Dim i%
  118.    
  119.     For i = 1 To 99
  120.         Select Case i
  121.         Case Is >= 20
  122.             If i Mod 10 > 0 Then
  123.                 num(i) = Mid(a, Int(i / 10), 1) & "十" & Mid(a, i Mod 10, 1)
  124.             Else
  125.                 num(i) = Mid(a, Int(i / 10), 1) & "十"
  126.             End If
  127.         Case Is > 10
  128.             num(i) = "十" & Mid(a, Int(i Mod 10), 1)
  129.         Case Is < 10
  130.             num(i) = Mid(a, i, 1)
  131.         Case Else
  132.             num(i) = "十"
  133.         End Select
  134.     Next
  135.     num(0) = "半"
  136. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-30 06:05 | 显示全部楼层
sylun 发表于 2022-8-29 22:31
4楼程序基本是按楼主1楼截图所编,确实有错漏。这样的文本处理复杂,主要是多重要求,文档格式需要归纳总结 ...

感谢老师辛苦付出!谢射!
真是见鬼了,还是和你的第一个代码一样,运行不了,我在图中红箭头所指的二处,反复试了多次都不成!试了几个其它的代码是正常的,老师这是啥原因?
5.png

TA的精华主题

TA的得分主题

发表于 2022-8-30 10:00 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
相见:你应该将 sylun 老师的代码直接放在 Option Explicit 下面(另起一段),再试试,不要放在模块 1 中了!

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-30 10:28 | 显示全部楼层
413191246se 发表于 2022-8-30 10:00
相见:你应该将 sylun 老师的代码直接放在 Option Explicit 下面(另起一段),再试试,不要放在模块 1 中 ...

水平未到,还是不知道要放那儿,老师能截个图看下否?
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-9-19 09:49 , Processed in 0.042230 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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