Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 替换方括号+;将内容作为合并字段的内容_Vba_Ms Word - Fatal编程技术网

Vba 替换方括号+;将内容作为合并字段的内容

Vba 替换方括号+;将内容作为合并字段的内容,vba,ms-word,Vba,Ms Word,我试图将方括号中的内容更改为合并字段。我有80个ish文档要处理,有些没有方括号,有些有几个(没有嵌套) 我已经成功地运行了我的代码,它对一些文件起到了作用。其他人(多数)给出了溢出错误。当我检查其中一个文件中发生的情况时,代码正确地提取了内容,它只是将合并字段放在了错误的位置,这反过来会导致它继续查找相同的方括号集 Public Function searchFiles(fFile As Variant, rootFolderStr2 As String, rootFolderStr As S

我试图将方括号中的内容更改为合并字段。我有80个ish文档要处理,有些没有方括号,有些有几个(没有嵌套)

我已经成功地运行了我的代码,它对一些文件起到了作用。其他人(多数)给出了溢出错误。当我检查其中一个文件中发生的情况时,代码正确地提取了内容,它只是将合并字段放在了错误的位置,这反过来会导致它继续查找相同的方括号集

Public Function searchFiles(fFile As Variant, rootFolderStr2 As String, rootFolderStr As String)
    Dim strTemp As String, mfc As String, msg As String
    Dim startStr As Integer, endStr As Integer
    Dim objWord As New Word.Application
    Dim objDoc As Word.Document
    Dim aField As Field, fFolder As String
    Dim rng As Variant, myField As Field, oldField As Variant

    On Error GoTo ErrorHandler

    'open file
    'Open fFile For Input As #1
    Set objDoc = objWord.Documents.Open(fFile)
    objDoc.TrackRevisions = False
    strTemp = objDoc.Range(0, objDoc.Range.End)

    startStr = InStrRev(strTemp, "[")
    endStr = InStrRev(strTemp, "]")

    Do While startStr <> 0
        'Merge field contents
        mfc = Right(Left(strTemp, endStr - 1), endStr - startStr - 1)
        Set rng = objDoc.Range(startStr - 1, endStr)
        Set myField = objDoc.Fields.Add(Range:=rng, Type:=wdFieldMergeField, Text:=mfc)

        strTemp = objDoc.Range(0, objDoc.Range.End)

        'Find next merge field
        startStr = InStrRev(strTemp, "[")
        endStr = InStrRev(strTemp, "]")
        If endStr < startStr And endStr <> -1 Then
            msg = "Error occured in " & fileName & " " & startStr & " " & endStr
            Debug.Print (msg)
            startStr = 0
            endStr = 0
        End If
    Loop
    'put in right folder
    fFolder = Right(objDoc.FullName, Len(objDoc.FullName) - Len(rootFolderStr))

    objDoc.SaveAs fileName:=rootFolderStr2 & "\" & fFolder
    objDoc.Close
    objWord.Quit

ErrorHandler:
If Err.Number <> 0 Then
    Debug.Print ("Error occured in file: " & fileName & " " & Err.Description)
    Exit Function
End If

End Function
公共函数搜索文件(fFile作为变量,rootFolderStr2作为字符串,rootFolderStr作为字符串)
Dim strTemp作为字符串,mfc作为字符串,msg作为字符串
Dim startStr为整数,endStr为整数
Dim objWord作为新词。应用
Dim objDoc作为Word.Document
将远处视为场,将文件夹视为线
Dim rng作为变量,myField作为变量,oldField作为变量
关于错误转到错误处理程序
'打开文件
'打开fFile以输入为#1
设置objDoc=objWord.Documents.Open(fFile)
objDoc.TrackRevisions=False
strTemp=objDoc.Range(0,objDoc.Range.End)
startStr=InStrRev(strTemp,“[”)
endStr=InStrRev(strTemp,“]”)
启动时执行TR 0
'合并字段内容
mfc=右(左(strTemp,endStr-1,endStr-startStr-1)
设置rng=objDoc.Range(startStr-1,endStr)
设置myField=objDoc.Fields.Add(范围:=rng,类型:=wdFieldMergeField,文本:=mfc)
strTemp=objDoc.Range(0,objDoc.Range.End)
'查找下一个合并字段
startStr=InStrRev(strTemp,“[”)
endStr=InStrRev(strTemp,“]”)
如果endStr
我正在努力理解word中的对象是如何工作的,所以请原谅


如果您能回答导致此问题的原因,或能提供更好的解决方法,我们将不胜感激。

好的。一般建议总是,总是,总是把选项显式地作为模块或类的开始。这有助于突出显示代码中与语法滥用和未声明变量等相关的错误。在发布的代码中有一个未声明的变量“Filename”

使用Word时,最好尝试找到一种使用Word对象模型的方法,而不是提取文本

您可以通过使用.MoveStart/EndUntil方法替换instrrev来修改现有代码

我已经更新了您的代码以使用这些移动方法

如果您不了解关键字的作用,请将光标放在关键字上,然后按F1。这将带您进入MS帮助页面。对于Word对象模型,帮助页需要仔细阅读

Option Explicit

' Changed to sub as you are not returning any values
Public Sub searchFiles(fFile As Variant, rootFolderStr2 As String, rootFolderStr As String)

Const FieldOpen                     As String = "["
Const FieldClose                    As String = "]"

    Dim strTemp As String, mfc As String, msg As String

    Dim objWord As New Word.Application
    Dim objDoc As Word.Document
    ' Dim aField As FieldDim
    Dim fFolder As String
    ' Dim rng As Variant
    ' Dim myField As Field
    ' Dim oldField As Variant

    ' Not previously declared
    Dim Filename As String


    Dim SearchRng                   As Word.Range
    Dim FieldRng                    As Word.Range
    Dim Moved                       As Long
    'open file
    'Open fFile For Input As #1
    On Error GoTo ErrorHandler
    Set objDoc = objWord.Documents.Open(fFile)
    objDoc.TrackRevisions = False

    'strTemp = objDoc.Range(0, objDoc.Range.End)
    Set SearchRng = ActiveDocument.Content

    'startStr = InStrRev(strTemp, "[")
    Moved = SearchRng.MoveStartUntil(cset:=FieldOpen)

    'Do While startStr <> 0
    Do Until Moved = 0
        'Merge field contents
        'mfc = Right(Left(strTemp, endStr - 1), endStr - startStr - 1)
        FieldRng.Start = SearchRng.Start + 1

        'endStr = InStrRev(strTemp, "]")
        ' exit if we don't find a closing field marker
        ' The side effect (which we want) is that the end is also moved
        If SearchRng.MoveEndUntil(cset:=FieldClose) = 0 Then GoTo ErrorHandler
        FieldRng.End = SearchRng.End + 1

        ' reduce the FieldRng to just the text
        FieldRng.Characters.First.Delete
        FieldRng.Characters.Last.Delete

        'Set rng = objDoc.Range(startStr - 1, endStr
        'Set myField = objDoc.Fields.Add(Range:=rng, Type:=wdFieldMergeField, Text:=mfc)
        objDoc.Fields.Add Range:=FieldRng, Type:=wdFieldMergeField, Text:=FieldRng.Text

        'strTemp = objDoc.Range(0, objDoc.Range.End)
        ' We now need to move the start of the search range to after the mergefield
        SearchRng.Start = FieldRng.End + 1

        'Find next merge field
        'startStr = InStrRev(strTemp, "[")
        'endStr = InStrRev(strTemp, "]")
        Moved = SearchRng.MoveStartUntil(cset:=FieldOpen)
'        If endStr < startStr And endStr <> -1 Then
'            msg = "Error occured in " & Filename & " " & startStr & " " & endStr
'            Debug.Print (msg)
'            startStr = 0
'            endStr = 0
'        End If
    Loop
    'put in right folder
    fFolder = Right(objDoc.FullName, Len(objDoc.FullName) - Len(rootFolderStr))

    objDoc.SaveAs Filename:=rootFolderStr2 & "\" & fFolder
    objDoc.Close
    objWord.Quit

ErrorHandler:
If Err.Number <> 0 Then
    Debug.Print ("Error occured in file: " & Filename & " " & Err.Description)
    Exit Sub
End If

End Sub
选项显式
'更改为sub,因为您不返回任何值
公共子搜索文件(fFile作为变量,rootFolderStr2作为字符串,rootFolderStr作为字符串)
Const FieldOpen As String=“[”
Const FieldClose As String=“]”
Dim strTemp作为字符串,mfc作为字符串,msg作为字符串
Dim objWord作为新词。应用
Dim objDoc作为Word.Document
“像田野一样暗淡
作为字符串的Dim-fFolder
“Dim rng作为变体
“将myField设置为字段”
“Dim oldField作为变体
"未经事先声明,
将文件名设置为字符串
暗淡的搜索范围为Word.Range
Dim FieldRng作为字范围
迪姆动了很久
'打开文件
'打开fFile以输入为#1
关于错误转到错误处理程序
设置objDoc=objWord.Documents.Open(fFile)
objDoc.TrackRevisions=False
'strTemp=objDoc.Range(0,objDoc.Range.End)
设置SearchRng=ActiveDocument.Content
'startStr=InStrRev(strTemp,“[”)
Moved=SearchRng.MoveStartUntil(cset:=FieldOpen)
'在启动时执行TR 0
直到移动=0为止
'合并字段内容
'mfc=右(左(strTemp,endStr-1,endStr-startStr-1)
FieldRng.Start=SearchRng.Start+1
'endStr=InStrRev(strTemp,“]”)
'如果找不到结束字段标记,则退出
"副作用(我们希望如此)是末端也会移动
如果SearchRng.moveEndTill(cset:=FieldClose)=0,则转到ErrorHandler
FieldRng.End=SearchRng.End+1
'将FieldRng简化为文本
FieldRng.Characters.First.Delete
FieldRng.Characters.Last.Delete
'设置rng=objDoc.Range(startStr-1,endStr
'设置myField=objDoc.Fields.Add(范围:=rng,类型:=wdFieldMergeField,文本:=mfc)
objDoc.Fields.Add范围:=FieldRng,类型:=wdFieldMergeField,文本:=FieldRng.Text
'strTemp=objDoc.Range(0,objDoc.Range.End)
'我们现在需要将搜索范围的开始移动到合并字段之后
SearchRng.Start=FieldRng.End+1
'查找下一个合并字段
'startStr=InStrRev(strTemp,“[”)
'endStr=InStrRev(strTemp,“]”)
Moved=SearchRng.MoveStartUntil(cset:=FieldOpen)
'如果endStrSub UpdateDocuments()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String, strDocNm As String, wdDoc As Document
strDocNm = ActiveDocument.FullName
strFolder = GetFolder
If strFolder = "" Then Exit Sub
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
  If strFolder & "\" & strFile <> strDocNm Then
    Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
      Call MakeFields(wdDoc)
      wdDoc.Close SaveChanges:=True
  End If
  strFile = Dir()
Wend
Set wdDoc = Nothing
Application.ScreenUpdating = True
End Sub

Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function

Sub MakeFields(wdDoc As Document)
With wdDoc.Range
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Forward = True
    .Format = False
    .Wrap = wdFindStop
    .MatchWildcards = True
    .Text = "\[*\]"
    .Execute
  End With
  Do While .Find.Found
    .Characters.First.Text = vbNullString
    .Characters.Last.Text = vbNullString
    .Fields.Add Range:=.Duplicate, Type:=wdFieldEmpty, Text:="MERGEFIELD " & .Text, Preserveformatting:=False
    .Collapse wdCollapseEnd
    .Find.Execute
  Loop
End With
End Sub