将所选 Word 表格复制到 Excel
Copy selection of Word tables to Excel
我修改了 Macro to export MS Word tables to Excel sheets 中的代码,以复制表格的顺序间隔(例如 1 到 4),而不是像原始代码那样复制所有表格。
但我不知道如何复制 Word 文档中的部分表格(例如表格 1、3、7、8)。
非常感谢帮助调整相关代码部分!
'For tableStart = 1 To tableTo '<- copies all tables
For tableStart = 1 To 4 '<- copies sequential interval of tables
With .tables(tableStart)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableStart
整个宏是:
Sub ImportWordTables()
Dim WordApp As Object
Dim WordDoc As Object
Dim arrFileList As Variant, FileName As Variant
Dim tableNo As Integer 'table number in Word
Dim tableStart As Integer
Dim tableTot As Integer
Dim Target As Range
On Error Resume Next
arrFileList = Application.GetOpenFilename("Word files (*.doc; *.docx),*.doc;*.docx", 2, _
"Browse for file containing table to be imported", , True)
If Not IsArray(arrFileList) Then Exit Sub '<-user cancelled import file browser
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Range("A:AZ").ClearContents
Set Target = Worksheets("MySheet").Range("A1")
For Each FileName In arrFileList
Set WordDoc = WordApp.Documents.Open(FileName, ReadOnly:=True)
With WordDoc
tableNo = WordDoc.tables.Count
tableTot = WordDoc.tables.Count
If tableNo = 0 Then
MsgBox WordDoc.Name & "Contains no tables", vbExclamation, "Import Word Table"
End If
'For tableStart = 1 To tableTo '<- copies all tables
For tableStart = 1 To 4 '<- copies interval of tables
With .tables(tableStart)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableStart
.Close False
End With
Next FileName
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
您可以将 table 的列表作为数组提供。我将其添加到下面的重组代码中。您提供一个变体,其中包含要复制到 ImportWordTables 子项的 table 个数字的数组。我会留给您修改代码,将参数设为可选,这样您就可以复制列表中的所有 table 或 table。
Option Explicit
Public Enum TableImportError
NoTables
UnexpectedIndex
End Enum
Public Sub ImportWordTables(ByVal ipTableList As Variant)
Dim arrFileList As Variant
If Not TryGetFileNameList(arrFileList) Then Exit Sub
Dim WordApp As Object
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
' the range should be qualified by the relevant wb/ws
Range("A:AZ").ClearContents
Dim FileName As Variant
For Each FileName In arrFileList
Dim WordDoc As Object
Set WordDoc = WordApp.Documents.Open(FileName, ReadOnly:=True)
Dim myReason As TableImportError
If Not TryImportTables(WordDoc, ipTableList, myReason) Then
Select Case myReason
Case TableImportError.NoTables
MsgBox WordDoc.Name & "Contains no tables", vbExclamation, "Import Word Table"
Case TableImportError.UnexpectedIndex
MsgBox WordDoc.Name & "Unexpected index", vbExclamation, "The table indexes exceed the total table count. No tables copies"
End Select
End If
Next FileName
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
Private Function TryGetFileNameList(ByRef opFileList As Variant) As Boolean
On Error Resume Next
opFileList = Application.GetOpenFilename("Word files (*.doc; *.docx),*.doc;*.docx", 2, _
"Browse for file containing table to be imported", , True)
On Error GoTo 0
TryGetFileNameList = IsArray(opFileList)
End Function
Private Function TryImportTables(ByRef ipDoc As Word.Document, ByVal ipTableList As Variant, ByRef opReason As TableImportError) As Boolean
TryImportTables = False
If ipDoc.Tables.Count = 0 Then
opReason = TableImportError.NoTables
Exit Function
End If
Dim myTable As Variant
For Each myTable In ipTableList
If myTable > ipDoc.Tables.Count Then
opReason = TableImportError.UnexpectedIndex
Exit Function
End If
Next
For Each myTable In ipTableList
With ipDoc.Tables.Item(myTable)
.Range.Copy
' replaced Target by worksheet refernce
' ideally this item should be passed as a parameter
' or second best defined as a module level variable.
'
' worksheets should be qualified by the relevant wb
With Worksheets("MySheet")
.Activate
.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
Set .Range("A1") = .Range("A1").Offset(.Rows.Count + 2, 0)
'.Paste
End With
End With
Next
TryImportTables = True
End Function
上面的代码可以编译,并且不会通过用于 VBA 的免费且出色的 Rubberduck 插件给出任何意外的代码检查警告。然而,由于它是一个彻底的重组,我不能保证它会像你以前的代码一样工作,所以请检查你是否决定使用它。
将您的这段代码设置为您使用 TableIndex 从 Main Sub 调用的函数
With .tables(tableIndex)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
将 tableIndex 变量设置为从 Word 文档中的 table 集合中分配的随机数。您必须决定迭代代码的次数,以便获得所需的随机样本大小,但基本代码可能如下所示:
Sub ReturnRandomNumber()
Dim TableIndex As Integer
Dim WordDoc As Word.Document
Randomize
TableIndex = Int((WordDoc.Tables.Count * Rnd) + 1)
CopyRandomTable WordDoc, TableIndex
End Sub
Function CopyRandomTable(ByRef WordDoc As Word.Document, ByRef TableIndex As Integer)
With WordDoc.Tables(TableIndex)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.rows.Count + 2, 0)
End With
End Function
RND 函数也可能 return 相同的 table 索引,因此您应该考虑如何处理它...比如可能设置一个 table 索引已被使用,然后采取相应行动。
有关随机化和 RND 函数的更多信息,请点击此处 Microsoft Article on the RND Function。
已解决,但输入框和内存容量问题仍待解决。
将上面第一个示例中的 With .tables(tableIndex)
部分替换为以下内容:
'For array
Dim tables() As Variant
Dim tableCounter As Long
tables = Array(1, 3, 7) '<- define array manually here
For tableCounter = LBound(tables) To UBound(tables)
With .tables(tables(tableCounter))
.Range.Copy
Target.Activate
'Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False '<- gives RAM capacity problems!
ActiveSheet.Paste '<- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableCounter
我修改了 Macro to export MS Word tables to Excel sheets 中的代码,以复制表格的顺序间隔(例如 1 到 4),而不是像原始代码那样复制所有表格。
但我不知道如何复制 Word 文档中的部分表格(例如表格 1、3、7、8)。
非常感谢帮助调整相关代码部分!
'For tableStart = 1 To tableTo '<- copies all tables
For tableStart = 1 To 4 '<- copies sequential interval of tables
With .tables(tableStart)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableStart
整个宏是:
Sub ImportWordTables()
Dim WordApp As Object
Dim WordDoc As Object
Dim arrFileList As Variant, FileName As Variant
Dim tableNo As Integer 'table number in Word
Dim tableStart As Integer
Dim tableTot As Integer
Dim Target As Range
On Error Resume Next
arrFileList = Application.GetOpenFilename("Word files (*.doc; *.docx),*.doc;*.docx", 2, _
"Browse for file containing table to be imported", , True)
If Not IsArray(arrFileList) Then Exit Sub '<-user cancelled import file browser
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Range("A:AZ").ClearContents
Set Target = Worksheets("MySheet").Range("A1")
For Each FileName In arrFileList
Set WordDoc = WordApp.Documents.Open(FileName, ReadOnly:=True)
With WordDoc
tableNo = WordDoc.tables.Count
tableTot = WordDoc.tables.Count
If tableNo = 0 Then
MsgBox WordDoc.Name & "Contains no tables", vbExclamation, "Import Word Table"
End If
'For tableStart = 1 To tableTo '<- copies all tables
For tableStart = 1 To 4 '<- copies interval of tables
With .tables(tableStart)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableStart
.Close False
End With
Next FileName
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
您可以将 table 的列表作为数组提供。我将其添加到下面的重组代码中。您提供一个变体,其中包含要复制到 ImportWordTables 子项的 table 个数字的数组。我会留给您修改代码,将参数设为可选,这样您就可以复制列表中的所有 table 或 table。
Option Explicit
Public Enum TableImportError
NoTables
UnexpectedIndex
End Enum
Public Sub ImportWordTables(ByVal ipTableList As Variant)
Dim arrFileList As Variant
If Not TryGetFileNameList(arrFileList) Then Exit Sub
Dim WordApp As Object
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
' the range should be qualified by the relevant wb/ws
Range("A:AZ").ClearContents
Dim FileName As Variant
For Each FileName In arrFileList
Dim WordDoc As Object
Set WordDoc = WordApp.Documents.Open(FileName, ReadOnly:=True)
Dim myReason As TableImportError
If Not TryImportTables(WordDoc, ipTableList, myReason) Then
Select Case myReason
Case TableImportError.NoTables
MsgBox WordDoc.Name & "Contains no tables", vbExclamation, "Import Word Table"
Case TableImportError.UnexpectedIndex
MsgBox WordDoc.Name & "Unexpected index", vbExclamation, "The table indexes exceed the total table count. No tables copies"
End Select
End If
Next FileName
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
Private Function TryGetFileNameList(ByRef opFileList As Variant) As Boolean
On Error Resume Next
opFileList = Application.GetOpenFilename("Word files (*.doc; *.docx),*.doc;*.docx", 2, _
"Browse for file containing table to be imported", , True)
On Error GoTo 0
TryGetFileNameList = IsArray(opFileList)
End Function
Private Function TryImportTables(ByRef ipDoc As Word.Document, ByVal ipTableList As Variant, ByRef opReason As TableImportError) As Boolean
TryImportTables = False
If ipDoc.Tables.Count = 0 Then
opReason = TableImportError.NoTables
Exit Function
End If
Dim myTable As Variant
For Each myTable In ipTableList
If myTable > ipDoc.Tables.Count Then
opReason = TableImportError.UnexpectedIndex
Exit Function
End If
Next
For Each myTable In ipTableList
With ipDoc.Tables.Item(myTable)
.Range.Copy
' replaced Target by worksheet refernce
' ideally this item should be passed as a parameter
' or second best defined as a module level variable.
'
' worksheets should be qualified by the relevant wb
With Worksheets("MySheet")
.Activate
.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
Set .Range("A1") = .Range("A1").Offset(.Rows.Count + 2, 0)
'.Paste
End With
End With
Next
TryImportTables = True
End Function
上面的代码可以编译,并且不会通过用于 VBA 的免费且出色的 Rubberduck 插件给出任何意外的代码检查警告。然而,由于它是一个彻底的重组,我不能保证它会像你以前的代码一样工作,所以请检查你是否决定使用它。
将您的这段代码设置为您使用 TableIndex 从 Main Sub 调用的函数
With .tables(tableIndex)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
将 tableIndex 变量设置为从 Word 文档中的 table 集合中分配的随机数。您必须决定迭代代码的次数,以便获得所需的随机样本大小,但基本代码可能如下所示:
Sub ReturnRandomNumber()
Dim TableIndex As Integer
Dim WordDoc As Word.Document
Randomize
TableIndex = Int((WordDoc.Tables.Count * Rnd) + 1)
CopyRandomTable WordDoc, TableIndex
End Sub
Function CopyRandomTable(ByRef WordDoc As Word.Document, ByRef TableIndex As Integer)
With WordDoc.Tables(TableIndex)
.Range.Copy
Target.Activate
Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False
'ActiveSheet.Paste <- pastes with formatting
Set Target = Target.Offset(.rows.Count + 2, 0)
End With
End Function
RND 函数也可能 return 相同的 table 索引,因此您应该考虑如何处理它...比如可能设置一个 table 索引已被使用,然后采取相应行动。
有关随机化和 RND 函数的更多信息,请点击此处 Microsoft Article on the RND Function。
已解决,但输入框和内存容量问题仍待解决。
将上面第一个示例中的 With .tables(tableIndex)
部分替换为以下内容:
'For array
Dim tables() As Variant
Dim tableCounter As Long
tables = Array(1, 3, 7) '<- define array manually here
For tableCounter = LBound(tables) To UBound(tables)
With .tables(tables(tableCounter))
.Range.Copy
Target.Activate
'Target.Parent.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False '<- gives RAM capacity problems!
ActiveSheet.Paste '<- pastes with formatting
Set Target = Target.Offset(.Rows.Count + 2, 0)
End With
Next tableCounter