ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 分享一个最近写的批量自动编号宏,还有两个小问题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-3-26 12:33 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yliuchuyang 于 2022-3-26 12:43 编辑

最近写了一个自动编号的宏,思路是参考的一个公众号的文章:Word—不用域,查找替换将不连续文本编号变为自动编号
照着这个思路把VBA写出来了,但原文中的一个问题没有解决:
目的:
把所有的“(一)(二)(三)..”这样的序号用通配符找到,然后设置自动编号,但是由于正文中也有引用“(一)(二)”  因此正文中的序号不能匹配,只能查找段首的序号。

思路:
直接用[^13]([一二三四五六七八九十]@ 利用换行符来定位段首的序号
可是有一个问题1,如果这个序号上面是一个表格,比如这样
image.png
利用换行符就匹配不到了,可能是表格后面的换行符和普通的换行符不一样,我在论坛也找了word64例的通配符讲解,没有看到类似的情况

因此只能绕一个弯,先匹配所有前面没有换行符的序号[!^13]([一二三四五六七八九十]@)
然后加几个字符做标记比如|||
然后再匹配没有标记的序号即段首的序号([一二三四五六七八九十]@)[!|||],完成自动编号,最后再把标记去掉。

这样做会带来一个问题2
如果序号不是(一)这样的样式而是“1、 2、 3、”这样的样式
在我匹配[!^13][0-9]@、时,即先把非段首的序号标记这一步
如果段首的序号超过了2位,比如11、  12、   那么其中的1、  2、也就是个位数开始也符合这个规则,因为他们的前面还有十位数,而并不是换行符
因此这种方法不能处理没有括号包围的序号

如果能解决问题1,那么问题2也不存在了
不知道我说清楚了没有,代码和附件都上传了,麻烦大神也帮我看下出下主意。
感谢各位~

  1. Sub 自动编号_中文括号数字()
  2.     Dim r As Range, p As Range, tpf, NF, NS, LI, FI
  3.     '================================================== 配置区
  4.     tpf = "([一二三四五六七八九十]@)"  '通配符
  5.     NF = "(%1)"   '编号格式,%1为编号本身,不能动,只需要编辑%1旁边的格式,比如'(一)'为'(%1)' 或者 '1、'为 '%1、' 或者 '第一章'为'第%1章'
  6.     NS = wdListNumberStyleSimpChinNum3  '编号的样式:wdListNumberStyleArabic阿拉伯数字    wdListNumberStyleSimpChinNum3中文数字
  7.     LI = CentimetersToPoints(0)    '左缩进
  8.     FI = CentimetersToPoints(0.74)   '首行缩进
  9.     '================================================== 配置区
  10.     Application.ScreenUpdating = False
  11.     If Selection.Type = wdSelectionIP Then
  12.         MsgBox "请选择范围!"
  13.         Exit Sub
  14.     Else
  15.         Set r = Selection.Range
  16.         Set p = Selection.Range
  17.     End If
  18.    
  19.     With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1)  '设置编号格式
  20.         .NumberFormat = NF
  21.         .TrailingCharacter = wdTrailingNone
  22.         .NumberStyle = NS
  23.         .NumberPosition = 0
  24.         .Alignment = wdListLevelAlignLeft
  25.         .TextPosition = 0
  26.         .TabPosition = wdUndefined
  27.         .ResetOnHigher = 0
  28.         .StartAt = 1
  29.         .LinkedStyle = ""
  30.     End With
  31.     ListGalleries(wdNumberGallery).ListTemplates(1).Name = ""
  32.    
  33.     With r.Find                                   '标识后面的注释引用
  34.         .Text = "[!^13]" & tpf
  35.         .Replacement.Text = "^&|||"
  36.         .MatchWildcards = True
  37.         .Execute Replace:=wdReplaceAll
  38.     End With
  39.    
  40.     With r.Find                                 '查找非注释引用部分并自动编号
  41.         .ClearFormatting
  42.         .Text = tpf & "[!|||]"
  43.         .Forward = True
  44.         .MatchWildcards = True
  45.         Do While .Execute
  46.             With .Parent
  47.                 If .End > p.End Then Exit Do
  48.                 .ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
  49.                     ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
  50.                     True, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
  51.                     wdWord10ListBehavior
  52.                
  53.                 With .ParagraphFormat
  54.                     .SpaceBeforeAuto = False
  55.                     .SpaceAfterAuto = False
  56.                     .LeftIndent = LI
  57.                     .FirstLineIndent = FI
  58.                 End With
  59.                 .Start = .End
  60.             End With
  61.         Loop
  62.     End With
  63.    
  64.     With p.Find                                       '替换本来存在的序号
  65.         .Text = tpf & "([!|||])"
  66.         .Replacement.Text = "\1"
  67.         .MatchWildcards = True
  68.         .Execute Replace:=wdReplaceAll
  69.     End With
  70.    
  71.     With p.Find                                       '替换注释标识
  72.         .Text = "|||"
  73.         .Replacement.Text = ""
  74.         .MatchWildcards = True
  75.         .Execute Replace:=wdReplaceAll
  76.     End With
  77.     Application.ScreenUpdating = True
  78.     MsgBox "完成"
  79. End Sub

  80. Sub 自动编号_阿拉伯数字无括号()
  81.     Dim r As Range, p As Range, tpf, NF, NS, LI, FI
  82.     '================================================== 配置区
  83.     tpf = "[123456789]@、"  '通配符
  84.     NF = "%1、"   '编号格式,%1为编号本身,不能动,只需要编辑%1旁边的格式,比如'(一)'为'(%1)' 或者 '1、'为 '%1、' 或者 '第一章'为'第%1章'
  85.     NS = wdListNumberStyleArabic  '编号的样式:wdListNumberStyleArabic阿拉伯数字    wdListNumberStyleSimpChinNum3中文数字
  86.     LI = CentimetersToPoints(0)    '左缩进
  87.     FI = CentimetersToPoints(0.74)   '首行缩进
  88.     '================================================== 配置区
  89.     Application.ScreenUpdating = False
  90.     If Selection.Type = wdSelectionIP Then
  91.         MsgBox "请选择范围!"
  92.         Exit Sub
  93.     Else
  94.         Set r = Selection.Range
  95.         Set p = Selection.Range
  96.     End If
  97.    
  98.     With ListGalleries(wdNumberGallery).ListTemplates(1).ListLevels(1)  '设置编号格式
  99.         .NumberFormat = NF
  100.         .TrailingCharacter = wdTrailingNone
  101.         .NumberStyle = NS
  102.         .NumberPosition = 0
  103.         .Alignment = wdListLevelAlignLeft
  104.         .TextPosition = 0
  105.         .TabPosition = wdUndefined
  106.         .ResetOnHigher = 0
  107.         .StartAt = 1
  108.         .LinkedStyle = ""
  109.     End With
  110.     ListGalleries(wdNumberGallery).ListTemplates(1).Name = ""
  111.    
  112.     With r.Find                                   '标识后面的注释引用
  113.         .Text = "[!^13]" & tpf
  114.         .Replacement.Text = "^&|||"
  115.         .MatchWildcards = True
  116.         .Execute Replace:=wdReplaceAll
  117.     End With
  118.    
  119.     With r.Find                                 '查找非注释引用部分并自动编号
  120.         .ClearFormatting
  121.         .Text = tpf & "[!|||]"
  122.         .Forward = True
  123.         .MatchWildcards = True
  124.         Do While .Execute
  125.             With .Parent
  126.                 If .End > p.End Then Exit Do
  127.                 .ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
  128.                     ListGalleries(wdNumberGallery).ListTemplates(1), ContinuePreviousList:= _
  129.                     True, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:= _
  130.                     wdWord10ListBehavior
  131.                
  132.                 With .ParagraphFormat
  133.                     .SpaceBeforeAuto = False
  134.                     .SpaceAfterAuto = False
  135.                     .LeftIndent = LI
  136.                     .FirstLineIndent = FI
  137.                 End With
  138.                 .Start = .End
  139.             End With
  140.         Loop
  141.     End With
  142.    
  143.     With p.Find                                       '替换本来存在的序号
  144.         .Text = tpf & "([!|||])"
  145.         .Replacement.Text = "\1"
  146.         .MatchWildcards = True
  147.         .Execute Replace:=wdReplaceAll
  148.     End With
  149.    
  150.     With p.Find                                       '替换注释标识
  151.         .Text = "|||"
  152.         .Replacement.Text = ""
  153.         .MatchWildcards = True
  154.         .Execute Replace:=wdReplaceAll
  155.     End With
  156.     Application.ScreenUpdating = True
  157.     MsgBox "完成"
  158. End Sub
复制代码









附件及代码.zip

30.27 KB, 下载次数: 23

TA的精华主题

TA的得分主题

发表于 2022-3-26 18:44 来自手机 | 显示全部楼层
很简单,直接查找[一二三四五六七八九十]@,此时会连同段落中间的也一并包含进去,然后使用asc(前面的一个字符)是否等于13就可以了。

TA的精华主题

TA的得分主题

发表于 2022-3-26 18:56 来自手机 | 显示全部楼层
本帖最后由 wdpfox 于 2022-3-27 23:12 编辑

解决问题               

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-3-26 20:36 | 显示全部楼层
zhanglei1371 发表于 2022-3-26 18:44
很简单,直接查找[一二三四五六七八九十]@,此时会连同段落中间的也一并包含进去,然后使用asc(前面的一个 ...

老师您好,前面的一个字符用vba怎么表示呢,我先find.Execute之后 匹配的内容还会有前面的换行符吗?

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-3-26 20:44 | 显示全部楼层
yliuchuyang 发表于 2022-3-26 20:36
老师您好,前面的一个字符用vba怎么表示呢,我先find.Execute之后 匹配的内容还会有前面的换行符吗?

我明白了,获取位置后再-1吧应该是

TA的精华主题

TA的得分主题

发表于 2022-3-26 21:01 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
yliuchuyang 发表于 2022-3-26 20:44
我明白了,获取位置后再-1吧应该是

是的,很简单。

TA的精华主题

TA的得分主题

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

解决了,非常感谢老师!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-29 19:55 , Processed in 0.038388 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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