英文:
Imports Word tables preserving format, but it splits the content of cells
问题
我有一个VBA宏,它可以导入Word表格并保留格式,但它会将单元格的内容拆分开来。似乎是因为换行符导致内容在Excel中拆分为多个单元格。我不太擅长编程,无法找到任何解决方案。我只能向这个论坛的专家寻求帮助。以下是宏代码。非常感谢您的帮助。谢谢!!
Sub ImportTablesAndFormat()
' 代码部分略...
' 调整单元格维度以匹配Word表格
For i = 1 To numRows
For j = 1 To numCols
Set wdCell = wdTbl.Cell(i, j)
Set xlCell = xlSheet.Cells(i, j)
' 用空格替换换行符
Dim cellText As String
cellText = Replace(wdCell.Range.Text, Chr(13), " ")
cellText = Replace(cellText, Chr(11), " ") ' 可选:也替换手动换行
xlCell.Value = cellText
xlCell.WrapText = wdCell.Range.ParagraphFormat.WordWrap
xlCell.Font.Bold = wdCell.Range.Font.Bold
xlCell.Font.Italic = wdCell.Range.Font.Italic
xlCell.Font.Color = wdCell.Range.Font.Color
xlCell.Interior.Color = wdCell.Range.Shading.BackgroundPatternColor
xlCell.Borders(xlEdgeLeft).LineStyle = wdCell.Borders(-1).LineStyle
xlCell.Borders(xlEdgeLeft).Weight = xlMedium
xlCell.EntireRow.AutoFit
Next j
Next i
' 清除Word范围的内容
wdRange.Delete
' 代码部分略...
End Sub
我尝试了多种方式修改循环,但没有任何效果。我似乎缺乏深入的知识来尝试更复杂的方法。我只想要Word表格中每个单元格的内容也在Excel中的一个单元格中。它们有换行符,所以大多数单元格有多行。通常第二行以“(”开始,如果有帮助的话。格式被复制得很好。很抱歉我不能提供文件作为模板,因为涉及到GDPR。非常感谢。
英文:
I have a VBA macro that Imports Word tables preserving format, but it splits the content of cells.
It seems that the break lines are causing the content to be split into several cells in excel.
I am not very good at coding and could not find any solution. I can just ask for help from experts in this forum. Below is the macro. I would really appreciate your help. Thank you!!
Sub ImportTablesAndFormat()
Dim wdApp As Object
Dim wdDoc As Object
Dim wdTbl As Object
Dim wdCell As Object
Dim wdRange As Object
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
Dim xlCell As Object
Dim myPath As String
Dim myFile As String
Dim numRows As Long
Dim numCols As Long
Dim i As Long
Dim j As Long
' Prompt user to select folder with Word files
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select Folder with Word Files"
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub
myPath = .SelectedItems(1) & "\"
End With
' Create new Excel workbook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Add
Set xlCell = xlBook.Sheets(1).Cells(1, 1)
' Loop through each Word file in folder
myFile = Dir(myPath & "*.docx")
Do While myFile <> ""
' Open Word document
Set wdApp = CreateObject("Word.Application")
Set wdDoc = wdApp.Documents.Open(myPath & myFile)
wdApp.Visible = False
' Loop through each table in Word document
For Each wdTbl In wdDoc.Tables
' Get dimensions of table
numRows = wdTbl.Rows.Count
numCols = wdTbl.Columns.Count
' Add new sheet to Excel workbook
Set xlSheet = xlBook.Sheets.Add(After:=xlBook.Sheets(xlBook.Sheets.Count))
xlSheet.Name = myFile & "Table" & xlSheet.Index
' Copy table to Word range
Set wdRange = wdTbl.Range
wdRange.Copy
' Paste table to Excel range
xlSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:=False
' Clear clipboard
Application.CutCopyMode = False
' Adjust cell dimensions to match Word table
For i = 1 To numRows
For j = 1 To numCols
Set wdCell = wdTbl.Cell(i, j)
Set xlCell = xlSheet.Cells(i, j)
' Replace line breaks with a space
Dim cellText As String
cellText = Replace(wdCell.Range.Text, Chr(13), " ")
cellText = Replace(cellText, Chr(11), " ") ' Optional: Replace manual line breaks as well
xlCell.Value = cellText
xlCell.WrapText = wdCell.Range.ParagraphFormat.WordWrap
xlCell.Font.Bold = wdCell.Range.Font.Bold
xlCell.Font.Italic = wdCell.Range.Font.Italic
xlCell.Font.Color = wdCell.Range.Font.Color
xlCell.Interior.Color = wdCell.Range.Shading.BackgroundPatternColor
xlCell.Borders(xlEdgeLeft).LineStyle = wdCell.Borders(-1).LineStyle
xlCell.Borders(xlEdgeLeft).Weight = xlMedium
xlCell.EntireRow.AutoFit
Next j
Next i
' Clear contents of Word range
wdRange.Delete
Next wdTbl
' Close Word document
wdDoc.Close SaveChanges:=False
Set wdDoc = Nothing
' Move to the next Word file in the folder
myFile = Dir
Loop
' Set the column widths
For Each xlSheet In xlBook.Sheets
xlSheet.Columns(1).ColumnWidth = 82
xlSheet.Columns(2).ColumnWidth = 32
Next xlSheet
' Save and close the Excel workbook
xlBook.SaveAs Filename:=myPath & "Tables.xlsx", FileFormat:=51
xlBook.Close SaveChanges:=True
xlApp.Quit
' Clean up objects
Set xlCell = Nothing
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing
' Display completion message
MsgBox "All tables from Word files in " & myPath & " have been imported into the Excel workbook " & myPath & "Tables.xlsx.", vbInformation, "Tables Converted"
End Sub
Tried to modify the loop in several ways I found online, but nothing would work. I lack the knowledge to
try anything deeper I guess.
I just want the content of every cell in the tables in word to be in one cell also in excel. a copy and paste really. They have break lines, so most of cells have more than one line. Usually the second line start with a "(", if that helps.
The format is being copied ok.
I am sorry I cannot provide you with a file as a template due to GDPR.
Thanks a lot.
答案1
得分: 1
这是在我的情况下效果最好的代码,希望能帮助其他人!!
Sub ImportWordTables()
' 应用程序变量
Dim wordApp As Object
Dim wordDoc As Object
Dim table As Object
' 文档变量
Dim wordDocsFolder As String
Dim docPath As String
' Excel 变量
Dim wb As Workbook
Dim ws As Worksheet
Dim nextRow As Long
Dim sheetName As String
' 优化性能
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' 设置应用程序
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = False
' 设置工作簿
Set wb = ThisWorkbook
' 提示用户选择包含 Word 文档的文件夹
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = -1 Then
wordDocsFolder = .SelectedItems(1)
End If
End With
' 获取第一个 Word 文档
docPath = Dir(wordDocsFolder & "\*.docx", vbNormal)
' 处理每个 Word 文档
Do While docPath <> ""
' 打开 Word 文档
Set wordDoc = wordApp.Documents.Open(wordDocsFolder & "\" & docPath)
' 为 Word 文档创建一个新工作表
sheetName = "Sheet" & Format(Now, "yyyymmddhhmmss")
Set ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
ws.Name = sheetName
' 复制每个表格并粘贴到 Excel 中
For Each table In wordDoc.Tables
' 在 Word 中将 ^p 替换为 " ||"
table.Range.Find.Execute FindText:="^p", ReplaceWith:=" ||", Replace:=wdReplaceAll
' 复制表格内容
table.Range.Copy
' 在 Excel 中查找下一个空行
nextRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
' 带格式粘贴表格
ws.Cells(nextRow, 1).Select
ws.Paste
' 关闭 Word 以后避免剪贴板消息
Application.CutCopyMode = False
' 循环遍历行,而不是单元格
Dim i As Long
For i = 1 To ws.UsedRange.Rows.Count
Dim cell As Range
Set cell = ws.Cells(i, "B")
' 如果 B 和 C 合并
If cell.MergeCells And cell.MergeArea.Columns.Count > 1 Then
' 存储合并信息,然后取消合并
Dim mergeRowCount As Long
mergeRowCount = cell.MergeArea.Rows.Count
cell.MergeArea.UnMerge
' 清除列 C
cell.Offset(0, 1).Resize(mergeRowCount, 1).ClearContents
' 垂直重新合并单元格
cell.Resize(mergeRowCount, 1).Merge
End If
' 重复 D 和 E
Set cell = ws.Cells(i, "D")
If cell.MergeCells And cell.MergeArea.Columns.Count > 1 Then
mergeRowCount = cell.MergeArea.Rows.Count
cell.MergeArea.UnMerge
cell.Offset(0, 1).Resize(mergeRowCount, 1).ClearContents
cell.Resize(mergeRowCount, 1).Merge
End If
Next i
Next table
' 最终化 Excel 工作表
ws.Cells.Replace What:=" ||", Replacement:=" ", LookAt:=xlPart
ws.Cells.Replace What:=" ", Replacement:=" ", LookAt:=xlPart
ws.Columns(1).ColumnWidth = 70
If ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column > 1 Then
ws.Columns(2).Resize(, ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column - 1).ColumnWidth = 30
End If
' 自动换行
ws.Cells.WrapText = True
' 不保存关闭 Word 文档
wordDoc.Close SaveChanges:=False
' 获取下一个 Word 文档
docPath = Dir()
Loop
' 清理
wordApp.Quit
Set wordApp = Nothing
' 恢复默认设置
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
英文:
This is the code that worked the best in my case I hope it helps someone else!!
Sub ImportWordTables()
' Application variables
Dim wordApp As Object
Dim wordDoc As Object
Dim table As Object
' Document variables
Dim wordDocsFolder As String
Dim docPath As String
' Excel variables
Dim wb As Workbook
Dim ws As Worksheet
Dim nextRow As Long
Dim sheetName As String
'Optimize Performance
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Set up applications
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = False
' Setup workbook
Set wb = ThisWorkbook
' Prompt user for folder containing Word docs
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = -1 Then
wordDocsFolder = .SelectedItems(1)
End If
End With
' Get first Word doc
docPath = Dir(wordDocsFolder & "\*.docx", vbNormal)
' Process each Word doc
Do While docPath <> ""
' Open Word doc
Set wordDoc = wordApp.Documents.Open(wordDocsFolder & "\" & docPath)
' Create a new sheet for the Word doc
sheetName = "Sheet" & Format(Now, "yyyymmddhhmmss")
Set ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
ws.Name = sheetName
' Copy each table and paste into Excel
For Each table In wordDoc.Tables
' Replace ^p by " ||" in Word
table.Range.Find.Execute FindText:="^p", ReplaceWith:=" ||", Replace:=wdReplaceAll
' Copy table content
table.Range.Copy
' Find next empty row in Excel
nextRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
' Paste table with formatting
ws.Cells(nextRow, 1).Select
ws.Paste
' Avoid clipboard message when closing Word later
Application.CutCopyMode = False
' Loop through rows, not cells
Dim i As Long
For i = 1 To ws.UsedRange.Rows.Count
Dim cell As Range
Set cell = ws.Cells(i, "B")
' If B and C are merged
If cell.MergeCells And cell.MergeArea.Columns.Count > 1 Then
' Store merge info, then unmerge
Dim mergeRowCount As Long
mergeRowCount = cell.MergeArea.Rows.Count
cell.MergeArea.UnMerge
' Clear column C
cell.Offset(0, 1).Resize(mergeRowCount, 1).ClearContents
' Re-merge cells vertically
cell.Resize(mergeRowCount, 1).Merge
End If
' Repeat for D and E
Set cell = ws.Cells(i, "D")
If cell.MergeCells And cell.MergeArea.Columns.Count > 1 Then
mergeRowCount = cell.MergeArea.Rows.Count
cell.MergeArea.UnMerge
cell.Offset(0, 1).Resize(mergeRowCount, 1).ClearContents
cell.Resize(mergeRowCount, 1).Merge
End If
Next i
Next table
' Finalize Excel sheet
ws.Cells.Replace What:=" ||", Replacement:=" ", LookAt:=xlPart
ws.Cells.Replace What:=" ", Replacement:=" ", LookAt:=xlPart
ws.Columns(1).ColumnWidth = 70
If ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column > 1 Then
ws.Columns(2).Resize(, ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column - 1).ColumnWidth = 30
End If
' Wrap text
ws.Cells.WrapText = True
' Close Word doc without saving
wordDoc.Close SaveChanges:=False
' Get next Word doc
docPath = Dir()
Loop
' Clean up
wordApp.Quit
Set wordApp = Nothing
'Restore Defaults
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
答案2
得分: 0
> 对不起,由于GDPR,我无法为您提供文件作为模板。非常感谢。
所以请尝试我根据您的代码进行了修改的代码。
Sub ImportTablesAndFormat()
Dim wdApp As Object 'Word.Application
Dim wdDoc As Object
Dim wdTbl As Object 'Word.Table
Dim wdCell As Object
Dim wdRange As Object
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object 'Excel.Worksheet
Dim xlCell As Object
Dim myPath As String
Dim myFile As String
Dim numRows As Long
Dim numCols As Long
Dim i As Long
Dim j As Long
' 提示用户选择包含Word文件的文件夹
With Application.FileDialog(msoFileDialogFolderPicker)
.title = "选择包含Word文件的文件夹"
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub
myPath = .SelectedItems(1) & "\"
End With
' 创建新的Excel工作簿
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Add
Set xlCell = xlBook.Sheets(1).Cells(1, 1)
' 在文件夹中循环遍历每个Word文件
myFile = Dir(myPath & "*.docx")
' 仅初始化Word应用程序一次
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = False
Do While myFile <> ""
' 打开Word文档
Set wdDoc = wdApp.Documents.Open(myPath & myFile)
' 循环遍历Word文档中的每个表格
For Each wdTbl In wdDoc.Tables
' 获取表格的行数和列数
numRows = wdTbl.Rows.Count
numCols = wdTbl.Columns.Count
' 向Excel工作簿添加新工作表
Set xlSheet = xlBook.Sheets.Add(After:=xlBook.Sheets(xlBook.Sheets.Count))
xlSheet.Name = myFile & "Table" & xlSheet.Index
' 替换换行符为逗号和空格
Dim cellText As String
For Each wdCell In wdTbl.Range.Cells
cellText = Replace(wdCell.Range.Text, Chr(13), ", ,") ' Excel中的换行符标记为chr(10),但在Word中似乎用chr(13)替代
cellText = Replace(cellText, Chr(11), ", ,") ' 可选:也替换手动换行符
Next wdCell
' 复制表格到Word范围
Set wdRange = wdTbl.Range
wdRange.Copy
' 粘贴表格到Excel范围
xlSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:=False
' 清除剪贴板
Application.CutCopyMode = False
' 调整单元格尺寸以匹配Word表格
For i = 1 To numRows
For j = 1 To numCols
Set wdCell = wdTbl.cell(i, j)
Set xlCell = xlSheet.Cells(i, j)
cellText = wdCell.Range.Text
cellText = Left(cellText, Len(cellText) - 2) ' 每个单元格末尾有Chr(13)和chr(7)
cellText = Replace(cellText, ", ,", Chr(10)) ' 恢复Word的换行格式
xlCell.Value = cellText
xlCell.WrapText = wdCell.Range.ParagraphFormat.WordWrap
xlCell.Font.Bold = wdCell.Range.Font.Bold
xlCell.Font.Italic = wdCell.Range.Font.Italic
xlCell.Font.Color = wdCell.Range.Font.Color
xlCell.Interior.Color = wdCell.Range.Shading.BackgroundPatternColor
xlCell.Borders(xlEdgeLeft).LineStyle = wdCell.Borders(-1).LineStyle
xlCell.Borders(xlEdgeLeft).Weight = xlMedium
xlCell.EntireRow.AutoFit
Next j
Next i
Next wdTbl
' 关闭Word文档
wdDoc.Close SaveChanges:=False
' 移动到文件夹中的下一个Word文件
myFile = Dir
Loop
' 关闭Word应用程序并释放内存
wdApp.Quit
Set wdDoc = Nothing: Set wdApp = Nothing
' 设置列宽
For Each xlSheet In xlBook.Sheets
xlSheet.Columns(1).ColumnWidth = 82
xlSheet.Columns(2).ColumnWidth = 32
Next xlSheet
' 保存并关闭Excel工作簿
xlBook.SaveAs FileName:=myPath & "Tables.xlsx", FileFormat:=51
xlBook.Close SaveChanges:=True
xlApp.Quit
' 清理对象
Set xlCell = Nothing
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing
' 显示完成消息
MsgBox "已将所有来自文件夹" & myPath & "中的Word文件的表格导入到Excel工作簿" & myPath & "Tables.xlsx。", vbInformation, "表格已转换"
End Sub
- Word的表格中是否有合并单元格?
- 为什么在“将换行符替换为空格”和“调整单元格尺寸以匹配Word表格”的代码之前执行了xlSheet.PasteSpecial?逻辑上应该反过来。
英文:
> I am sorry I cannot provide you with a file as a template due to GDPR. Thanks a lot.
So plz try the code which I've modified with my imagination according to your code.
Sub ImportTablesAndFormat()
Dim wdApp As Object 'Word.Application
Dim wdDoc As Object
Dim wdTbl As Object 'Word.Table
Dim wdCell As Object
Dim wdRange As Object
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object 'Excel.Worksheet
Dim xlCell As Object
Dim myPath As String
Dim myFile As String
Dim numRows As Long
Dim numCols As Long
Dim i As Long
Dim j As Long
' Prompt user to select folder with Word files
With Application.FileDialog(msoFileDialogFolderPicker)
.title = "Select Folder with Word Files"
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub
myPath = .SelectedItems(1) & "\"
End With
' Create new Excel workbook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Add
Set xlCell = xlBook.Sheets(1).Cells(1, 1)
' Loop through each Word file in folder
myFile = Dir(myPath & "*.docx")
Rem just initiate Word app once
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = False
Do While myFile <> ""
' Open Word document
' Set wdApp = CreateObject("Word.Application")
Set wdDoc = wdApp.Documents.Open(myPath & myFile)
'wdApp.Visible = False
' Loop through each table in Word document
For Each wdTbl In wdDoc.Tables
' Get dimensions of table
numRows = wdTbl.Rows.Count
numCols = wdTbl.Columns.Count
' Add new sheet to Excel workbook
Set xlSheet = xlBook.Sheets.Add(After:=xlBook.Sheets(xlBook.Sheets.Count))
xlSheet.Name = myFile & "Table" & xlSheet.Index
'' Replace line breaks with a space
Rem Replace line breaks with chr(10)s to retain the format like Word
Dim cellText As String
For Each wdCell In wdTbl.Range.Cells
cellText = Replace(wdCell.Range.Text, Chr(13), ", ,") ' Line break mark is chr(10) in Excel, however in Word it Seems to be replace with chr(13)
cellText = Replace(cellText, Chr(11), ", ,") ' Optional: Replace manual line breaks as well
' cellText = Replace(wdCell.Range.Text, Chr(13), Chr(10)) '" ")' Line break mark is chr(10) in Excel, however in Word it Seems to be replace with chr(13)
' cellText = Replace(cellText, Chr(11), Chr(10)) '" ") ' Optional: Replace manual line breaks as well
Next wdCell
' Copy table to Word range
Set wdRange = wdTbl.Range
wdRange.Copy
' Paste table to Excel range
xlSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:=False
' Clear clipboard
Application.CutCopyMode = False
' Adjust cell dimensions to match Word table
For i = 1 To numRows
For j = 1 To numCols
Set wdCell = wdTbl.cell(i, j)
Set xlCell = xlSheet.Cells(i, j)
cellText = wdCell.Range.Text
cellText = VBA.Left(cellText, VBA.Len(cellText) - 2) 'there will be Chr(13)& chr(7) in the end of each cell
cellText = VBA.Replace(cellText, ", ,", Chr(10)) 'restore the Word line break format
' ' Replace line breaks with a space
' Dim cellText As String
' cellText = Replace(wdCell.Range.Text, Chr(13), " ")
' cellText = Replace(cellText, Chr(11), " ") ' Optional: Replace manual line breaks as well
xlCell.Value = cellText
xlCell.WrapText = wdCell.Range.ParagraphFormat.WordWrap
xlCell.Font.Bold = wdCell.Range.Font.Bold
xlCell.Font.Italic = wdCell.Range.Font.Italic
xlCell.Font.color = wdCell.Range.Font.color
xlCell.Interior.color = wdCell.Range.Shading.BackgroundPatternColor
xlCell.Borders(xlEdgeLeft).LineStyle = wdCell.Borders(-1).LineStyle
xlCell.Borders(xlEdgeLeft).Weight = xlMedium
xlCell.EntireRow.AutoFit
Next j
Next i
' Clear contents of Word range
'wdRange.Delete
Rem why do you do this? you do not save the doc `wdDoc.Close SaveChanges:=False` and next to the next table
Rem so This line is unnecessary.
Next wdTbl
' Close Word document
wdDoc.Close SaveChanges:=False
Rem Run this at the end to release the memory.
'Set wdDoc = Nothing
' Move to the next Word file in the folder
myFile = Dir
Loop
Rem close word app and release the memory.
wdApp.Quit
Set wdDoc = Nothing: Set wdApp = Nothing
' Set the column widths
For Each xlSheet In xlBook.Sheets
xlSheet.Columns(1).ColumnWidth = 82
xlSheet.Columns(2).ColumnWidth = 32
Next xlSheet
' Save and close the Excel workbook
xlBook.SaveAs FileNAme:=myPath & "Tables.xlsx", FileFormat:=51
xlBook.Close SaveChanges:=True
xlApp.Quit
' Clean up objects
Set xlCell = Nothing
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing
' Display completion message
MsgBox "All tables from Word files in " & myPath & " have been imported into the Excel workbook " & myPath & "Tables.xlsx.", vbInformation, "Tables Converted"
End Sub
- Do you have merged cells in Word's tables?
- Why you do xlSheet.PasteSpecial before ' Replace line breaks with a space of Adjust cell dimensions to match Word table? Logically should be reversed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论