更改Word文档中的所有链接源 - 范围的错位

R3u*_*3uK 10 excel vba ms-word excel-vba word-vba

我处理此代码以将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
Run Code Online (Sandbox Code Playgroud)

我注意到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
Run Code Online (Sandbox Code Playgroud)

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

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

关于如何更新Word链接的任何其他输入将不胜感激!


正如Andrew Toomey的回答所建议的那样,我使用的是HyperLinks,但在我的每个模板中,该集合都是空的:

在此输入图像描述


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

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
Run Code Online (Sandbox Code Playgroud)

小智 1

我认为使用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
Run Code Online (Sandbox Code Playgroud)

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

'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
Run Code Online (Sandbox Code Playgroud)