【发布时间】: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 共享它。如果数据敏感,您可能还想用虚拟数据替换原始数据。