Arrays 查找PowerPoint演示文稿中的单词列表(包括表格),并将其替换为VBA

Arrays 查找PowerPoint演示文稿中的单词列表(包括表格),并将其替换为VBA,arrays,vba,replace,powerpoint,Arrays,Vba,Replace,Powerpoint,我已经试着解决这个问题好几天了,尽管谷歌搜索了很多次,但我还是被卡住了,所以如果有任何建议,我都会非常感激:) 因此,我试图用另一个单词替换一个单词列表(我的文件是用于几个项目的模板)。它在文本框中工作正常,但在表格中不起作用,因此我尝试将文本框代码调整到表格中。下面的代码运行时没有给我错误消息,但仍然没有编辑我的表 Sub Multi_FindReplace() 'PURPOSE: Find & Replace a list of text/values throughout ent

我已经试着解决这个问题好几天了,尽管谷歌搜索了很多次,但我还是被卡住了,所以如果有任何建议,我都会非常感激:)

因此,我试图用另一个单词替换一个单词列表(我的文件是用于几个项目的模板)。它在文本框中工作正常,但在表格中不起作用,因此我尝试将文本框代码调整到表格中。下面的代码运行时没有给我错误消息,但仍然没有编辑我的表

Sub Multi_FindReplace()

'PURPOSE: Find & Replace a list of text/values throughout entire PowerPoint presentation

Dim sld As Slide
Dim shp As Shape
Dim ShpTxt As TextRange
Dim TmpTxt As TextRange
Dim FindList As Variant
Dim ReplaceList As Variant
Dim x As Long
Dim i As Long
Dim j As Long
Dim tbl As Table


' INSERT THE LIST OF MERGE FIELDS HERE
FindList = Array("word1", "word2", "word3")

' INSERT THE LIST OF VARIABLES TO BE INSERTED BY HERE  
ReplaceList = Array("word1.1", "word2.1", "word3.1")


'Loop through each slide in Presentation
  For Each sld In ActivePresentation.Slides

    For Each shp In sld.Shapes

        '''''for tables
        If shp.HasTable Then

                'give name to table
                Set tbl = shp.Table

                'loops on table rows and columns
                For i = 1 To shp.Table.Rows.Count
                    For j = 1 To shp.Table.Columns.Count

                        'Store cell text into a variable
                        ShpTxt = tbl.Cell(i, j).Shape.TextFrame.TextRange


                          'Ensure There is Text To Search Through
                          If ShpTxt <> "" Then
                             For x = LBound(FindList) To UBound(FindList)

                             'Store text into a variable
                            'Set ShpTxt = shp.TextFrame.TextRange

                             'Find First Instance of "Find" word (if exists)
                             Set TmpTxt = ShpTxt.Replace( _
                              FindWhat:=FindList(x), _
                              Replacewhat:=ReplaceList(x), _
                              WholeWords:=False)

                             'Find Any Additional instances of "Find" word (if exists)
                              Do While Not TmpTxt Is Nothing
                                Set ShpTxt = ShpTxt.Characters(TmpTxt.Start + TmpTxt.Length, ShpTxt.Length)
                                Set TmpTxt = ShpTxt.Replace( _
                                  FindWhat:=FindList(x), _
                                  Replacewhat:=ReplaceList(x), _
                                  WholeWords:=False)
                              Loop
                             Next x
                          End If


                     Next j
                Next i
        Else


        ''''for all shapes excluding tables
        If shp.HasTextFrame Then

           'Store shape text into a variable
           Set ShpTxt = shp.TextFrame.TextRange

            'Ensure There is Text To Search Through
             If ShpTxt <> "" Then
                For x = LBound(FindList) To UBound(FindList)

                'Store text into a variable
                'Set ShpTxt = shp.TextFrame.TextRange

                'Find First Instance of "Find" word (if exists)
                Set TmpTxt = ShpTxt.Replace( _
                  FindWhat:=FindList(x), _
                  Replacewhat:=ReplaceList(x), _
                  WholeWords:=False)

                'Find Any Additional instances of "Find" word (if exists)
                Do While Not TmpTxt Is Nothing
                  Set ShpTxt = ShpTxt.Characters(TmpTxt.Start + TmpTxt.Length, ShpTxt.Length)
                  Set TmpTxt = ShpTxt.Replace( _
                    FindWhat:=FindList(x), _
                    Replacewhat:=ReplaceList(x), _
                    WholeWords:=False)
                Loop
               Next x
            End If

        End If

        End If

    Next shp

Next sld


End Sub
Sub Multi_FindReplace()
'目的:查找并替换整个PowerPoint演示文稿中的文本/值列表
将sld变暗为幻灯片
将shp变暗为形状
将文本设置为文本范围
将TmpTxt设置为文本范围
Dim FindList作为变体
Dim ReplaceList作为变体
暗x等长
我想我会坚持多久
Dim j尽可能长
如表所示的尺寸tbl
'在此处插入合并字段列表
FindList=数组(“word1”、“word2”、“word3”)
'在此插入要插入的变量列表
替换列表=数组(“word1.1”、“word2.1”、“word3.1”)
'在演示文稿中循环浏览每张幻灯片
对于ActivePresentation.Slides中的每个sld
对于sld形状中的每个shp
桌子用的
如果shp.HasTable,则
'为表命名
设置tbl=shp.表格
'表行和列上的循环
对于i=1到shp.Table.Rows.Count
对于j=1到shp.Table.Columns.Count
'将单元格文本存储到变量中
ShpTxt=tbl.Cell(i,j).Shape.TextFrame.TextRange
'确保有要搜索的文本
如果是“TXT”,则
对于x=LBound(FindList)到UBound(FindList)
'将文本存储到变量中
'设置SHPXTXT=shp.TextFrame.TextRange
'查找“查找”单词的第一个实例(如果存在)
设置TmpTxt=ShpTxt.Replace(_
FindWhat:=FindList(x)_
Replacewhat:=ReplaceList(x)_
WholeWords:=假)
'查找“查找”单词的任何其他实例(如果存在)
不做就做TmpTxt什么都不是
设置ShpTxt=ShpTxt.Characters(TmpTxt.Start+TmpTxt.Length,ShpTxt.Length)
设置TmpTxt=ShpTxt.Replace(_
FindWhat:=FindList(x)_
Replacewhat:=ReplaceList(x)_
WholeWords:=假)
环
下一个x
如果结束
下一个j
接下来我
其他的
适用于除桌子以外的所有形状
如果是shp.HasTextFrame,则
'将形状文本存储到变量中
设置SHPCTXT=shp.TextFrame.TextRange
'确保有要搜索的文本
如果是“TXT”,则
对于x=LBound(FindList)到UBound(FindList)
'将文本存储到变量中
'设置SHPXTXT=shp.TextFrame.TextRange
'查找“查找”单词的第一个实例(如果存在)
设置TmpTxt=ShpTxt.Replace(_
FindWhat:=FindList(x)_
Replacewhat:=ReplaceList(x)_
WholeWords:=假)
'查找“查找”单词的任何其他实例(如果存在)
不做就做TmpTxt什么都不是
设置ShpTxt=ShpTxt.Characters(TmpTxt.Start+TmpTxt.Length,ShpTxt.Length)
设置TmpTxt=ShpTxt.Replace(_
FindWhat:=FindList(x)_
Replacewhat:=ReplaceList(x)_
WholeWords:=假)
环
下一个x
如果结束
如果结束
如果结束
下一个小水电
下一个sld
端接头

为了提高代码的可读性和可维护性,我对您的代码进行了一些重构

由于所有内容都在一个子
中,因此理解其中的所有内容可能会比较困难,特别是当
If
语句的不同部分中有大量代码时。因此,你的主要日常活动最终会是这样:

Option Explicit

Sub Multi_FindReplace()
    'PURPOSE: Find & Replace a list of text/values throughout entire PowerPoint presentation

    ' INSERT THE LIST OF MERGE FIELDS HERE
    Dim FindList As Variant
    FindList = Array("word1", "word2", "word3")

    ' INSERT THE LIST OF VARIABLES TO BE INSERTED BY HERE
    Dim ReplaceList As Variant
    ReplaceList = Array("word1.1", "word2.1", "word3.1")

    'Loop through each slide in Presentation
    Dim sld As Slide
    For Each sld In ActivePresentation.Slides
        Dim shp As Shape
        For Each shp In sld.Shapes
            '''''for tables
            If shp.HasTable Then
                ReplaceWordsInTable shp, FindList, ReplaceList

            ElseIf shp.HasTextFrame Then
                ReplaceWordsInTextFrame shp, FindList, ReplaceList
            Else
                '--- doing nothing for all other shapes (at this time)
            End If
        Next shp
    Next sld
End Sub
现在更容易理解,而且非常清楚的是,处理
文本框
与处理
表格
不同。此外,该组织将顶级例程简化为基本设置和初始化,然后是高级逻辑流

接下来,查看两个“ReplaceWords”子例程:

Private Sub ReplaceWordsInTable(ByRef shp As Shape, _
                                ByRef FindList As Variant, _
                                ByRef ReplaceList As Variant)
    'give name to table
    Dim tbl As Table
    Set tbl = shp.Table

    'loops on table rows and columns
    Dim i As Long
    Dim j As Long
    Dim ShpTxt As TextRange
    Dim TmpTxt As TextRange
    For i = 1 To shp.Table.Rows.Count
        For j = 1 To shp.Table.Columns.Count
            'Store cell text into a variable
            Set ShpTxt = tbl.Cell(i, j).Shape.TextFrame.TextRange
            If ShpTxt <> "" Then
                ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
            End If
        Next j
    Next i
End Sub

Private Sub ReplaceWordsInTextFrame(ByRef shp As Shape, _
                                    ByRef FindList As Variant, _
                                    ByRef ReplaceList As Variant)
    'Store shape text into a variable
    Dim ShpTxt As TextRange
    Set ShpTxt = shp.TextFrame.TextRange
    If ShpTxt <> "" Then
        ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
    End If
End Sub
您会注意到循环被简化为一个
Replace
语句(因此您不必执行查找第一个单词然后重试逻辑)。此外,我在测试中发现,如果
FindList
上的一个单词被定位并以大写字母开头,那么替换操作会将其保留为小写单词。因此,我实现了一个
Find
语句,这样我们就可以捕获第一个字母的大小写,并在替换后重新设置第一个字母

以下是整个模块是一个单独的模块:

Option Explicit

Sub Multi_FindReplace()
    'PURPOSE: Find & Replace a list of text/values throughout entire PowerPoint presentation

    ' INSERT THE LIST OF MERGE FIELDS HERE
    Dim FindList As Variant
    FindList = Array("word1", "word2", "word3")

    ' INSERT THE LIST OF VARIABLES TO BE INSERTED BY HERE
    Dim ReplaceList As Variant
    ReplaceList = Array("word1.1", "word2.1", "word3.1")

    'Loop through each slide in Presentation
    Dim sld As Slide
    For Each sld In ActivePresentation.Slides
        Dim shp As Shape
        For Each shp In sld.Shapes
            '''''for tables
            If shp.HasTable Then
                ReplaceWordsInTable shp, FindList, ReplaceList

            ElseIf shp.HasTextFrame Then
                ReplaceWordsInTextFrame shp, FindList, ReplaceList
            Else
                '--- doing nothing for all other shapes (at this time)
            End If
        Next shp
    Next sld
End Sub

Private Sub ReplaceWordsInTable(ByRef shp As Shape, _
                                ByRef FindList As Variant, _
                                ByRef ReplaceList As Variant)
    'give name to table
    Dim tbl As Table
    Set tbl = shp.Table

    'loops on table rows and columns
    Dim i As Long
    Dim j As Long
    Dim ShpTxt As TextRange
    Dim TmpTxt As TextRange
    For i = 1 To shp.Table.Rows.Count
        For j = 1 To shp.Table.Columns.Count
            'Store cell text into a variable
            Set ShpTxt = tbl.Cell(i, j).Shape.TextFrame.TextRange
            If ShpTxt <> "" Then
                ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
            End If
        Next j
    Next i
End Sub

Private Sub ReplaceWordsInTextFrame(ByRef shp As Shape, _
                                    ByRef FindList As Variant, _
                                    ByRef ReplaceList As Variant)
    'Store shape text into a variable
    Dim ShpTxt As TextRange
    Set ShpTxt = shp.TextFrame.TextRange
    If ShpTxt <> "" Then
        ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
    End If
End Sub

Private Sub ReplaceWordsInTextRange(ByRef thisRange As TextRange, _
                                    ByRef FindList As Variant, _
                                    ByRef ReplaceList As Variant)
    Dim TmpTxt As TextRange
    Dim foundWord As TextRange
    Dim x As Long
    Dim nextCharPosition As Long
    Dim finished As Boolean
    nextCharPosition = 0
    For x = LBound(FindList) To UBound(FindList)
        finished = False
        Do While Not finished
            '--- find the word first, and capture the case of the starting character
            Set foundWord = thisRange.Find(FindWhat:=FindList(x), After:=nextCharPosition, _
                                           MatchCase:=msoFalse, _
                                           WholeWords:=msoFalse)
            If Not foundWord Is Nothing Then
                Dim firstCharUpper As Boolean
                firstCharUpper = (foundWord.Characters(0, 1) = UCase(foundWord.Characters(0, 1)))
                Set TmpTxt = thisRange.Replace(FindWhat:=FindList(x), _
                                               Replacewhat:=ReplaceList(x), _
                                               MatchCase:=msoFalse, _
                                               WholeWords:=msoFalse)
                nextCharPosition = TmpTxt.Start + Len(ReplaceList(x))
                If firstCharUpper Then
                    thisRange.Characters(TmpTxt.Start, 1) = UCase(thisRange.Characters(TmpTxt.Start, 1))
                End If
            Else
                finished = True
            End If
        Loop
    Next x
End Sub
选项显式
子Multi_FindReplace()
'目的:查找并替换整个PowerPoint演示文稿中的文本/值列表
'在此处插入合并字段列表
Dim FindList作为变体
FindList=数组(“word1”、“word2”、“word3”)
'在此插入要插入的变量列表
Dim ReplaceList作为变体
替换列表=数组(“word1.1”、“word2.1”、“word3.1”)
'在演示文稿中循环浏览每张幻灯片
将sld变暗为幻灯片
对于ActivePresentation.Slides中的每个sld
将shp变暗为形状
对于sld形状中的每个shp
桌子用的
如果shp.HasTable,则
replaceWordsTable shp、FindList、ReplaceList
Option Explicit

Sub Multi_FindReplace()
    'PURPOSE: Find & Replace a list of text/values throughout entire PowerPoint presentation

    ' INSERT THE LIST OF MERGE FIELDS HERE
    Dim FindList As Variant
    FindList = Array("word1", "word2", "word3")

    ' INSERT THE LIST OF VARIABLES TO BE INSERTED BY HERE
    Dim ReplaceList As Variant
    ReplaceList = Array("word1.1", "word2.1", "word3.1")

    'Loop through each slide in Presentation
    Dim sld As Slide
    For Each sld In ActivePresentation.Slides
        Dim shp As Shape
        For Each shp In sld.Shapes
            '''''for tables
            If shp.HasTable Then
                ReplaceWordsInTable shp, FindList, ReplaceList

            ElseIf shp.HasTextFrame Then
                ReplaceWordsInTextFrame shp, FindList, ReplaceList
            Else
                '--- doing nothing for all other shapes (at this time)
            End If
        Next shp
    Next sld
End Sub

Private Sub ReplaceWordsInTable(ByRef shp As Shape, _
                                ByRef FindList As Variant, _
                                ByRef ReplaceList As Variant)
    'give name to table
    Dim tbl As Table
    Set tbl = shp.Table

    'loops on table rows and columns
    Dim i As Long
    Dim j As Long
    Dim ShpTxt As TextRange
    Dim TmpTxt As TextRange
    For i = 1 To shp.Table.Rows.Count
        For j = 1 To shp.Table.Columns.Count
            'Store cell text into a variable
            Set ShpTxt = tbl.Cell(i, j).Shape.TextFrame.TextRange
            If ShpTxt <> "" Then
                ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
            End If
        Next j
    Next i
End Sub

Private Sub ReplaceWordsInTextFrame(ByRef shp As Shape, _
                                    ByRef FindList As Variant, _
                                    ByRef ReplaceList As Variant)
    'Store shape text into a variable
    Dim ShpTxt As TextRange
    Set ShpTxt = shp.TextFrame.TextRange
    If ShpTxt <> "" Then
        ReplaceWordsInTextRange ShpTxt, FindList, ReplaceList
    End If
End Sub

Private Sub ReplaceWordsInTextRange(ByRef thisRange As TextRange, _
                                    ByRef FindList As Variant, _
                                    ByRef ReplaceList As Variant)
    Dim TmpTxt As TextRange
    Dim foundWord As TextRange
    Dim x As Long
    Dim nextCharPosition As Long
    Dim finished As Boolean
    nextCharPosition = 0
    For x = LBound(FindList) To UBound(FindList)
        finished = False
        Do While Not finished
            '--- find the word first, and capture the case of the starting character
            Set foundWord = thisRange.Find(FindWhat:=FindList(x), After:=nextCharPosition, _
                                           MatchCase:=msoFalse, _
                                           WholeWords:=msoFalse)
            If Not foundWord Is Nothing Then
                Dim firstCharUpper As Boolean
                firstCharUpper = (foundWord.Characters(0, 1) = UCase(foundWord.Characters(0, 1)))
                Set TmpTxt = thisRange.Replace(FindWhat:=FindList(x), _
                                               Replacewhat:=ReplaceList(x), _
                                               MatchCase:=msoFalse, _
                                               WholeWords:=msoFalse)
                nextCharPosition = TmpTxt.Start + Len(ReplaceList(x))
                If firstCharUpper Then
                    thisRange.Characters(TmpTxt.Start, 1) = UCase(thisRange.Characters(TmpTxt.Start, 1))
                End If
            Else
                finished = True
            End If
        Loop
    Next x
End Sub