【问题标题】:Change all links' sources in a Word document - Misplacement of Ranges更改 Word 文档中所有链接的来源 - 范围错位
【发布时间】:2017-02-16 21:31:54
【问题描述】:

我处理此代码以将 Word 模板中所有链接字段/图表/...的来源更改为启动它的工作簿。

我有常用字段图表(存储在InlineShapes),所以每个模板都有2个循环。


这些循环有时会卡在For Each 上,并在Fields/InlineShapes 上不停地循环(甚至不增加索引...)。 (我为此添加了DoEvents,它似乎减少了这种情况发生的频率......如果您有解释,将非常受欢迎!

而使用For i = ... to .Count,现在它几乎可以完美运行,除了Pasted Excel Range 被更改为相同大小的范围,每次都从A1 开始,并且在工作簿


为避免InlineShapes 出现问题,我添加了一个测试以了解LinkFormat.SourceFullName 是否可访问,从而避免出现可能导致进程停止的错误:

Function GetSourceInfo(oShp As InlineShape) As Boolean
Dim test As Variant
    On Error GoTo Error_GetSourceInfo
    test = oShp.LinkFormat.SourceFullName
    GetSourceInfo = True
    Exit Function
Error_GetSourceInfo:
   GetSourceInfo = False
End Function

我在我的模板中注意到了两种类型的链接InlineShapes

图表

粘贴为 Microsoft Office Graphic Object.hasChart = -1 .Type = 12 .LinkFormat.Type = 8

范围

粘贴为 Picture (Windows Metafile).hasChart = 0 .Type = 2 .LinkFormat.Type = 0

这是我的 InlineShapes 循环:

For i = 1 To isCt
    If Not GetSourceInfo(oDoc.InlineShapes(i)) Then GoTo nextshape
        oDoc.InlineShapes(i).LinkFormat.SourceFullName = NewLink
        DoEvents
nextshape:
Next i

问题

由于我只更新了仅描述路径和文件的 .SourceFullName,因此我不知道为什么或如何影响最初选择的范围...

问题回顾:Pasted Excel Range 更改为相同大小的范围,每次从A1 开始,并在工作簿的活动工作表上

对于如何更新 Word 链接的任何其他意见,我们将不胜感激!


正如 Andrew Toomey 的回答中所建议的,我使用超链接,但在我的每个模板中,集合都是空的:


我尝试了很多不同的组合,这是我清理的:

Sub change_Templ_Args()

Dim oW As Word.Application, _
    oDoc As Word.Document, _
    aField As Field, _
    fCt As Integer, _
    isCt As Integer, _
    NewLink As String, _
    NewFile As String, _
    BasePath As String, _
    aSh As Word.Shape, _
    aIs As Word.InlineShape, _
    TotalType As String

On Error Resume Next
Set oW = GetObject(, "Word.Application")
If Err.Number <> 0 Then Set oW = CreateObject("Word.Application")
On Error GoTo 0
oW.Visible = True

NewLink = ThisWorkbook.Path & "\" & ThisWorkbook.Name

BasePath = ThisWorkbook.Path & "\_Templates\"
NewFile = Dir(BasePath & "*.docx")

Do While NewFile <> vbNullString
    Set oDoc = oW.Documents.Open(BasePath & NewFile)
    fCt = oDoc.Fields.Count
    isCt = oDoc.InlineShapes.Count
    MsgBox NewFile & Chr(13) & "Fields : " & oDoc.Fields.Count & Chr(13) & "Inline Shapes : " & isCt

    For i = 1 to fCt 
        With oDoc.Fields(i)
            '.LinkFormat.AutoUpdate = False
            'DoEvents
            .LinkFormat.SourceFullName = NewLink
            '.Code.Text = Replace(.Code.Text, Replace(.LinkFormat.SourceFullName, "\", "\\"), Replace(NewLink, "\", "\\"))
        End With
    Next i

    For i = 1 To isCt
        If Not GetSourceInfo(oDoc.InlineShapes(i)) Then GoTo nextshape
            With oDoc.InlineShapes(i)
                .LinkFormat.SourceFullName = NewLink
                DoEvents
                'MsgBox .LinkFormat.SourceFullName & Chr(13) & Chr(13) & _
                        "Type | LF : " & .LinkFormat.Type & Chr(13) & _
                        "Type | IS : " & .Type & Chr(13) & _
                        "hasChart : " & .HasChart & Chr(13) & Chr(13) & _
                        Round((i / isCt) * 100, 0) & " %" 
            End With
nextshape:
    Next i

    MsgBox oDoc.Name & " is now linked with this workbook!"
    oDoc.Save
    oDoc.Close
    NewFile = Dir()
Loop
oW.Quit

Set oW = Nothing
Set oDoc = Nothing

MsgBox "All changes done.", vbInformation + vbOKOnly, "End proc"

End Sub

【问题讨论】:

  • 您是从 excel 中运行此程序,您希望所有文档都来自该工作簿?然后打开文档,查找链接对象并将引用替换为您从中调用宏的 WB?
  • @Raystafarian :正是这个!
  • 我已经测试过更新链接范围,它对我来说很好。重要的是不要更改 for-each-next 循环内的对象,而是仅使用 for-next 循环。我唯一经历的是NewLink中的Excel工作表必须有一个与新工作表名称相对应的工作表名称。
  • @dee :谢谢输入,我不知道为什么这个范围问题没有重现...:/我会立即为For Each 进行更改,实际上我忘记了指定它必须是相同的文件结构才能更新链接。 (我在不同的计算机上工作,路径总是在变化,这就是我需要这个的原因)
  • 你有我可以玩的示例文件吗?这将节省我重新创建这些的时间,这样maybe (not promising you that)我将能够为您提供直接的解决方案。如果是,那么您可以通过 Dropbox 共享它。如果数据敏感,您可能还想用虚拟数据替换原始数据。

标签: vba excel ms-word


【解决方案1】:

可能并非所有字段/形状都已链接,并且字段/形状的原始插入导致并非在对象上创建所有属性。

要推进您的代码并更详细地了解对象的问题,请尝试忽略并报告错误。使用手表检查对象。

例如:

On Error Goto fieldError
For Each aField In oDoc.Fields
    With aField
        .LinkFormat.AutoUpdate = False
        DoEvents
        .LinkFormat.SourceFullName = NewLink
        .Code.Text = Replace(.Code.Text, Replace(.LinkFormat.SourceFullName, "\", "\\"), Replace(NewLink, "\", "\\"))
        Goto fieldContinue
      fieldError:
        MsgBox "error: <your info to report / breakpoint on this line>"
      fieldContinue:
    End With
Next aField

P.s.:DoEvents 的目的是什么?这将处理外部事件(Windows 消息)。

【讨论】:

  • 感谢输入。 DoEvents 是一种避免陷入循环的尝试,它现在工作了 90% 的时间......虽然不知道为什么......对于错误处理,我尝试了一些我自己的和规范与手表我的元素(字段没关系,是InlineShapes 让我发疯了),我要编辑问题,因为我找到了部分解决方案。
【解决方案2】:

我认为使用hyperlinks 集合是解决问题的关键——除非你有特定的理由不这样做。从 Word 文档到 Excel 工作簿的链接是外部链接,因此都应列在 Hyperlinks 集合中(无论它们是文本链接还是链接的 InlineShapes)。

这是我的代码,可能会有所帮助。为简单起见,我对 Word 文档进行了硬编码,因为这对您来说不是问题:

Sub change_Templ_Args()
    WbkFullname = ActiveWorkbook.FullName

    'Alternatively...
    'WbkFullname = "C:\temp\myworkbook.xlsx"
    'Application.Workbooks.Open Filename:=WbkFullname

    'Get Document filename string
    MyWordDoc = "C\Temp\mysample.docx"

    Set oW = CreateObject("Word.Application")
    oW.Documents.Open Filename:=MyWordDoc 
    Set oDoc = oW.ActiveDocument

    'Reset Hyperlinks
    For Each HypLnk In oDoc.Hyperlinks
        HypLnk.Address = WbkFullname
    Next

End Sub

如果你真的需要使用FieldsInlineShapes,试试这个代码。我在 For 循环中使用了变体,并为目录或交叉引用字段的字段添加了对 wdLinkTypeReference 的检查 - 这些链接在文档内部。

'Reset links to InlineShapes
For Each InShp In ActiveDocument.InlineShapes
    If Not InShp.LinkFormat Is Nothing Then
        InShp.LinkFormat.SourceFullName = WbkFullname
    End If
    If InShp.Hyperlink.Address <> "" Then
        InShp.LinkFormat.SourceFullName = WbkFullname
    End If
Next

'Reset links to fields
For Each Fld In ActiveDocument.Fields
    If Not Fld.LinkFormat Is Nothing Then
        If Fld.LinkFormat.Type <> wdLinkTypeReference Then 
            Fld.LinkFormat.SourceFullName = WbkFullname
        End If
    End If
Next

【讨论】:

  • 感谢您的见解,但超链接的集合在我的模板中是空的,虽然其他不是...我希望这是我错过的东西,但不是。关于另一部分,我不断收到 error 5825 Object has been deleted on InShp.Hyperlink.Addresserror 6083 Objects in this document contain links to files that cannot be found. The linked information will not be updated. on Fld.LinkFormat.SourceFullName = WbkFullname
猜你喜欢
  • 1970-01-01
  • 2013-10-02
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多