当使用“.paste”方法将数据从 MS Excel 中的单元格粘贴到 MS Word table 中的单元格时,为什么 VBA 退出调试模式?
Why does VBA come out of debug mode when ".paste" method is used to paste data from cell in MS Excel to a cell in a MS Word table?
下面的代码用于从 excel 列的单元格中按顺序复制字符串 (i=3 到 61),找到目录文件夹包含相同 .doc 文件的多个副本,并将每个字符串粘贴到 second 行,第一个 table 的 first 列每个 .doc 文件。
问题:程序无意地继续循环并在第一次执行以下行后完成 运行 其余代码:
wddoc.Tables(1).Cell(2, 1).Range.Paste
即使我使用 F8 进入每一行代码以到达这行代码,也会发生这种情况。代码完成 运行 而没有将任何内容粘贴到目录中的其余文件中。 (excel 文档第 3 行中的字符串已成功粘贴到 计划模板中 - 复制 (10).docx 但剩余的字符串未粘贴到其余文件中)
代码:
Option Explicit
Sub CopyExcelToWord(path As String)
'variables----------------------------------------------------------------
'Decare Object variables for the Word application and file or documentl
Dim wdapp As Object, wddoc As Object, i As Integer
'Declare a String variable for the directory root and current file in that directory
Dim currentPath As String
'main process----------------------------------------------------------
'error handling is extremely important in making Excel work with Word
On Error Resume Next
'GetObject needs two parameters. The first is optional
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'we create a new instance of MS Word
Set wdapp = CreateObject("Word.Application")
End If
'Our application is made visible
wdapp.Visible = True
currentPath = Dir(path, vbDirectory)
For i = 3 To 61
Do Until currentPath = vbNullString
Debug.Print currentPath
If Left(currentPath, 1) <> "." And Left(currentPath, 1) <> "" Then
Debug.Print path & currentPath
Sheet1.Range(Cells(i, 2), Cells(i, 2)).Copy
'we activate our MS Word instance
wdapp.Activate
Set wddoc = wdapp.Documents(path & currentPath)
If wddoc Is Nothing Then Set wddoc = wdapp.Documents.Open(path & currentPath)
wddoc.Activate
wddoc.Tables(1).Cell(2, 1).Range.Paste
'Free alocated memory and close
wdapp.Quit
Set wddoc = Nothing
Set wdapp = Nothing
'The following line of code removes the cell selection in Excel
Application.CutCopyMode = False
currentPath = Dir()
Else
currentPath = Dir()
End If
Loop
Next
End Sub
打印(我已经放置了一个 '...' 我省略了路径的一部分):
.
.
..
.
plan template - Copy (10).docx
L
C:**...**\ plan template - Copy (10).docx
程序无意中运行了其余代码。 excel 文档第 3 行中的字符串已成功粘贴到 计划模板中 - 复制 (10).docx,但其余部分字符串未粘贴到其余文件中)
plan template Copy (11).docx
L
C:*...**\plan template - Copy (11).docx
Lesson plan template - Copy (12).docx
L
C:*...\plan template -Copy (12).docx
plan template - Copy (13).docx
L
C:**...\ plan template -
L
...
C:*...**\plan template - Copy (9).docx
Lesson plan template.docx
L
C:*...**\plan template.docx
我不确定解决这个问题是否能解决您的问题,但您已经
wddoc.Tables(1).Cell(2, 1).Range.Paste
'Free alocated memory and close
wdapp.Quit
Set wddoc = Nothing
Set wdapp = Nothing
完成后 wdapp.Quit,您将不再拥有 wdapp,因此在“For i”循环的下一次迭代中,什么都不会起作用。
但是如果你想保存你的 wddoc,你不能依赖 Set wddoc = Nothing
来做到这一点。您需要执行明确的关闭或保存并关闭
例如
wddoc.Tables(1).Cell(2, 1).Range.Paste
wddoc.Close -1 ' SaveChanges:=Word.wdSaveOptions.wdSaveChanges
' Only do this outside your "For i =" loop
'Free alocated memory and close
'wdapp.Quit
Set wddoc = Nothing
' Only do this outside your "For i =" loop
' Set wdapp = Nothing
你的'issue'与粘贴命令无关
您的代码将所有错误设置为忽略,创建一个 Word 应用程序对象,然后进入一个循环,其中:
- 一个单元格值被复制
- 一个Word文档被打开
- 剪贴板的内容被粘贴到 Word 文档中的一个 table 单元格中
- Word 已关闭且应用程序对象已销毁
循环的第一次迭代将 运行 成功,但后续迭代将在涉及 Word 的每一行出错,因为对象不再存在。由于 On Error Resume Next
.
,这些错误被忽略
您需要做的事情:
- 获取Word对象后重置错误处理
- 如果 Word 未打开则添加一个标记,以便在操作完成后关闭它
- 在循环内完成后关闭文档并保存更改
- 将
wdapp.quit
移到循环外
由于 Word 会保留剪贴板历史记录,而您只是复制单个单元格的值,因此我会避免为此使用复制粘贴。而是直接将值写入 table 单元格。
这就是我编写代码的方式:
Option Explicit
Sub CopyExcelToWord(path As String)
'variables----------------------------------------------------------------
'Decare Object variables for the Word application and file or document
Dim wdapp As Object, wddoc As Object, i As Integer
'Declare a String variable for the directory root and current file in that directory
Dim currentPath As String
'declare flag to show if Word needs to be quit
Dim quitWord As Boolean
'main process----------------------------------------------------------
'error handling is extremely important in making Excel work with Word
On Error Resume Next
'GetObject needs two parameters. The first is optional
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'we create a new instance of MS Word
Set wdapp = CreateObject("Word.Application")
'as Word wasn't already open make application visible
wdapp.Visible = True
'set flag to show Word needs to be shut down
quitWord = True
End If
'reset error handling so that any subsequent errors aren't ignored
On Error GoTo 0
currentPath = Dir(path, vbDirectory)
For i = 3 To 61
Do Until currentPath = vbNullString
Debug.Print currentPath
If Left(currentPath, 1) <> "." And Left(currentPath, 1) <> "" Then
Debug.Print path & currentPath
Set wddoc = wdapp.Documents.Open(path & currentPath)
wddoc.Tables(1).Cell(2, 1).Range.Text = Sheet1.Range(Cells(i, 2), Cells(i, 2)).Value
'document no longer required so close and save changes
wddoc.Close -1 ' SaveChanges:=Word.wdSaveOptions.wdSaveChanges
Set wddoc = Nothing
currentPath = Dir()
Else
currentPath = Dir()
End If
Loop
Next
'Now that operations involving Word are complete quit Word if necessary and destroy objects
If quitWord Then wdapp.Quit
Set wdapp = Nothing
End Sub
下面的代码用于从 excel 列的单元格中按顺序复制字符串 (i=3 到 61),找到目录文件夹包含相同 .doc 文件的多个副本,并将每个字符串粘贴到 second 行,第一个 table 的 first 列每个 .doc 文件。
问题:程序无意地继续循环并在第一次执行以下行后完成 运行 其余代码:
wddoc.Tables(1).Cell(2, 1).Range.Paste
即使我使用 F8 进入每一行代码以到达这行代码,也会发生这种情况。代码完成 运行 而没有将任何内容粘贴到目录中的其余文件中。 (excel 文档第 3 行中的字符串已成功粘贴到 计划模板中 - 复制 (10).docx 但剩余的字符串未粘贴到其余文件中)
代码:
Option Explicit
Sub CopyExcelToWord(path As String)
'variables----------------------------------------------------------------
'Decare Object variables for the Word application and file or documentl
Dim wdapp As Object, wddoc As Object, i As Integer
'Declare a String variable for the directory root and current file in that directory
Dim currentPath As String
'main process----------------------------------------------------------
'error handling is extremely important in making Excel work with Word
On Error Resume Next
'GetObject needs two parameters. The first is optional
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'we create a new instance of MS Word
Set wdapp = CreateObject("Word.Application")
End If
'Our application is made visible
wdapp.Visible = True
currentPath = Dir(path, vbDirectory)
For i = 3 To 61
Do Until currentPath = vbNullString
Debug.Print currentPath
If Left(currentPath, 1) <> "." And Left(currentPath, 1) <> "" Then
Debug.Print path & currentPath
Sheet1.Range(Cells(i, 2), Cells(i, 2)).Copy
'we activate our MS Word instance
wdapp.Activate
Set wddoc = wdapp.Documents(path & currentPath)
If wddoc Is Nothing Then Set wddoc = wdapp.Documents.Open(path & currentPath)
wddoc.Activate
wddoc.Tables(1).Cell(2, 1).Range.Paste
'Free alocated memory and close
wdapp.Quit
Set wddoc = Nothing
Set wdapp = Nothing
'The following line of code removes the cell selection in Excel
Application.CutCopyMode = False
currentPath = Dir()
Else
currentPath = Dir()
End If
Loop
Next
End Sub
打印(我已经放置了一个 '...' 我省略了路径的一部分):
. . .. . plan template - Copy (10).docx L C:**...**\ plan template - Copy (10).docx
程序无意中运行了其余代码。 excel 文档第 3 行中的字符串已成功粘贴到 计划模板中 - 复制 (10).docx,但其余部分字符串未粘贴到其余文件中)
plan template Copy (11).docx L C:*...**\plan template - Copy (11).docx Lesson plan template - Copy (12).docx L C:*...\plan template -Copy (12).docx plan template - Copy (13).docx L C:**...\ plan template - L ... C:*...**\plan template - Copy (9).docx Lesson plan template.docx L C:*...**\plan template.docx
我不确定解决这个问题是否能解决您的问题,但您已经
wddoc.Tables(1).Cell(2, 1).Range.Paste
'Free alocated memory and close
wdapp.Quit
Set wddoc = Nothing
Set wdapp = Nothing
完成后 wdapp.Quit,您将不再拥有 wdapp,因此在“For i”循环的下一次迭代中,什么都不会起作用。
但是如果你想保存你的 wddoc,你不能依赖 Set wddoc = Nothing
来做到这一点。您需要执行明确的关闭或保存并关闭
例如
wddoc.Tables(1).Cell(2, 1).Range.Paste
wddoc.Close -1 ' SaveChanges:=Word.wdSaveOptions.wdSaveChanges
' Only do this outside your "For i =" loop
'Free alocated memory and close
'wdapp.Quit
Set wddoc = Nothing
' Only do this outside your "For i =" loop
' Set wdapp = Nothing
你的'issue'与粘贴命令无关
您的代码将所有错误设置为忽略,创建一个 Word 应用程序对象,然后进入一个循环,其中:
- 一个单元格值被复制
- 一个Word文档被打开
- 剪贴板的内容被粘贴到 Word 文档中的一个 table 单元格中
- Word 已关闭且应用程序对象已销毁
循环的第一次迭代将 运行 成功,但后续迭代将在涉及 Word 的每一行出错,因为对象不再存在。由于 On Error Resume Next
.
您需要做的事情:
- 获取Word对象后重置错误处理
- 如果 Word 未打开则添加一个标记,以便在操作完成后关闭它
- 在循环内完成后关闭文档并保存更改
- 将
wdapp.quit
移到循环外
由于 Word 会保留剪贴板历史记录,而您只是复制单个单元格的值,因此我会避免为此使用复制粘贴。而是直接将值写入 table 单元格。
这就是我编写代码的方式:
Option Explicit
Sub CopyExcelToWord(path As String)
'variables----------------------------------------------------------------
'Decare Object variables for the Word application and file or document
Dim wdapp As Object, wddoc As Object, i As Integer
'Declare a String variable for the directory root and current file in that directory
Dim currentPath As String
'declare flag to show if Word needs to be quit
Dim quitWord As Boolean
'main process----------------------------------------------------------
'error handling is extremely important in making Excel work with Word
On Error Resume Next
'GetObject needs two parameters. The first is optional
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'we create a new instance of MS Word
Set wdapp = CreateObject("Word.Application")
'as Word wasn't already open make application visible
wdapp.Visible = True
'set flag to show Word needs to be shut down
quitWord = True
End If
'reset error handling so that any subsequent errors aren't ignored
On Error GoTo 0
currentPath = Dir(path, vbDirectory)
For i = 3 To 61
Do Until currentPath = vbNullString
Debug.Print currentPath
If Left(currentPath, 1) <> "." And Left(currentPath, 1) <> "" Then
Debug.Print path & currentPath
Set wddoc = wdapp.Documents.Open(path & currentPath)
wddoc.Tables(1).Cell(2, 1).Range.Text = Sheet1.Range(Cells(i, 2), Cells(i, 2)).Value
'document no longer required so close and save changes
wddoc.Close -1 ' SaveChanges:=Word.wdSaveOptions.wdSaveChanges
Set wddoc = Nothing
currentPath = Dir()
Else
currentPath = Dir()
End If
Loop
Next
'Now that operations involving Word are complete quit Word if necessary and destroy objects
If quitWord Then wdapp.Quit
Set wdapp = Nothing
End Sub