1. 别一张张调了:为什么你需要一个Word图片批处理宏
做标书、整理产品手册、汇总项目材料,最烦的事情之一就是文档里的图片乱七八糟。有的大得撑破页面,小得看不清;有的被压缩得变了形;有的边框粗细不一,风格完全不统一。你要是负责过上百页的技术文档排版,肯定能体会那种一张张右键设置图片大小和环绕方式的绝望感。
我当初接一个几十页的投标文件,光图片就有上百张。甲方要求所有截图统一宽度、统一居中、统一带细边框,格式五花八门——有的插的是原始截图,有的复制粘贴进来的,还有的嵌在表格里。手动处理了两页我就放弃了,老老实实打开录制宏,配合VBA把整个文档的图片刷了一遍,十分钟搞定,效果统一得像是用专业排版软件做的。
这里说的宏操作,本质就是利用Word的VBA编程接口,遍历文档中的所有图片对象,然后批量修改它们的宽度、高度、比例、边框、环绕方式、对齐方式等格式属性。相比手工修改,它最大的优势有两个:一是快,几百张图片也是同一段代码瞬间执行完;二是统一,所有图片都会严格按照你预设的规则处理,不存在人工操作时的漏网之鱼和偏差。
这篇文章会一步一步拆解怎么做这件事。从最基础的宏录制,到直接手写VBA代码,再到常见的坑和实际使用技巧,全程用我调试过的真实代码片段做示范。不管你是完全没碰过宏的小白,还是写过一点VBA但又不太熟的老手,按着文章走一遍,应该都能做出属于自己的图片批处理工具。
2. 摸清Word图片的家底:InlineShapes和Shapes到底啥区别
在写代码之前,有一个概念必须搞清楚,否则你的宏要么找不到图片,要么把不该动的对象动了。
Word里的图片对象主要分两类。一类叫InlineShapes(嵌入式图形),另一类叫Shapes(浮动图形)。大部分通过“插入→图片”和复制粘贴放进正文里的图片,属于InlineShapes。你可以理解成它们是跟着文字一起排版走的,像一个大号字符一样嵌在段落里。而Shapes则是浮动在页面上的对象,可以随意拖动位置,一般是从“插入→形状”创建的图形,或者手动设置了非嵌入型环绕方式之后,InlineShape也会转化为浮动状态。
用宏批量处理图片,遍历对象时这两类都要处理。只遍历InlineShapes,浮动图片就漏了;只遍历Shapes,正文里的嵌入式图片反而改不到。
判断一张图片属于哪一类,最直接的办法是点击图片,看光标旁边的布局选项。如果出现“嵌入型”选项并且是激活状态,它就是InlineShape。如果布局选项显示的是“四周型”“浮于文字上方”之类的,那就是浮动Shape。
更准确的方法是看对象类型的枚举值。在VBA里,InlineShape对象的Type属性返回的是WdInlineShapeType枚举,其中wdInlineShapePicture对应值为3,表示这是一张图片。而Shape对象的Type属性里,wdShapeTypePicture对应的值是13。也有一部分图片是以OLE对象或者链接形式存在的,这些一般来说不建议通过尺寸批量处理,因为有可能改变原对象的展示比例或者触发链接更新。
我们这篇主要针对Type为3的InlineShape图片和Type为13的Shape图片来写处理代码。
3. 录制宏和开启开发者模式:正式动手前的基础准备
3.1 开启“开发工具”选项卡
Word默认隐藏了“开发工具”选项卡,录宏和写代码之前得先把它调出来。
鼠标右键点击Word工具栏的空白区域,选择“自定义功能区”。在弹出的窗口右侧主选项卡列表里,勾选“开发工具”,点击确定。这样顶部菜单栏就会出现“开发工具”,里面默认有Visual Basic、宏、录制宏、宏安全性等入口。
我用的是较新版本的Word,不同版本界面略有差异,但大致位置一致。如果你的Word版本比较老,可能在“工具→宏”菜单里直接能找到录制宏的按钮,不一定需要开开发工具选项卡。
3.2 录制一段只包含核心操作的宏
录制宏是学习VBA最快的入门方式。它会把你的鼠标和键盘操作自动转换为VBA代码,虽然录出来的代码往往冗余,但能帮你快速建立起“操作”和“代码”之间的对应关系。
我建议你先录制一段手工修改单张图片的宏,看看Word内部是怎么描述这些操作的。步骤很简单:
点击“录制宏”,在弹出的对话框里给宏起个名字,比如FormatPic,保存位置选择“所有文档(Normal.dotm)”或者当前文档,点击确定。然后手工处理一张图片——选中它,右键点“大小和位置”,在布局设置里把宽度设为8厘米,锁定纵横比,再把环绕方式改成浮于文字上方,最后点击确定。处理完一张之后,停止录制。
打开宏列表,点击刚才录好的宏,再点“编辑”,你就能看到Word自动生成的代码。虽然代码比较啰嗦,但大致能看出每个步骤对应哪些属性。比如LockAspectRatio对应锁定纵横比,Width对应宽度,RelativeHorizontalPosition对应相对位置等等。这就是你后面写批处理代码的语料库。
3.3 设置宏安全性:为什么我的宏一运行就被拦截
即使代码写好了,第一步要解决的往往不是代码本身,而是Word的宏安全策略。默认情况下,带宏的文档会被标记为“宏已被禁用”,点开之后会提示启用内容。
点击“开发工具→宏安全性”,将宏设置调整为“禁用所有宏,并发出通知”,这是比较稳妥的模式。如果你是在本地用自己的电脑处理自己的文档,也可以临时选择“启用所有宏”,但要注意这一点只适合完全可信的环境,不建议长期开着。
还有一类情况是文档是从其他地方复制过来的,里面的宏被整体剥离了。你写好的代码存在Normal模板里,但打开别人的文档时,由于文档来源不受信任,宏依然可能不运行。此时要用“文件→选项→信任中心→受信任位置”,把存放你常用文档的文件夹添加到受信任位置列表里,就能避免每次弹安全提醒。
4. 核心代码逐段拆解:批量统一图片尺寸的完整方案
4.1 遍历文档中的嵌入式图片(InlineShapes)
批量修改的关键在于遍历。先看最常用的InlineShapes遍历代码:
Sub FormatAllInlinePictures() Dim doc As Document Dim pic As InlineShape Dim picCount As Integer Dim i As Integer Set doc = ActiveDocument picCount = doc.InlineShapes.Count If picCount = 0 Then MsgBox "当前文档中没有找到嵌入式图片。" Exit Sub End If For i = picCount To 1 Step -1 Set pic = doc.InlineShapes.Item(i) If pic.Type = wdInlineShapePicture Then ' 在这里写批处理逻辑 End If Next i MsgBox "共处理了 " & picCount & " 张嵌入式图片。" End Sub注意这里用的是倒序循环,从最后一张图片往前遍历。为什么倒序?因为如果你在处理过程中删除了某张图片,正序循环会导致索引错位,容易漏掉图片或者越界报错。倒序则可以安全地删除和处理,不影响尚未遍历到的图片索引。
嵌套在里面的If pic.Type = wdInlineShapePicture判断是必须的。InlineShapes集合里除了图片,还可能是OLE对象、ActiveX控件、甚至某些形状类型的对象,如果不加类型判断,一旦遇到非图片对象,后面的尺寸赋值就容易报错或者产生意外效果。
4.2 遍历文档中的浮动图片(Shapes)
浮动图片的处理逻辑类似,但对象模型不同:
Sub FormatAllFloatingPictures() Dim shp As Shape Dim i As Integer Dim shapeCount As Integer shapeCount = ActiveDocument.Shapes.Count If shapeCount = 0 Then MsgBox "当前文档中没有找到浮动图形。" Exit Sub End If For i = shapeCount To 1 Step -1 Set shp = ActiveDocument.Shapes.Item(i) If shp.Type = msoPicture Then ' 在这里写批处理逻辑 End If Next i MsgBox "共处理了 " & shapeCount & " 张浮动图片。" End Sub这里有个细节要注意。Shapes集合包含的不只是图片,还包括文本框、线条、箭头、流程图等形状。它们都继承自Shape对象,Type属性各不相同。msoPicture这个常量对应的就是纯图片类型,值为13。如果只判断Type = msoPicture,文本框这些对象就不会被误伤。
还有一种情况,图片虽然以Shape形式存在,但Type被识别为Placeholder或者LinkedPicture。比如一些老版本的文档格式转换后,图片可能变成链接图片,Type对应的枚举值就不是msoPicture了。这时候要谨慎处理,最好先查看文档实际的对象类型再决定是否纳入批量范围。
4.3 统一设置图片宽度和高度:你必须要懂的比例
设置图片尺寸,最简单的方式是同时指定Width和Height属性。但问题在于,如果你不知道该图片的原始宽高比,强行设置固定的宽度和高度,图片就会被拉伸变形。这里提供一个稳妥的做法:
Const TARGET_WIDTH As Single = 8 ' 单位:厘米 Const TARGET_HEIGHT As Single = 6 ' 单位:厘米,按需修改 Dim pic As InlineShape Dim ratio As Double With pic If .Width > 0 And .Height > 0 Then ratio = .Width / .Height If ratio > TARGET_WIDTH / TARGET_HEIGHT Then ' 图片较宽,以宽度为基准等比缩放 .Width = TARGET_WIDTH .Height = TARGET_WIDTH / ratio Else ' 图片较高,以高度为基准等比缩放 .Height = TARGET_HEIGHT .Width = TARGET_HEIGHT * ratio End If End If End With这段代码的核心思想是:先判断原始宽高比和目标宽高比的大小关系,然后决定以宽度还是高度为基准,另一纬度按比例计算。这样不管原始图片是横图还是竖图,缩放后都不会变形。
实测下来,在Word里使用Width和Height属性时,默认单位是磅(point)。1厘米约等于28.35磅。如果你习惯用厘米来思考尺寸,建议最好先做一个单位换算,或者直接用Application.InchesToPoints这种内置转换函数,配合1英寸等于2.54厘米的换算关系,就能把厘米准确转成磅。
4.4 绕开尺寸赋值的一个隐藏坑:LockAspectRatio属性
如果你直接把Width和Height都赋了值,部分情况下Word会自动重置LockAspectRatio的状态,导致下一次缩放时按原图原始比例重新计算。为了确保稳定性,在修改尺寸前先锁定纵横比:
Dim pic As InlineShape Set pic = ... ' 拿到具体图片对象 ' 先解锁纵横比,确保Width和Height都能单独赋值 pic.LockAspectRatio = msoFalse pic.Width = Application.CentimetersToPoints(8) pic.Height = Application.CentimetersToPoints(6)Wait,这里需要解释一下。如果你希望保持原图比例不变形,那就不应该同时设置Width和Height,而是通过比例公式计算。但如果你就是为了把所有图片统一成完全一致的大小(哪怕变形也认了),那把LockAspectRatio设为msoFalse之后同时赋值两个属性最省事。
我个人的建议是:除非你明确知道这批图片原始比例都一样,否则尽量不要用强制宽高。文字报告中插入的截图往往比例千差万别,强行统一大小会导致严重变形,观感反而更差。使用等比缩放方案,宽度最多8厘米,高度按比例自适应,既能统一观感,又不会让图片畸形。
4.5 给图片统一加边框:从零基础到精细控制
企业文档里的图片统一加个细边框,不仅美观,而且能突出图片边界,尤其是白底截图。边框操作在VBA里对应的就是LineFormat和Border属性:
Dim pic As InlineShape With pic.Borders .Enable = True ' 开启边框 .OutsideLineStyle = wdLineStyleSingle .OutsideColor = wdColorGray50 ' 颜色可根据需要调整 .OutsideLineWidth = wdLineWidth050pt ' 0.5磅线宽 End With注意,InlineShape对象自带Borders属性,可以直接设置。但如果你处理的是Shape浮动图片,边框设置的路子就变了,要操作Shape.Line对象:
Dim shp As Shape With shp.Line .Visible = msoTrue .ForeColor.RGB = RGB(128, 128, 128) ' 灰色 .Weight = 0.5 ' 线宽,单位磅 .DashStyle = msoLineSolid End With这两套写法很容易搞混。我在刚开始写的时候就犯过错,用Shapes.Line的写法去操作InlineShape,结果点了半天没反应。后来才知道,InlineShape的边框归属于段落边框体系,概念上和Shape自己的线条边框不同,虽然视觉上都是“给图片加了个框”,但是底层实现对象不一样。
4.6 统一图片环绕方式和对齐方式
环绕方式决定了图片与文字的排版关系。批量处理时,如果文档里有混合的环绕方式,会导致布局乱掉。所以一般会统一设置为某一种对齐模式。
浮动图片(Shape)的环绕方式由WrapFormat属性控制:
Dim shp As Shape With shp.WrapFormat .Type = wdWrapSquare ' 四周型环绕 .Side = wdWrapBoth ' 两侧都环绕 .DistanceTop = Application.PointsToCentimeters(0.2) .DistanceBottom = Application.PointsToCentimeters(0.2) End With嵌入式图片(InlineShape)本身就是嵌在文字流里的,不存在环绕方式设置。它更像是文字的字号一样参与排版。如果想让图片居中,不能直接设对齐方式,而是要通过选中图片后设置ParagraphFormat对齐:
Dim pic As InlineShape ' 选中该图片 pic.Range.Select Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter这里有必要做一点说明:在Word中,嵌入型图片被当成段落里的一个字符,段落对齐方式决定了它在行内的水平位置。所以设置嵌入式图片居中的本质,是设置它所在段落的对齐方式为居中。如果图片嵌套在表格单元格里,要对齐方式设置的是单元格内段落的对齐,逻辑一样。
浮动图片的居中则相对麻烦一些。它没有类似段落的对齐属性,你需要先选中它,然后使用Selection对象移动,或者直接设置相对位置:
Dim shp As Shape With shp .Left = (Application.PageSetup.PageWidth - .Width) / 2 .Top = .Top ' 保持原垂直位置不变 End With注意这里计算水平居中用的是页面宽度减去图片自身宽度的差值的一半。如果要考虑页边距,那就应该用“版心宽度”而不是PageWidth。版心宽度等于PageWidth减去左页边距和右页边距。否则图片会居中于整个物理页面,而不是文字区域。
5. 把代码组装成真正能用的批处理工具
5.1 一个合并所有功能的自包含宏
这里给一个完整的、可以直接复制使用的宏示例。它会把当前文档里的所有嵌入式图片和浮动图片统一处理:等比缩放到目标宽度不超过8厘米、添加浅灰色0.5磅边框、设置为四周型环绕,并尽量水平居中于版心。
Sub BatchFormatAllPictures() Dim doc As Document Dim pic As InlineShape Dim shp As Shape Dim i As Integer Dim picCount As Integer Const TARGET_WIDTH_CM As Single = 8 Const TARGET_WIDTH_PTS As Single = 8 * 28.35 Set doc = ActiveDocument ' 处理嵌入式图片 picCount = doc.InlineShapes.Count If picCount > 0 Then For i = picCount To 1 Step -1 Set pic = doc.InlineShapes.Item(i) If pic.Type = wdInlineShapePicture Then Dim ratio As Double ratio = pic.Width / pic.Height ' 等比例缩放 If pic.Width > TARGET_WIDTH_PTS Then pic.LockAspectRatio = msoTrue pic.Width = TARGET_WIDTH_PTS End If ' 添加边框 With pic.Borders .Enable = True .OutsideLineStyle = wdLineStyleSingle .OutsideColor = RGB(180, 180, 180) .OutsideLineWidth = wdLineWidth050pt End With ' 使所在段落居中 pic.Range.Select Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter End If Next i End If ' 处理浮动图片 picCount = doc.Shapes.Count If picCount > 0 Then For i = picCount To 1 Step -1 Set shp = doc.Shapes.Item(i) If shp.Type = msoPicture Then ratio = shp.Width / shp.Height If shp.Width > TARGET_WIDTH_PTS Then shp.LockAspectRatio = msoTrue shp.Width = TARGET_WIDTH_PTS End If ' 浮动图片边框 With shp.Line .Visible = msoTrue .ForeColor.RGB = RGB(180, 180, 180) .Weight = 0.5 .DashStyle = msoLineSolid End With ' 设置四周型环绕 shp.WrapFormat.Type = wdWrapSquare ' 水平居中于版心 Dim contentWidth As Single contentWidth = doc.PageSetup.PageWidth - doc.PageSetup.LeftMargin - doc.PageSetup.RightMargin shp.Left = contentWidth / 2 - shp.Width / 2 End If Next i End If MsgBox "处理完成!" End Sub这段代码用的是8厘米作为目标宽度上限。你实际使用时可以根据文档版心宽度自己调整。另外注意我这里用常量TARGET_WIDTH_PTS做了厘米转磅的换算,8乘以28.35约等于226.8磅。如果页边距左右各3.17厘米,版心宽度就是21 - 6.34 ≈ 14.66厘米,8厘米的图片占版心一半多一点点,视觉上比较协调。
5.2 如何把宏绑定到快速访问工具栏上
每次运行宏都要去“开发工具→宏→运行”,确实麻烦。更顺手的方法是把它加到快速访问工具栏,做一个专属按钮。
点击左上角快速访问工具栏旁的下拉箭头,选择“更多命令”。在“从下列位置选择命令”里选择“宏”,找到BatchFormatAllPictures,点击“添加”,它会出现在右侧列表里。再点击“修改”,选择一个顺眼的图标,名称改成“统一图片格式”,确认保存。
这样你在任何一个文档窗口,只要点一下这个按钮,宏就会自动跑起来。配合之前设置的受信任位置,基本可以做到一键处理,完全不用碰代码窗口。
5.3 批量处理多个文档的思路扩展
宏本身还能做跨文档的处理。如果你想一口气把某个文件夹下所有Word文档的图片都处理一遍,只需在外层套一个文件遍历循环:
Sub BatchFormatAllDocuments() Dim fso As Object Dim folder As Object Dim file As Object Dim doc As Document Dim folderPath As String folderPath = "C:\待处理文档\" ' 根据实际情况修改 Set fso = CreateObject("Scripting.FileSystemObject") Set folder = fso.GetFolder(folderPath) For Each file In folder.Files If Right(file.Name, 5) = ".docx" Then Set doc = Documents.Open(file.Path) BatchFormatAllPictures ' 调用上面的批量处理宏 doc.Save doc.Close End If Next file MsgBox "所有文档处理完成!" End Sub这个方法在批量整理历史归档文档时尤其好用。比如你要给一套旧项目的几十个Word文档统一加上图片边框,手动打开一个个处理得大半天,用这个方案就是几秒钟的事情。
6. 常见报错和坑:这些坑我踩过,你直接绕开
6.1 尺寸单位搞混,图片大得离谱
Word里Width和Height属性的默认单位是磅,不是厘米。很多人录制宏的时候,在对话框里输入的8厘米,录出来的代码却是226.8,但你要是看录出来的代码,有时候因为录制器的优化,它可能直接写8并备注了一个单位转换的隐式操作,导致你自己在写代码时看不清楚。
我实际测试时发现,直接赋值为8,图片显示的大小就是8磅,缩成一个极小的点;赋值为226.8,才是8厘米的效果。建议在代码里统一用Application.CentimetersToPoints函数转换,或者干脆定义常量时就把厘米转成磅,避免出错。
6.2 处理表格里的图片:看似图片,实则可移动对象
文档里嵌在表格单元格中的图片,有两种存在形式。一种是以InlineShape存在,处理方式和正文图片一样。另一种是用户在表格里插入的浮动图片,它在Shapes集合中,通常被锚定在某个单元格附近。这种图片在处理时,水平居中的计算要考虑表格的列宽,单纯按版心宽度计算会导致位置偏到页面外或者不居中的情况。
我的处理方式是:先判断Shape的Anchor是否在表格内,如果在,就跳过水平居中逻辑,只做缩放和边框的处理。因为表格单元格内的对齐,最好通过单元格的段落对齐来实现,不要用绝对坐标去定位,否则表格在不同页面或者不同缩放级别下,位置都可能错乱。
6.3 图片没有填充区域导致边框不可见
有些图片本身是透明背景的PNG或者无边框的图形,你在设置Borders.Enable = True之后,可能看不到边框。这种情况通常是因为图片的Borders类型是混合的,或者图片本身没有定义边框区域。可以先用Borders.Item(wdBorderTop)逐边设置,看看效果。如果仍不可见,换个思路,用Shape.Line来处理。
对于嵌入型图片,也有一个取巧的替代方案:把图片放进一个文本框或者表格单元格里,给容器加边框。但这种做法会改变文档结构,适合美术要求较高的场景,不适合大批量自动化。
6.4 混合文档导致图片类型识别失败
Word文档经过多次格式转换、复制粘贴、从网页直接粘贴图片之后,图片类型可能会变成wdInlineShapeLinkedPicture或者wdInlineShapeWebVideo等非预期类型。这些对象不能简单当普通图片处理。
一个防御性的做法是,在判断Type时,除了wdInlineShapePicture,也把wdInlineShapeLinkedPicture包含进来。链接图片仍然可以设置宽高和环绕方式,只是修改时不影响原文件。如果你发现某张图片Type既不是这两种,那就跳过处理,避免报错。
6.5 宏运行时提示“对象已被删除”或“方法无效”
这种情况最常见的原因是在循环内误删了当前图片,然后又继续访问它的属性。比如你设置了删除不符合条件的图片的逻辑,正序循环里一旦删除,后面的索引就乱了。解决办法就是坚持用倒序循环,且确认删除操作不影响循环变量。
6.6 图片和形状的Shapes.Count不是一回事
有人会把ActiveDocument.Shapes.Count当作图片总数,这其实不对。Shapes集合还包含文本框、自选图形等非图片对象。如果你在报告里写了“共处理了N张图片”之类的信息,应当统计两个集合中Type满足图片类型的数量之和,而不是简单相加Count。否则对外汇报处理数量时会闹笑话。
7. 进阶玩法:让宏只处理选中的图片
有时候你不需要整篇文档都处理,只希望改某几页的内容。可以给宏增加一个判断,只处理用户当前选中的图片。方法也不难,先看Selection.Type是否为wdSelectionInlineShape或者wdSelectionShape,再遍历Selection.InlineShapes或者Selection.Shapes。
需要注意的是,Selection.Shapes只有在选中浮动图片时才返回对象,如果选中多个对象或者未选中,可能返回空集合,需要加好判空逻辑。
这个进阶功能在批量处理部分页面时非常实用。比如你把标书里的技术方案部分图片统一加上标注框,而前面的资质文件图片保持不变,这时用选中处理就比全文处理更灵活。
8. 把宏保存为模板:一劳永逸的方案
辛辛苦苦写好代码,最好把它保存成可复用的模板。推荐的做法是把宏存到Normal模板里,这样每次打开Word任何文档,都能直接运行。但注意Normal模板一旦堆了太多宏,加载会变慢,而且如果遇到宏病毒问题,清理起来也麻烦。
更规范的做法是:新建一个专门的模板文件,比如“图片处理模板.dotm”,把所有宏放在里面。处理文档时,通过“文件→打开”的方式打开这个模板,或者直接双击模板新建一个基于该模板的文档。这样既不影响日常的Normal模板,又能在这个模板环境下方便地运行宏。
如果你的宏要分享给同事用,可以把这个.dotm文件发给对方,让对方放到Word的启动文件夹(STARTUP)里,这样Word每次启动都会自动加载该模板,里面的宏就全局可用了。启动文件夹的位置一般在:
%APPDATA%\Microsoft\Word\STARTUP把.dotm放进去之后重启Word,就能在宏列表中看到这些宏。这个方式在做团队标准化文档处理时很实用,保证大家用同一套批处理逻辑,不会出现你按你的标准、我按我的格式的混乱局面。
9. 我的实操体会和几个小建议
图片批处理宏看起来是一个简单的功能,但用好了能省下大量重复劳动。就我个人处理过的一百多页标书来说,自动化处理前后对比差异是肉眼可见的:处理前是各种尺寸交错的“拼接风”,处理后统一成8厘米宽、细边框、居中的“规范风”,整个文档的档次都不一样了。
几个建议,算是我踩坑后的总结。第一,在跑全文档处理之前,一定要先备份原文件或者另存副本。宏操作有风险,万一某个逻辑写错,全文档图片的位置和大小都会被改乱,撤销有时候都来不及。第二,先在只有一两张图片的小文档上测试,确认效果符合预期之后,再跑真实的大文档。第三,如果文档同时有横版和竖版页面,目标宽度要根据页面实际情况调整,不要一个宽度走天下。
关于更复杂的应用,比如按图片宽高比自动分类、给图片加统一编号、把图片导出重排然后重新插回文档等,也都是可以写在宏里的。但入口都一样,无非是在遍历图片的循环里,针对不同需求写不同的分支逻辑。掌握了这套思路,后面想扩展什么功能都顺理成章。
我自己现在处理Word图片基本不碰手动操作,全部走宏。虽然初次写好这段代码花了一点时间调试,但后面每一次使用都是纯收益。希望你读完这篇文章,也能自己写出来一个趁手的批处理工具,把时间省下来做真正有价值的排版思考。