vba根据内容调整word表格_VBA 实践(1)——通过word vba 辅助修改大量pdf数据

5b9551a235e54c3918ef5849d5f7fbbb.png

VBA 实践(1)——通过word vba 辅助修改大量pdf数据

项目说明:

有约1000页pdf的文件的数据需要修改。Pdf含文字层,可通过acrobat pro等编辑功能修改。

修改要求为:将所有数据放大1.6倍,并替换原数据,字体字号位置等应该尽量保持与原来一致。要求修改的数据分布在每个页面的右侧,行数列数不定,除了要修改的部分外,其他地方需要保持原样。数据有的是整数、有的含一位小数,有的含两位小数,修改后的数据要求保留一样的小数位数。数据如下图所示,红框内是要求修改的数据。

ee91fb92952ea2b150c290559ff79bdf.png

项目方案:

Pdf格式是一种便携式支持跨平台的,着重于保持版面效果的格式,不是一种便于修改的格式,它的文字编辑功能较弱,更没有提供数学运算的功能。它的修改是基于板块的,而不是文字。

在pdf文件里一个一个地修改,耗时会非常长,且容易出错。不但计算容易出错,而且格式位置也容易出错,且难以调整。

根据自身能力及情况,制定这样的方案。

第一步,把pdf文件中的需要修改的数据提取出来,放到word中,其他不需要修改的地方不动。

第二步,在word中对数据进行修改,并调整格式,导出为pdf文件

第三步,以页为单位,对原pdf的数据进行手工替换。


第一步:如何快速地提取需要修改的数据?

Pdf是含有文字层的,可以直接导出为.docx、.xls等文档。可以尝试利用acrobat pro直接导出为.docx,但是只能全部导出,不能选择部分数据导出。导出效果如下图所示。

这是使用acrobat pro 9转换出来的word文档,总体效果较差,出现了较多的分栏符、分节符、制表符等标志符,文档结构复杂难改。①处本来是有图像的,但丢失了;②处是有表格线及灰色相间的条纹的,但也丢失了,而且数据不是用表格来组织的。

这样的文档需要修改成符合要求的文档,工作量是非常大的,主要的困难体现在两方面:一需要补充丢失的图像、表格线,重新排版;二需要排除其他内容的干扰,才能准确地对数据进行更改。

如果转换为excel文档,更改数据方面会方便一点,但排版方面会更麻烦。直接转换的方法困难重重。

9f476da9e9b5f305ac715ec44469d8ff.png

还有另一个方法——使用Abbyy finereader进行识别转换。

Abbyy finereader可以对pdf文档进行识别,最重要的是通过布置识别区域可以只对页面的某部分进行识别,避免引入其他需要保持原样的部分。识别并导出的word文档数据如下图所示。

因为需要更改的区域在页面中的位置是固定的,所以识别区域可以进行批量设置,大大提高了效率。数字识别正确率非常高,几乎是100%。数据是以表格的形式组织的,这非常有利于后续的数据自动化更改。表格的宽度与每列的宽度与原pdf是一致的,减少了后面格式排版的工作量。

到现在,已经可以快速地提取需要的数据了。接下来就是批量更改数据,并进行排版。

95e52a61d5cab0e3d83758683106607a.png

第二步:修改数据,调整格式,生成pdf

批量修改数据,当然是使用vba写个小程序方便啦。

在修改数据方面,显然在excel里面修改会更为方便,但是排版格式并不好调整。想到vba在word和excel里面都是可以使用的,而word是擅长排版的,所以在word里面处理数据可以兼具批量更改数据和格式排版的便利。

批量更改数据的vba代码如下:

Sub 放大数据并修改格式()
Dim c, x, ws
Dim mystr As String

Const fangd1 = 1.6 '声明一个常量
x = 0

Application.ScreenUpdating = False '关闭屏幕刷新

'外循环体(每一个表格循环)

For Each ws In ActiveDocument.Tables
'内循环体(表格内每一个单元格循环)

    For Each c In ws.Range.Cells
        mystr = Left(c.Range.Text, Len(c.Range.Text) - 2)   '去除单元格的隐含字符
        '数值形式的判断,首先判断两位小数,然后判断一位小数,剩下的为整数。
        If mystr Like "*.##" Then
            c.Range.Text = Format(Round(Val(mystr) * fangd1, 2), "#0.00")
        ElseIf mystr Like "*.#" Then
            c.Range.Text = Format(Round(Val(mystr) * fangd1, 2), "#0.0")
        ElseIf mystr <> "" Then
            c.Range.Text = Round(Val(mystr) * fangd1, 0)
        ElseIf mystr = "" Then
             c.Range.Text = "-"
        End If

    Next c
    x = x + 1
Next ws
Application.ScreenUpdating = True '开启屏幕刷新

MsgBox "共修改了" & x & "个表"

End Sub

代码在编写的过程中,遇到了判断条件不起作用的问题。在判断时直接使用了c.Range.Text Like "*.##"进行判断,而没有注意到word表格中每个单元格末尾其实都有两个隐含的字符,导致判断条件不起作用。后来得到了知友TuskAi的帮助,顺利地解决了问题。他还提示我使用Format函数对数据形式进行限定,以防止末尾小数0被忽略,而使小数位数不对。在此对他表示感谢!

还有,如果Format函数的参数写为"#.00"时,那么小于的1的小数个位数上的0会被忽略,比如0.12会变成.12。所以参数要写成"#0.00"。

调整数据格式

调整数据格式也可以使用vba代码。首先需要到原pdf中获取相关参数,比如字体、字号、行高等。格式修改的代码都可以通过录制宏的方式得到,Vba代码如下。

    ws.Select
'修改字体格式
    With Selection.Font
        .NameFarEast = ""
        .NameAscii = "U001Con"
        .NameOther = "U001Con"
        .Name = ""
        .Size = 9
    End With
'修改段落格式
    With Selection.ParagraphFormat
        .LeftIndent = CentimetersToPoints(0)
        .RightIndent = CentimetersToPoints(0)
        .SpaceBefore = 0
        .SpaceBeforeAuto = False
        .SpaceAfter = 0
        .SpaceAfterAuto = False
        .LineSpacingRule = wdLineSpaceSingle
        .Alignment = wdAlignParagraphCenter
        .FirstLineIndent = CentimetersToPoints(0)
        .OutlineLevel = wdOutlineLevelBodyText
        .CharacterUnitLeftIndent = 0
        .CharacterUnitRightIndent = 0
        .CharacterUnitFirstLineIndent = 0
        .LineUnitBefore = 0
        .LineUnitAfter = 0
        .WordWrap = True
    End With
'修改表格格式
    Selection.Rows.HeightRule = wdRowHeightExactly
    Selection.Rows.Height = CentimetersToPoints(0.454)
    Selection.Cells.VerticalAlignment = wdCellAlignVerticalCenter
    Selection.Shading.Texture = wdTextureNone
    Selection.Shading.ForegroundPatternColor = wdColorAutomatic
    Selection.Shading.BackgroundPatternColor = wdColorAutomatic
 '均布列
    Selection.Cells.DistributeWidth

    '边框修改
        Selection.Borders(wdBorderTop).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderBottom).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderRight).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderHorizontal).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderVertical).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderDiagonalDown).LineStyle = wdLineStyleNone
        Selection.Borders(wdBorderDiagonalUp).LineStyle = wdLineStyleNone
    With Options
        .DefaultBorderLineStyle = wdLineStyleSingle
        .DefaultBorderLineWidth = wdLineWidth050pt
        .DefaultBorderColor = wdColorAutomatic
    End With
Next ws

数据处理完后,导出pdf。效果如下图所示。字体、字号、列宽、行高都可以和原pdf文档吻合。

e6aecefc069eae5c3b44203c665ba8e3.png

第三步,以页为单位,对原pdf的数据进行手工替换。

接下来的任务就是把转换出来的修改好的数据替换原pdf中的数据。没有找到高效替换的方法,只能以页为单位,手工复制粘贴,然后调整位置,过程如下图所示。

这一步是机械重复的、非常耗时的。

不知道有没有什么方法可以提高这一过程的效率。

a92eca47b7201f80889c7efe2aa2fe46.png

将近1000页的pdf文档,最终用时7天完成修改。时间很大一部分花在了第三步。如果没有第二步使用vba代码提高效率,恐怕时间还要翻倍,甚至更长。

学好vba还是很有用的!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值