Visual Basic в Word: сравнить выделение в пределах диапазона

ОБНОВЛЕНИЕ: Следуя предложению Синди ниже, я использовал функцию 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, который я еще не совсем понимаю. Я не программист, а всего лишь полутехнический писатель, самоучка некоторого кодирования, перед которым стоит задача автоматизации преобразования документов.

Должен быть лучший способ сравнить точку выбора, чтобы проверить, находится ли она в пределах именованного диапазона, но я не могу его найти. Искренне признательны за любые указатели, которые вы можете мне дать!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
429
3

Ответы 3

Не большой специалист по 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

Спасибо, это помогает мне лучше понимать диапазоны!

montereyredfox 26.10.2018 22:43

спасибо за вклад и идею. Я реализовал ваше предложение. Однако по неизвестным причинам это не удается. Происходит одна странная вещь: диапазон SpecBodyPairRange произвольно изменяется во время выполнения функции, по-видимому, свернувшись до точки вставки.

montereyredfox 27.10.2018 01:50

@montereyredfox Хорошо, я ответил на ваш первоначальный вопрос. Но ваш вопрос настоящий кажется другим: как искать только в диапазоне, отмеченном закладками? Это совсем другое дело, и правильно должен быть другой вопрос. В Stack Overflow считается «дурным тоном» изменять вопрос таким образом, что люди должны начинать с ответа - что происходит, когда вы меняете свой код тем, что находится в ответе, а затем говорите: «У меня новая проблема».

Cindy Meister 27.10.2018 07:11

Но FWIW @montereyredfox это потому, что вы никогда не переназначаете rngSelection внутри цикла. Запустите Find на нем вместо Selection.

Cindy Meister 27.10.2018 07:13

спасибо за информацию и новости о хорошем поведении StackOverflow.

montereyredfox 29.10.2018 16:43

Вы можете использовать метод 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 26.10.2018 23:38

@montereyredfox Код делает перебирает весь диапазон, охватываемый закладкой SpecBodyPairRange; Я предлагаю вам еще раз проверить, что охватывает этот диапазон и какие стили используются в нем.

macropod 27.10.2018 07:03

Другие вопросы по теме

Похожие вопросы

Как перейти к нужной ячейке в Excel при нажатии клавиши ввода?
Как отсортировать подмножество по некоторому упорядоченному надмножеству?
Существуют ли эквиваленты ADODB.connection ADODB.recordset в Excel для Mac 2016?
Excel 2013 VBA: формулы копирования-вставки копирует значение из скопированной ячейки (в дополнение к формуле) вместо повторного вычисления
Как подсчитать количество нечисловых слов в Excel с помощью функции VBA
Необходимо проанализировать ячейку в Excel для определенного текста и скопировать текст рядом с ним
Алгоритм: найти два положительных целых числа, разность которых минимизирована и произведение которых известно
Сценарий VBA, который преобразует HTML в форматированный текст и вставляет несколько строк данных в буфер обмена в одну ячейку
Макрос Word для изменения цвета отрицательных чисел в определенном столбце в зависимости от значения в другом столбце
Можно ли использовать приложение без COM?