【发布时间】:2020-10-15 20:31:11
【问题描述】:
我有数百个 Word 文件 (docx),每个文件都有不同的标题,定义为标题 1、标题 2、标题 3 等。每个文件都有一个与标题对应的目录。
我想将每个文件中的每个标题提取到 Excel 工作簿中以构建数据库。
我的第一次尝试是将单个 Word 文档中的标题提取到 Excel 工作簿中。我在网上找到了从 Word 中提取标题到 Outlook 的代码,以及从 Word 中提取标题到新 Word 文件的单独代码。
我无法适应其中任何一个。
如何将单个 Word 文件中的标题提取到 Excel?然后我会尝试制定进一步的步骤。
Word 到 Outlook
Sub CopyHeadingsIntoOutlookMail()
Dim objOutlookApp, objMail As Object
Dim objMailDocument As Word.Document
Dim objMailRange As Word.Range
Dim varHeadings As Variant
Dim i As Long
Dim strText As String
Dim nLongDiff As Integer
'Create a new Outlook email
Set objOutlookApp = CreateObject("Outlook.Application")
Set objMail = objOutlookApp.CreateItem(olMailItem)
objMail.Display
Set objMailDocument = objMail.GetInspector.WordEditor
Set objMailRange = objMailDocument.Range(0, 0)
'Get the headings of the current Word document
varHeadings = ActiveDocument.GetCrossReferenceItems(wdRefTypeHeading)
For i = LBound(varHeadings) To UBound(varHeadings)
strText = Trim(varHeadings(i))
'Get the heading level
nLongDiff = Len(RTrim$(CStr(varHeadings(i)))) - Len(Trim(CStr(varHeadings(i))))
nHeadingLevel = (nLongDiff / 2) + 1
'Insert the heading into the Outlook mail
With objMailRange
.InsertAfter strText & vbNewLine
.Style = "Heading " & nHeadingLevel
.Collapse wdCollapseEnd
End With
Next i
End Sub
逐字逐句
Public Sub CreateOutline()
Dim docOutline As Word.Document
Dim docSource As Word.Document
Dim rng As Word.Range
Dim astrHeadings As Variant
Dim strText As String
Dim intLevel As Integer
Dim intItem As Integer
Set docSource = ActiveDocument
Set docOutline = Documents.Add
' Content returns only the
' main body of the document, not
' the headers and footer.
Set rng = docOutline.Content
astrHeadings = _
docSource.GetCrossReferenceItems(wdRefTypeHeading)
For intItem = LBound(astrHeadings) To UBound(astrHeadings)
' Get the text and the level.
strText = Trim$(astrHeadings(intItem))
intLevel = GetLevel(CStr(astrHeadings(intItem)))
' Add the text to the document.
rng.InsertAfter strText & vbNewLine
' Set the style of the selected range and
' then collapse the range for the next entry.
rng.Style = "Heading " & intLevel
rng.Collapse wdCollapseEnd
Next intItem
End Sub
Private Function GetLevel(strItem As String) As Integer
' Return the heading level of a header from the
' array returned by Word.
' The number of leading spaces indicates the
' outline level (2 spaces per level: H1 has
' 0 spaces, H2 has 2 spaces, H3 has 4 spaces.
Dim strTemp As String
Dim strOriginal As String
Dim intDiff As Integer
' Get rid of all trailing spaces.
strOriginal = RTrim$(strItem)
' Trim leading spaces, and then compare with
' the original.
strTemp = LTrim$(strOriginal)
' Subtract to find the number of
' leading spaces in the original string.
intDiff = Len(strOriginal) - Len(strTemp)
GetLevel = (intDiff / 2) + 1
End Function
【问题讨论】:
-
我怀疑你会想从 Excel 开始。您需要决定如何存储在 Excel 中获得的数据。每个文档有多少行?有多少个标题?您是否要为不同的标题级别设置不同的列?
-
您会在 MVP 常见问题解答网站上找到循环遍历特定文件夹中所有文档以进行查找和替换的代码。一旦您拥有提取和存储标题的代码,就可以将其用于您的任务。 wordmvp.com/FAQs/MacrosVBA/BatchFR.htm
-
注意,macropod 的宏是 Excel 宏。它不提取标题,而是提取目录。如果目录基于您想要的标题,它应该适合您。 (目录默认基于标题1-3,但可以基于其他内容。)
-
亲爱的 Charles,非常感谢您抽出宝贵时间回答这个问题。下面的 Macropod 为我提供了完整的代码,所以我很高兴。
-
抱歉,我在提交我的评论后看到了您的最后一条评论。也许理想情况下,它会在不破坏循环的情况下忽略任何没有目录的文件,或者只是提取标题。但是,它肯定会遇到大量文件来帮助构建数据库
标签: excel vba ms-word tableofcontents heading