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)
如果您确实需要使用Fields并InlineShapes尝试此代码。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)