【问题标题】:Writing Data from Excel to Word将数据从 Excel 写入 Word
【发布时间】:2015-12-23 19:52:39
【问题描述】:
  • 我想使用 Excel 将“标签名称”存储在 A 列中,并将它们关联的“替换文本”存储在 B 列中。代码运行时,它需要收集每个标签,一次一个(逐行),在整个 Word 文档中搜索这些词,并将它们替换为相应的替换词。
  • 我注意到页眉和页脚中的特殊标签没有被替换。我转向这篇文章 (http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm) 并发现使用一系列范围(或循环浏览文档中所有可用的故事范围)我能够做到这一点。
  • 我按照上面链接中的建议改进了我的代码,只要我的代码嵌入到我的“普通”Word 文件中,它就可以工作,从而使用 Word 中的 VBA 代码对另一个 Word 文档进行操作。但是,我们的目标是在读取 Excel 文件时使用 VBA Excel 来操作替换。
  • 当我将代码移至 Excel 时,我遇到了一个自动化错误,该错误显示为,

“运行时错误'-2147319779 (8002801d)': 未注册自动化错误库。”。

  • 我从查看注册表到使用“Word.Application.12”代替“Word.Application”来寻找答案。

我有一台装有 Microsoft Office 2007 的 Windows 7 64 位机器。我选择了以下库:

  • Excel:

    • Visual Basic 应用程序
    • Microsoft Excel 12.0 对象库
    • OLE 自动化
    • Microsoft Access 12.0 对象库
    • Microsoft Outlook 12.0 对象库
    • Microsoft Word 12.0 对象库
    • Microsoft Forms 2.0 对象库
    • Microsoft Office 14.0 对象库
  • 单词:

    • Visual Basic 应用程序
    • Microsoft Word 12.0 对象库
    • OLE 自动化
    • Microsoft Office 12.0 对象库

我对在 Excel 内部操作 VBA 没有任何问题。通常,我会将一组字符串传递给该函数,但现在,我已将字符串嵌入函数内部,就好像我只打算用另一个预定字符串交换一个字符串(对于任意数量的实例) .

Function Story_Test()
Dim File As String
Dim Tag As String
Dim ReplacementString As String

Dim a As Integer

Dim WordObj As Object
Dim WordDoc As Object
Dim StoryRange As Word.Range
Dim Junk As Long

Dim BaseFile As String

'Normally, these lines would be strings which get passed in
File = "Z:\File.docx"
Tag = "{{Prepared_By}}"
ReplacementString = "Joe Somebody"

'Review currently open documents, and Set WordDoc to the correct one
'Don't worry, I already have error handling in place for the more complex code
Set WordObj = GetObject(, "Word.Application")
BaseFile = Basename(File)
For a = 1 To WordObj.Documents.Count
    If WordObj.Documents(a).Name = BaseFile Then
        Set WordDoc = WordObj.Documents(a)
        Exit For
    End If
Next a

'This is a fix provided to fix the skipped blank Header/Footer problem
Junk = WordDoc.Sections(1).Headers(1).Range.StoryType


'Okay, this is the line where we can see the error.
'When this code is run from Excel VBA, problem.  From Word VBA, no problem.
'Anyone known why this is???
'***********************************************************************
For Each StoryRange In WordObj.Documents(a).StoryRanges
'***********************************************************************
    Do
        'All you need to know about the following function call is
        ' that I have a function that works to replace strings.
        'It works fine provided it has valid strings and a valid StoryRange.
        Call SearchAndReplaceInStory_ForVariants(StoryRange, Tag, _
          ReplacementString, PreAdditive, FinalAdditive)
        Set StoryRange = StoryRange.NextStoryRange
    Loop Until StoryRange Is Nothing
Next StoryRange

Set WordObj = Nothing
Set WordDoc = Nothing

End Function

【问题讨论】:

  • 这个问题再好不过了。一种建议是检查 Word-VBA 项目中的引用,并查看 Excel-VBA 项目中缺少哪些引用
  • 与您的解决方案相关的唯一小问题是,在 VBA Excel 中我有 Microsoft Office 14.0 对象库,而在 VBA Word 中,我有 Microsoft Office 12.0 对象库,如上所述。但是,这似乎不是解决办法。
  • 只是为了确认一下,您的意思是您尝试将 Excel-VBA 中的引用从 Office14 更改为 Office12?
  • 在我的 Word VBA 中,我只有“Microsoft Office 12.0 对象库”选项。在 Excel VBA 中,我只有“Microsoft Office 14.0 对象库”选项。你相信这里可能会有所不同吗?呃......可能与自动化错误有关的一个??
  • 我会说这种可能性是存在的。因为从报错信息来看,很明显是自动化问题。这些 DLL 中的某个地方正试图访问另一个未安装的 DLL。至少,我建议您在安装了完全相同的库的安装上尝试您的代码。不知何故,office14 或 office12 但不是两者都

标签: vba excel runtime-error


【解决方案1】:
For Each StoryRange In WordObj.Documents(a).StoryRanges

应该是

For Each StoryRange In WordDoc.StoryRanges

因为你刚刚在上面的循环中分配了它。

【讨论】:

  • 是的,“a”似乎越界了,不是吗?但我怀疑这是否能解决找到 BaseFile 的问题
  • 至于“a”变量超出范围......“a”将从 1 开始并朝着 word 文档的数量工作。但是,如果没有,更复杂的代码允许使用“GetObject(,”Word.Application“)”在上面几行中实际捕获的错误处理。如果 WordObj.Documents.Count = 0 的事件(出于某种疯狂的原因),则 For 循环将在开始之前结束,从而从一开始就绕过它。在这种情况下,“WordDoc”不会被初始化,但不用担心,更多的错误处理。谢谢!
  • Tim Williams...虽然我明白您为什么会建议进行更改,但在提供的错误方面似乎没有区别。如果您要编写用于替换 word 文档任何位置中的字符串的简单代码,所有这些都是从 Excel VBA 完成的,您会怎么做?也许我没有使用最有效的方式?提前感谢您的宝贵时间!!!
  • 如果在 WordObj.Documents 集合中找不到 BaseFile,@TheKirkwoods a 将超出范围。您需要记住,在这种情况下,a 的值将是 WordObj.Documents.Count + 1。这就是我警告可能越界的原因。但正如我所说,如果找到 BaseFile,则不应发生这种情况。
  • 啊……好吧,是的。这就说得通了。也许我需要将较低的代码移动到 for 循环中,以找到 BaseFile 的条件。谢谢!
【解决方案2】:

现在,我必须得出结论,因为我没有可能进行相反的测试,在一个 VBA 环境中使用 Microsoft Office 12 对象库和在另一个 VBA 环境中使用 Microsoft Office 14 对象库之间存在差异.我也没有改变的手段/授权,所以我必须得出结论,就目前而言,两者之间的差异是罪魁祸首。因此,如果我要继续前进并期待不同的结果,我会假设 Microsoft Office 12 对象库是正确的库,其中 14 有一些我不知道的差异。

感谢所有提供意见的人。如果您有任何其他建议,我们可以讨论和转发。谢谢!

【讨论】:

    【解决方案3】:

    这是为了更新散布在正文和页眉页脚上的一堆链接。 我不是只凭记忆写的,做了很多修复、包含和调整。 它向您展示了如何涵盖所有不同的部分,并且可以轻松修改以在您的参数范围内工作。 完成后请发布您的最终代码。

    Public Sub UpdateAllFields()
    Dim doc As Document
    Dim wnd As Window
    Dim lngMain As Long
    Dim lngSplit As Long
    Dim lngActPane As Long
    Dim rngStory As Range
    Dim TOC As TableOfContents
    Dim TOA As TableOfAuthorities
    Dim TOF As TableOfFigures
    Dim shp As Shape
    Dim sctn As Section
    Dim Hdr As HeaderFooter
    Dim Ftr As HeaderFooter
    
    ' Set Objects
    Set doc = ActiveDocument
    Set wnd = ActiveDocument.ActiveWindow
    
    ' get Active Pane Number
    lngActPane = wnd.ActivePane.Index
    
    ' Hold View Type of Main pane
    lngMain = wnd.Panes(1).View.Type
    
    ' Hold SplitSpecial
    lngSplit = wnd.View.SplitSpecial
    
    ' Get Rid of any split
    wnd.View.SplitSpecial = wdPaneNone
    
    ' Set View to Normal
    wnd.View.Type = wdNormalView
    
    ' Loop through each story in doc to update
    For Each rngStory In doc.StoryRanges
        If rngStory.StoryType = wdCommentsStory Then
            Application.DisplayAlerts = wdAlertsNone
            ' Update fields
            rngStory.Fields.Update
            Application.DisplayAlerts = wdAlertsAll
        Else
            ' Update fields
            rngStory.Fields.Update
        End If
    Next
    
    'Loop through text boxes and update
    For Each shp In doc.Shapes
        With shp.TextFrame
            If .HasText Then
                shp.TextFrame.TextRange.Fields.Update
            End If
        End With
    Next
    
    ' Loop through TOC and update
    For Each TOC In doc.TablesOfContents
        TOC.Update
    Next
    
    ' Loop through TOA and update
    For Each TOA In doc.TablesOfAuthorities
        TOA.Update
    Next
    
    ' Loop through TOF and update
    For Each TOF In doc.TablesOfFigures
        TOF.Update
    Next
    
    For Each sctn In doc.Sections
        For Each Hdr In sctn.Headers
            Hdr.Range.Fields.Update
            For Each shp In Hdr.Shapes
                With shp.TextFrame
                    If .HasText Then
                        shp.TextFrame.TextRange.Fields.Update
                    End If
                End With
            Next shp
        Next Hdr
        For Each Ftr In sctn.Footers
            Ftr.Range.Fields.Update
            For Each shp In Ftr.Shapes
                With shp.TextFrame
                    If .HasText Then
                        shp.TextFrame.TextRange.Fields.Update
                    End If
                End With
            Next shp
        Next Ftr
    Next sctn
    
    ' Return Split to original state
    wnd.View.SplitSpecial = lngSplit
    
    ' Return main pane to original state
    wnd.Panes(1).View.Type = lngMain
    
    ' Active proper pane
    wnd.Panes(lngActPane).Activate
    
    ' Close and release all pointers
    Set wnd = Nothing
    Set doc = Nothing
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多