ОБНОВЛЕНИЕ: Следуя предложению Синди ниже, я использовал функцию InRange. Моя функция отлично повторяет операцию поиска. Но функция не может вернуть FALSE, когда выбор находится за пределами именованного диапазона. См. «ОТКАЗ ЗДЕСЬ» ниже. Спасибо.
Используя Visual Basic, мне нужно проверить, находится ли место выбора в документе Word в пределах именованного диапазона. Много лет назад я использовал этот код для этого:
ActiveDocument.Bookmarks("typdef").Select
While ((WordBasic.CmpBookmarks("\Sel", "typedef") = 8 _
Or WordBasic.CmpBookmarks("\Sel", "typedef") = 6 _
Or WordBasic.CmpBookmarks("\Sel", "typedef") = 10) _
And leaveloop <> 1
...
If WordBasic.CmpBookmarks("\Sel", "\EndOfDoc") = 0 Then
leaveloop = 1
End If
Wend
Вот обновленная функция, которую я написал:
Function FormatSpecHeadReturn(strStyle)
Dim rngBookmark As Word.Range
Dim rngSelection As Word.Range
Set rngBookmark = ActiveDocument.Bookmarks("SpecBodyPairRange").Range
Set rngSelection = Selection.Range
var = rngSelection.InRange(rngBookmark)
Debug.Print var
Do While rngSelection.InRange(rngBookmark) = True
Selection.Find.Style = ActiveDocument.Styles(strStyle)
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "^p"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindAsk
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.HomeKey
' FAILING HERE: Returns TRUE when selection point
' is outside SpecBodyPairRange
var = rngSelection.InRange(rngBookmark)
Debug.Print var
Selection.HomeKey Unit:=wdLine, Extend:=wdMove
Selection.InsertBefore Chr(182)
Selection.EndKey
Selection.InsertAfter vbTab
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
If rngSelection.InRange(rngBookmark) <> True Then Exit Do
Loop
End Function
Я использовал CmpBookmarks в этом текущем проекте, но он ненадежно возвращал значение текущего местоположения. Когда точка выбора находится в пределах именованного диапазона, он возвращает 8 для двух циклов, а затем возвращает 6. Когда точка выбора находится за пределами именованного диапазона, CmpBookmarks возвращает 6.
Очевидно, что CmpBookmarks устарел. Я не могу найти возвращаемые значения, которые производит CmpBookmarks, и не могу найти современную эквивалентную функцию.
Признаюсь, я не понимаю разницы между названным диапазоном "SpecBodyPairRange" и диапазоном, присвоенным r, здесь:
Dim r As Диапазон
Я вижу, что «r» в этом случае, кажется, содержит весь документ. Я изучал интерфейс диапазона и интерфейс выбора на Microsoft.Office.Interop.Word, который я еще не совсем понимаю. Я не программист, а всего лишь полутехнический писатель, самоучка некоторого кодирования, перед которым стоит задача автоматизации преобразования документов.
Должен быть лучший способ сравнить точку выбора, чтобы проверить, находится ли она в пределах именованного диапазона, но я не могу его найти. Искренне признательны за любые указатели, которые вы можете мне дать!
Не большой специалист по Word VBA, но можете ли вы просто сравнить свойства Start
и End
?
Dim bm As Bookmark
Set bm = ActiveDocument.Bookmarks("tester")
Debug.Print "Bookmark", bm.Start, bm.End
Debug.Print "Selection", Selection.Start, Selection.End
Чтобы определить, находится ли один Range
в другом, используйте метод InRange
:
Dim rngBookmark as Word.Range
Dim rngSelection as Word.Range
Set rngBookmark = ActiveDocument.Bookmarks("typeDef").Range
Set rngSelection = Selection.Range
If rngSelection.InRange(rngBookmark) = True Then
'Do something
End If
спасибо за вклад и идею. Я реализовал ваше предложение. Однако по неизвестным причинам это не удается. Происходит одна странная вещь: диапазон SpecBodyPairRange произвольно изменяется во время выполнения функции, по-видимому, свернувшись до точки вставки.
@montereyredfox Хорошо, я ответил на ваш первоначальный вопрос. Но ваш вопрос настоящий кажется другим: как искать только в диапазоне, отмеченном закладками? Это совсем другое дело, и правильно должен быть другой вопрос. В Stack Overflow считается «дурным тоном» изменять вопрос таким образом, что люди должны начинать с ответа - что происходит, когда вы меняете свой код тем, что находится в ответе, а затем говорите: «У меня новая проблема».
Но FWIW @montereyredfox это потому, что вы никогда не переназначаете rngSelection
внутри цикла. Запустите Find
на нем вместо Selection
.
спасибо за информацию и новости о хорошем поведении StackOverflow.
Вы можете использовать метод VBA InRange. Например:
Function FormatSpecHeadReturn(strStyle)
Dim Rng As Range
With ActiveDocument
Set Rng = .Bookmarks("SpecBodyPairRange").Range
With .Bookmarks("SpecBodyPairRange").Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "^p"
.Replacement.Text = ""
.Style = strStyle
.Format = True
.Forward = True
.Wrap = wdFindStop
.MatchWildcards = False
.Execute
End With
Do While .Find.Found
If .InRange(Rng) = False Then Exit Do
.Style = "SpecHead"
.Paragraphs.First.InsertBefore Chr(182)
.InsertAfter vbTab
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
End With
End Function
Это здорово, это значительно упрощает то, что я пытаюсь сделать. Однако он не проходит через весь диапазон.
@montereyredfox Код делает перебирает весь диапазон, охватываемый закладкой SpecBodyPairRange; Я предлагаю вам еще раз проверить, что охватывает этот диапазон и какие стили используются в нем.
Спасибо, это помогает мне лучше понимать диапазоны!