我有一个Word宏,该宏可将其光标放在Word文档中的任何位置,它查找并保存标题<标题>,标题2>和标题3文本,该文本位于上方用户为了捕获与文档中任何句子相关的章,节和小节。
我目前正在使用下面的代码,它将代码逐行向上移动,直到找到包含“ Heading x”的样式。完成此任务后,我向下移动要达到标题1的行数,该行数可能很多。
您可以想象这很尴尬,需要很长时间(有时需要60+秒),并且在视觉上令人不安。
下面的代码是标识标题的子例程。
Dim str_heading_txt, hdgn_STYLE As String
Dim SELECTION_PG_NO as Integer
hdng_STYLE = Selection.Style
Do Until Left(hdng_STYLE, 7) = "Heading"
LINESUP = LINESUP + 1
Selection.MoveUp Unit:=wdLine, COUNT:=1
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
hdng_STYLE = Selection.Style
'reached first page without finding heading
SELECTION_PG_NO = Selection.Information(wdActiveEndPageNumber)
If SELECTION_PG_NO = 1 Then 'exit if on first page
a_stop = True
Exit Sub
End If
Loop
str_heading_txt = Selection.Sentences(1)
我尝试了下面的另一种方法,以便使用下面的Range.Find命令消除滚动和性能问题。
我无法使选择范围移动到具有“标题1”样式的文本。该代码在初始选择时选择句子,而不是“标题1”样式的文本。
理想情况下,“查找”命令会将我带到任何包含“标题”的样式,但是如果需要,我可以分别为“标题1”,“标题2”和“标题3”编写代码。
需要对代码进行哪些更改,以便选择“标题1”,或者选择“标题”?
Dim str_heading_txt, hdgn_STYLE As String
Dim Rng As Range
Dim Fnd As Boolean
Set Rng = Selection.Range
With Rng.Find
.ClearFormatting
.Style = "Heading 1"
.Forward = False
.Execute
Fnd = .Found
End With
If Fnd = True Then
With Rng
hdng_STYLE = Selection.Style
str_heading_txt = Selection.Sentences(1)
End With
End If
衷心感谢您的协助。
答案 0 :(得分:1)
您可以使用range.GoTo()
方法。
Dim rngHead As Range, str_heading_txt As String, hdgn_STYLE As String
Set rngHead = Selection.GoTo(wdGoToHeading, wdGoToPrevious)
'Grab the entire text - headers are considered a paragraph
rngHead.Expand wdParagraph
' Read the text of your heading
str_heading_txt = rngHead.Text
' Read the style (name) of your heading
hdgn_STYLE = rngHead.Style
我注意到您使用Selection.Sentences(1)
来抓取文本,但是标题本身就本质上就是一个段落-因此您可以使用range.Expand()
方法并使用wdParagraph
进行扩展>
还有一些建议:
在声明变量时,例如:
Dim str_heading_txt, hdgn_STYLE As String
您的意图很好,但是实际上str_heading_txt
被声明为类型Variant
。不幸的是,对于VBA,如果希望变量具有特定的数据类型,则需要单独声明:
Dim str_heading_txt As String, hdgn_STYLE As String
或者某些数据类型甚至具有称为“字符”的“简写”方法:
Dim str_heading_txt$, hdgn_STYLE$
注意到$
是如何附加到变量末尾的?这只是将其声明为 String ,而无需使用As String
。
一些常见的类型字符:
$
字符串&
长%
整数!
单身#
双人您甚至可以将这些附加到实际值之后:
Dim a
a = 5
Debug.Print TypeName(a) 'Prints Integer (default)
a = 5!
Debug.Print TypeName(a) 'Prints Single
答案 1 :(得分:0)
尝试根据以下内容进行尝试:
Sub Demo()
Dim Rng As Range, StrHd As String, s As Long
s = 10
With Selection
Set Rng = .Range
Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
StrHd = Rng.Paragraphs.First.Range.Text
Do While Right(Rng.Paragraphs.First.Style, 1) > 1
Rng.End = Rng.Start - 1
Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
With Rng.Paragraphs.First
If Right(.Style, 1) < s Then
s = Right(.Style, 1)
StrHd = .Range.Text & StrHd
End If
End With
Loop
MsgBox StrHd
End With
End Sub