1

Тема: Как выполнить условие в зависимости от места курсора в документе?

Плохо владею VBA, не знаю объектов Word. Помогите, please, выполнить условия в макрокоманде.
Если курсор находится в основном тексте документа, то должны выполняться одни команды (Операторы 1), а если курсор находится в тексте сносок, то надо выполнить другие команды (Операторы 2).
Как называются на VBA эти объекты - основной текст и текст сносок - и как к ним обратиться? Прошу направить на нужный путь.

Каркас макроса такой:

Sub Макрос()
Если курсор в основном тексте, то:
Операторы 1
Если курсор в тексте сносок, то:
Операторы 2
End Sub

2

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

Каркас макроса такой:
Sub Макрос()
Если курсор в основном тексте, то:
Операторы 1
Если курсор в тексте сносок, то:
Операторы 2
End Sub

Можете посмотреть такой пример (текст ниже). Подробнее об объекте StoryRanges можете по ссылке внешняя ссылка
В примере проводится выяснение, где находится выделенный текст или курсор - в области сносок или нет (с точки зрения VBA курсор - это вырожденный случай Selection'а или выделенный текст нулевой длины).

Sub DetermineFootnoteRange()
'Определить, где курсор или выделенный текст - в области сносок или нет
Dim selrange As Range
Dim footnoterange As Range
Dim selinfootnotes As Boolean

Set selrange = Selection.Range
Set footnoterange = Nothing
On Error Resume Next
Set footnoterange = ActiveDocument.StoryRanges(wdFootnotesStory)
On Error GoTo 0
If footnoterange Is Nothing Then
    MsgBox "В документе нет сносок"
Else
    selinfootnotes = selrange.InRange(footnoterange)
    If selinfootnotes Then
        MsgBox "Курсор (или выделенный текст) находится в области сносок"
    Else
        MsgBox "Курсор (или выделенный текст) находится НЕ в области сносок"
    End If
End If
End Sub

3

Re: Как выполнить условие в зависимости от места курсора в документе?

Спасибо! Как раз то, что надо!
Остается лишь доспросить.
А если речь пойдет о концевых сносках, то, видимо, объектом выделения будет wdEndnotesStory?

Так оно называется?

4

Re: Как выполнить условие в зависимости от места курсора в документе?

Премного благодарен!
Сам попробовал для концевых сносок - все получилось!

5

Re: Как выполнить условие в зависимости от места курсора в документе?

yshindin пишет:

...ActiveDocument.StoryRanges...

Мы не ищем легких путей? smile Есть свойство StoryType:

    If Selection.StoryType = wdMainTextStory Then
        ' главная часть
    ElseIf Selection.StoryType = wdFootnotesStory Then
        ' сноски
    ElseIf Selection.StoryType = wdEndnotesStory Then
        ' концевые
    End If
Макросы под заказ и готовый пакет - mtdmacro.ru

6

Re: Как выполнить условие в зависимости от места курсора в документе?

Спасибо еще раз!
Сейчас попробую модернизировать и сообщу, что получилось.

7

Re: Как выполнить условие в зависимости от места курсора в документе?

Вообще, все это мне понадобилось, чтобы осуществить следующее.
Мне хотелось в Word, чтобы после перехода от одной сноски к другой сразу же всплывала ее подсказка.
Советы с этого форума и с других я объединил, добавил к мудрым советам знатоков немного своего бреда, и получился такой макрос.

Sub ПредСноска()
' Определить сначала, где курсор - в области сносок или нет
Dim cX As Long, cY As Long, i As Byte
Dim selrange As Range
Dim footnoterange As Range
Dim selinfootnotes As Boolean

Set selrange = Selection.Range
Set footnoterange = Nothing
On Error Resume Next
Set footnoterange = ActiveDocument.StoryRanges(wdFootnotesStory)
On Error GoTo 0
    If footnoterange Is Nothing Then
        MsgBox "В документе нет сносок"
    Else
        selinfootnotes = selrange.InRange(footnoterange)
        If selinfootnotes Then
            ' Если курсор в тексте сносок, - то следует простой переход к пред. сноске
            Application.Run "GoToPreviousFootnote"
        Else
             ' Если курсор в основном тексте, то следует переход к пред. сноске,
             ' затем находятся координаты курсора, потом указатель мыши ставится на них,
             ' но при помощи цикла и таймера сразу же имитируется шевеление мыши, чтобы всплыла подсказка
             Application.Run "GoToPreviousFootnote"
                ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
                   For i = 0 To 2
                   SetCursorPos cX + i, cY + i
                   Dim Start
                   Start = Timer ' текущее время в секундах
                   Do While Timer < Start + 0.05
                   Loop
                Next i
        End If
    End If
End Sub

В итоге всё действует почти безотказно, особенно, если макросам назначены удобные горячие клавиши.

Еще раз всем спасибо!

8

Re: Как выполнить условие в зависимости от места курсора в документе?

Правда, так как я слабоват в VBA, есть у меня еще маленькие проблемки.
Например, когда пришел к самой первой сноске, надо, чтобы об этом сообщение показалось:
"Это первая сноска в документе!"
Также и для последней.
Есть у меня доки, где полно сносок: и простых, и концевых.
Как сделать в показанном коде?

9

Re: Как выполнить условие в зависимости от места курсора в документе?

Вождь пишет:
yshindin пишет:

...ActiveDocument.StoryRanges...

Мы не ищем легких путей? smile Есть свойство StoryType:

    If Selection.StoryType = wdMainTextStory Then
        ' главная часть
    ElseIf Selection.StoryType = wdFootnotesStory Then
        ' сноски
    ElseIf Selection.StoryType = wdEndnotesStory Then
        ' концевые
    End If

А с учетом этих объектов, мне уже не понадобится вот это:

Dim selrange As Range
Dim footnoterange As Range
Dim selinfootnotes As Boolean

Set selrange = Selection.Range
Set footnoterange = Nothing
On Error Resume Next
Set footnoterange = ActiveDocument.StoryRanges(wdEndnotesStory)

Сразу можно переходить к условному оператору?

10

Re: Как выполнить условие в зависимости от места курсора в документе?

Вот так модернизировал:

Sub СледКонцеваяСноска()
Dim cX As Long, cY As Long, i As Byte
On Error Resume Next
On Error GoTo 0
If Selection.StoryType = wdEndnotesStory Then ' Если курсор в области концевых сносок, подсказки не будет
    Application.Run "GoToNextEndnote"
Else ' Подразумевается, что курсор в основном в основном тексте, - подсказка будет
    Application.Run "GoToNextEndnote"
        ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
            For i = 0 To 2
                SetCursorPos cX + i, cY + i
                Dim Start
                Start = Timer ' текущее время в секундах
                Do While Timer < Start + 0.05
                Loop
            Next i
End If
End Sub

Это нормально для дилетанта?

11

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

Вот так модернизировал:

Sub СледКонцеваяСноска()
Dim cX As Long, cY As Long, i As Byte
On Error Resume Next
On Error GoTo 0
If Selection.StoryType = wdEndnotesStory Then ' Если курсор в области концевых сносок, подсказки не будет
    Application.Run "GoToNextEndnote"
Else ' Подразумевается, что курсор в основном в основном тексте, - подсказка будет
    Application.Run "GoToNextEndnote"
        ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
            For i = 0 To 2
                SetCursorPos cX + i, cY + i
                Dim Start
                Start = Timer ' текущее время в секундах
                Do While Timer < Start + 0.05
                Loop
            Next i
End If
End Sub

Это нормально для дилетанта?

Не понял смысл комментария ("' Подразумевается, что курсор в основном в основном тексте, - подсказка будет") - что такое подсказка? Также неясны GetPoint и цикл For с таймером. А что будет, если в документе нет концевых сносок?

12

Re: Как выполнить условие в зависимости от места курсора в документе?

Уважаемый yshindin!
Действительно, наверное, никто не поймет сразу, что мне требовалось: очень оригинальное требование было у меня.
Сейчас поясню.

13

Re: Как выполнить условие в зависимости от места курсора в документе?

Задача стояла такая.
Как известно, в Word'е штатная команда GoToNextFootnote (и другие такие же) находит следующую сноску. Курсор в этом случае становится перед знаком сноски (это особенно хорошо видно при большом масштабе - 500%. Кстати, так же происходит и с гиперссылками).
Для того, чтобы к этой сноске всплыла подсказка, надо навести на нее указатель мыши.
Об этом все, конечно, знают.
У меня в доках много ссылок, сносок и примечаний.
Мне захотелось мобильности, а именно:
1. Чтобы после перехода к след. сноске по команде GoToNextFootnote сразу же всплывала ее подсказка, а не дожидалась наведения указателя мыши.
Я искал на форумах, как это сделать, но смогли только подсказать, как найти координаты курсора и переместить на них указатель мыши.
Подсказка от этого не хотела всплывать. Она надрессирована лишь на наведение мыши. Что было делать? Надо было шевельнуть мышь.
Вот я ее как мог и подвинул: по таймеру велел сместиться на три пикселя вниз и вправо. Оказалось, что эта мультипликация подействовала: подсказки всплывают хорошо.
Другого способа мне не посоветовали.
Я знаю, что есть там какие-то события мыши... Но не знаю, как воспользоваться ими.

2. Есть также команда ViewFootnoteArea, которая перемещает курсор туда-сюда между знаками сноски в основном тексте и знаками сноски в тексте сносок. Но в основном тексте подсказка бывает, а в тексте сносок ее нет. Поэтому понадобилось условие, которое Вы мне подсказали.

Все это имеет эффект только в том случае, если для указанных команд назначены удобные горячие клавиши. У меня они очень удобные (буквы условно русские):

ПредСноска            Alt+Щ        ПредКонцевая            Alt+З
СноскиПростые        Alt+Д        СноскиКонцевые        Alt+Ж
СледСноска            Alt+Ю        СледКонцевая            Alt+.

С такими клавишами просмотр и редактирование сноскок становится очень удобным.
Примерно также и для гиперссылок сделано.
Еще раз - спасибо всем! Я доволен.

14

Re: Как выполнить условие в зависимости от места курсора в документе?

Если хотите, могу для пробы прислать док, в котором много сносок и уже назначены эти горячие клавиши.

15

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

Правда, так как я слабоват в VBA, есть у меня еще маленькие проблемки.
Например, когда пришел к самой первой сноске, надо, чтобы об этом сообщение показалось:
"Это первая сноска в документе!"
Также и для последней.
Есть у меня доки, где полно сносок: и простых, и концевых.
Как сделать в показанном коде?

Прошу не забыть про это и тоже подсказать.

16

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

...
когда пришел к самой первой сноске, надо, чтобы об этом сообщение показалось:
"Это первая сноска в документе!"
...

Кроме перехода к очередной концевой сноске (как в вашем примере), вы можете просто перебирать сноски как объекты в семействе - ниже пример. По поводу освоения VBA-кода - старайтесь в макросе достичь лишь того, что вам абсолютно необходимо и делайте это наиболее наглядно.
Как сказал мой сослуживец: "Давайте писать МИКРОСЫ".  :}}

Sub LoopEndnotes()
Dim en As Endnote
For Each en In ActiveDocument.Endnotes
    If en.Index = 1 Then
        en.Range.Select
        MsgBox "First endnote found"
    End If
Next
End Sub

17

Re: Как выполнить условие в зависимости от места курсора в документе?

С Добрым утром!
С Праздником!
Очень рад помощи!
Но, ведь этот макрос находит первую концевую сноску в области сносок.
Какой смысл ее искать, если она там и так стоит первая, да еще и описание тут же?
Логика моего вопроса была такая:
1. Я перехожу в тексте от сноски к сноске.
2. Благодаря усовершенствованному переходу сразу же вижу всплывающие подсказки.
3. При необходимости перепрыгиваю к знаку текущей сноски в область сносок или обратно (той же командой).
4. А вот когда достиг первой сноски в основном тексте, Ваш макрос и должен предупредить, что дальше переходить некуда, потому что это самая первая сноска (или, соответственно, последняя).

18

Re: Как выполнить условие в зависимости от места курсора в документе?

То есть, так должно быть:
Сначала должно проверяться условие - есть ли вообще сноски. (Это Вы сразу написали, я помню.)
Потом при переходе по сноскам должно проверяться условие: не первая ли это сноска (если идешь вверх) или не последняя это сноска (если идешь вниз). И выдаваться сообщение, что дальше искать не надо - бесполезно нажимать команду.
Пожалуйста, не так ли?

19

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

...
при переходе по сноскам должно проверяться условие: не первая ли это сноска (если идешь вверх) или не последняя это сноска (если идешь вниз). И выдаваться сообщение
...

Если я правильно понял, вы хотите пользоваться макросом Word "GoToNextEndnote", но при этом проверять, не последняя ли это сноска, в том месте, куда перешли. Как вариант - перебрать все сноски и выяснить, относится ли референс очередной сноски к тому месту в основном тексте, куда перешли. Если да, и если это последняя сноска, то сообщить. Вот пример ниже (для случая перехода к следующей концевой сноски).

Sub NextEndnote()
Dim en As Endnote
Dim en_cnt As Long
Dim enr As Range
en_cnt = ActiveDocument.Endnotes.Count
If en_cnt > 0 Then
    Application.Run "GoToNextEndnote"
    Set enr = Selection.Range
    For Each en In ActiveDocument.Endnotes
        If en.Reference.Start = enr.Start Then
            If en.Index = en_cnt Then
                MsgBox "it is the last endnote"
            End If
        End If
    Next
End If
End Sub

20

Re: Как выполнить условие в зависимости от места курсора в документе?

Пробую и проверяю...

21

Re: Как выполнить условие в зависимости от места курсора в документе?

Да! Хорошо - годится такой вариант для концевой сносочки!
Щас докумекаю, как для других сносок переписать и дополню своими циклами для подсказок.
Сообщу.
Пока - спасибо еще раз!

22

Re: Как выполнить условие в зависимости от места курсора в документе?

yshindin пишет:

...перебрать все сноски и выяснить...

Да уж. Зачем вообще использовать Application.Run, и лезть в команды Word, когда есть обычный код, выполняющий то же самое? Используйте Selection.GoTo или Range.Goto. Вот небольшой пример всех нужных вам опций:

Sub A()
    ' текущая область
Dim R As Range
    Set R = Selection.Range
    ' переход к следующей сноске
    Selection.GoTo What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1
    ' никуда не перешли
    If (R.Start <> Selection.Start) Or (R.End <> Selection.End) Then
    ElseIf Selection.Characters.First.Footnotes.Count <= 0 Then
        MsgBox "Впереди нет сносок"
        Exit Sub
    End If
    ' текущая сноска
Dim F As Footnote
    Set F = Selection.Characters.First.Footnotes(1)
    ' наличие следующей сноски
    Set R = Selection.Range.GoTo(What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1)
    If R.Start <= Selection.Start Then
        MsgBox "Это последняя сноска"
    End If
End Sub
Макросы под заказ и готовый пакет - mtdmacro.ru

23

Re: Как выполнить условие в зависимости от места курсора в документе?

Уважаемый, Вождь!
Это не yshindin "полез в команды Word", а я. Вспомните, с чего началась тема:

auto-teacher пишет:

Плохо владею VBA, не знаю объектов Word...

Цель есть, задача поставлена, а инструменты в темной комнате лежат.
Сейчас вы оба меня так загрузили (в хорошем смысле слова), что я не знаю, какие варианты выбрать. Прихожу к выводу: для обычных сносок надо выбрать один вариант, для концевых - другой, а для гиперссылок - третий, чтобы не пропадали ваши советы.
Между прочим, красоту короткого и ясного кода я умею ценить.
Но получается, что я не смогу без вас в такую длинную макрокоманду с условиями вставить правильно рекомендуемые операторы. Да еще и с обработкой возможных ошибок надо бы.
Я могу это сделать только на обычном русском языке.
Сейчас еще раз изложу свои пожелания. Может быть, вы и вставите ваши советы вместо простого языка.

24

Re: Как выполнить условие в зависимости от места курсора в документе?

Уважаемые программисты!

Фактически с вашими советами по моей теме уже почти все сделано (и я тащусь от счастья!), но вы же сами и недовольны, что какого-то блеска в коде не хватает.
Задачу о подсказках я выше подробно описывал, поэтому сейчас подробнее скажу об условиях (о ветвях, наверное) выполнения.
Цель: использовать в документе с большим количеством сносок, ссылок и примечаний три команды Word или их менее сложные заменители посредством горячих клавиш.
На примере обычных сносок (потому что переделать для концевых сносок, у меня мозгов должно хватить) опишу еще раз.
Так как такие команды есть, то я и взял их на вооружение, но с желанием усовершенствовать.

1. GoToPreviousFootnote - ПредСноска - перескок к предыдущей сноске.
Нажимаю Alt+Щ.
Должны выполняться такие условия:
• Если обычных сносок в документе нет - ничего не происходит, кроме сообщения об этом, которое после появления (на секундочку) лучше само бы и закрылось (не знаю, есть ли такая фишка с таймером).
• Если курсор в основном тексте, то курсор перескакивает к знаку предыдущей сноски, и подсказка (после моей мультипликации) всплывает,
а Если курсор в области сносок - курсор просто перескакивает выше к знаку пред. сноски (здесь мультипликация не нужна, и выделять текст сноски ни к чему - именно так делает штатная команда).
• Если сноска самая первая, - об этом сообщается в окне, но немного не так, как вы написали.
По вашим советам сначала появлялось сообщение, а после нажатия "ОК" всплывала подсказка. Это же неправильно? Сообщение должно появляться только после следующей попытки искать ниже последней сноски: "Успокойся, дружок! Это была последняя сноска!" Так будет логичней.

2. ViewFootnoteArea - СноскиОбычные - перескок между знаками текущей сноски из области сносок в основной текст или наоборот (именно так делает команда).
Нажимаю Alt+Д.
Если сносок нет - сообщение об этом, которое лучше бы через секунду само и исчезло.
Здесь надо сделать пояснение. В режиме разметки эта команда очень удобно делает перескок именно между знаками текущей сноски - туда-сюда. А вот в режиме Черновика для области сносок открывается подокно: и если в нем сделать переход к другой сноске, то потом ViewFootnoteArea подокно закрывает и курсор скачет куда попало.

3. GoToNextFootnote - СледCноска - перескок к следующей сноске.
Нажимаю Alt+Ю.
И все также, как для ПредСноска.

Что касается гиперссылок, к которым у меня с вашей помощью (с моей мультипликацией) также стали сами загораться подсказки, то хотелось бы также немного добавить операторов в макрос.
PrevField - ПредГиперссылка - перескок к предыдущей гиперссылке.
Если в доке не гиперссылок - сообщение об этом, а Если пришли к первой, то сообщение об этом и предложение пройтись этой же командой с самого низу (по кругу, как это устроено для исправлений), например: "Это была первая гиперссылка в тугаменте. Не желаете ли, Сэр, начать просмотр гиперссылок с конца?"

Из предложенных вами, уважаемые знатоки, кодов в настоящий момент я работаю с такими опробованными макросами:

Sub СноскиОбычные()
Set footnoterange = Nothing
On Error Resume Next
Set footnoterange = ActiveDocument.StoryRanges(wdFootnotesStory)
On Error GoTo 0
If footnoterange Is Nothing Then
    MsgBox "В документе нет обычных сносок"
Else
        Application.Run "ViewFootnoteArea"
End If
End Sub
Sub СледСноска()
'Определить сначала, где курсор - в области концевых сносок или нет
Dim cX As Long, cY As Long, i As Byte
Dim selrange As Range
Dim footnoterange As Range
Dim selinfootnotes As Boolean

Set selrange = Selection.Range
Set footnoterange = Nothing
On Error Resume Next
Set footnoterange = ActiveDocument.StoryRanges(wdFootnotesStory)
On Error GoTo 0
If footnoterange Is Nothing Then
    MsgBox "В документе нет обычных сносок"
Else
    selinfootnotes = selrange.InRange(footnoterange)
    If selinfootnotes Then
        Application.Run "GoToNextFootnote"
    Else
        Application.Run "GoToNextFootnote"
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
               For i = 0 To 2
               SetCursorPos cX + i, cY + i
               Dim Start
               Start = Timer ' текущее время в секундах
               Do While Timer < Start + 0.05
               Loop
            Next i
    End If
End If
End Sub
Sub СледСноска()
' Выбран другой вариант кода. См. ниже
Dim cX As Long, cY As Long, i As Byte
On Error Resume Next
On Error GoTo 0
If Selection.StoryType = wdFootnotesStory Then ' Если курсор в области простых сносок, подсказки не будет
    Application.Run "GoToNextFootnote"
Else ' Подразумевается, что курсор в основном тексте, - подсказка будет
    Application.Run "GoToNextFootnote"
        ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
            For i = 0 To 2
                SetCursorPos cX + i, cY + i
                Dim Start
                Start = Timer ' текущее время в секундах
                Do While Timer < Start + 0.05
                Loop
            Next i
End If
End Sub
Sub СледующаяСноска()
Dim cX As Long, cY As Long, i As Byte
    If Selection.Information(wdInFootnote) Then
        Application.Run "GoToNextFootnote"
    Else ' Если курсор в основном тексте
        Application.Run "GoToNextFootnote"
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
                For i = 0 To 2
                    SetCursorPos cX + i, cY + i
                    Dim Start
                    Start = Timer ' текущее время в секундах
                    Do While Timer < Start + 0.05
                    Loop
                Next i
    End If
End Sub
Sub СледКонцеваяСноска()
' С условиями перехода в зависимости от области текста и сообщением о последней найденной концевой сноске
Dim cX As Long, cY As Long, i As Byte
Dim en As Endnote
Dim en_cnt As Long
Dim enr As Range
en_cnt = ActiveDocument.Endnotes.Count
On Error Resume Next
On Error GoTo 0
If Selection.StoryType = wdEndnotesStory Then ' Если курсор в области концевых сносок, после перехода подсказки не ожидается
    Application.Run "GoToNextEndnote"
Else ' Следовательно, подразумевается, что раз курсор не в области сносок, значит, - в основном тексте, - подсказка должна будет всплыть, как дрессированный дельфин
    If en_cnt > 0 Then ' Вариант перехода к концевой сноске с имитацией движения мыши
        Application.Run "GoToNextEndnote"
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range ' Находим координаты курсора...
                For i = 0 To 2 ' ... даем их указателю мыши...
                    SetCursorPos cX + i, cY + i
                    Dim Start  ' ... и сдвигаем этим циклом по таймеру указатель вправо-вниз для имитации движения.
                    Start = Timer ' текущее время в секундах
                    Do While Timer < Start + 0.05
                    Loop
                Next i
        Set enr = Selection.Range
        For Each en In ActiveDocument.Endnotes
            If en.Reference.Start = enr.Start Then
                If en.Index = en_cnt Then
                    MsgBox "Дальше можно не искать! Это последняя концевая сноска в документе!"
                End If
            End If
        Next
    End If
End If
End Sub

Если тут что-то лишнее, то я уж и не разберусь.

Для гиперссылок:

Sub СледГиперссылка()
    Dim cX As Long, cY As Long, i As Byte
    Selection.GoTo What:=wdGoToField, Which:=wdGoToNext, Count:=1, Name:="HYPERLINK"
    ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
       For i = 0 To 2  ' Хорошо всплывают при масштабе 100%. Для больших масштабов надо двигать на 15
       SetCursorPos cX + i, cY + i
       Dim Start
       Start = Timer ' текущее время в секундах
       Do While Timer < Start + 0.1
       Loop
    Next i
End Sub

Если вы мне не вставите их в желаемые условия и ветви, то я не скоро изменю и буду пока как есть пользоваться.

25

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

... кроме сообщения об этом, которое после появления (на секундочку) лучше само бы и закрылось (не знаю, есть ли такая фишка с таймером).
...

Вот попробуйте модуль в прицепе (Messaging.bas) - включите его в дерево вашего VBA-проекта.
Вместо обычного оператора

MsgBox "текст"

используйте функцию MsgboxOKDrop, напр.,

lRetVal = MsgboxOKDrop("Informational message subheading (first line)" & vbCrLf & _
    "Informational message details ...", vbOKOnly + vbInformation, "Message title", interval)

где "interval" - это число миллисекунд, после истечении которого окно сообщения автоматом закроется (или если вы сами закроете окно). Остальные параметры, как в обычном MsgBox.

Пример использования функции см. в конце текста модуля (TestMessage - попробуйте его запустить). Сам модуль старый (2000 г.), автор - Andrew Baker. Думаю, на современных Windows и Office должно сработать.

Post's attachments

Messaging.bas 3.42 Кб, 4 скачиваний с 2016-11-08 

You don't have the permssions to download the attachments of this post.

26

Re: Как выполнить условие в зависимости от места курсора в документе?

С добрым утром!
Всплывающее сообщение, которое само гаснет через заданное время, да еще в котором можно делать перевод строки - это классная штучка!
Я его опробовал сперва на холостом доке, а теперь с уверенностью добавлю модуль в главный шаблон.

Очень рад, что Вы, yshindin, его откопали, а автор - Andrew Baker - молодец!

27

Re: Как выполнить условие в зависимости от места курсора в документе?

yshindin! Теперь как правильно: весь этот макрос должен включаться каждый раз вместо MsgBox?
Или основную часть можно для всех будущих сообщений наверху расположить?

Sub ВременноеВсплывающееОкно()
    Dim lRetVal As VbMsgBoxResult
    Dim interval As Long 'message will display this time (msec) unless it is stopped by clicking [OK]
    interval = 2000
    lRetVal = MsgboxOKDrop("Информационное сообщение (первая строка)" & vbCrLf & _
    "Детали информационного сообщения ...", vbOKOnly + vbInformation, "Заголовок сообщения", interval)
    '''Debug.Print lRetVal
End Sub

28

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

...
Теперь как правильно: весь этот макрос должен включаться каждый раз вместо MsgBox?
Или основную часть можно для всех будущих сообщений наверху расположить?
...

Ну, это вам решать... На мой вкус, когда макрос достигает крайних сносок, следует выдавать сообщение с автозакрытием, а для критических сообщений (завершающих исполнение макроса) можно рекомендовать обычный MsgBox.

29

Re: Как выполнить условие в зависимости от места курсора в документе?

Я не про это...
Вот, допустим, ВСЕ, ЧТО НИЖЕ - это макрос с двумя сообщениями. Со вторым все ясно.
А первое - самозакрывающееся сообщение - состоит из двух частей (красной и зеленой).
Я именно про это спрашиваю: каждый раз надо и красное и зеленое включать в качестве сообщения или можно красную часть где-нибудь для всех описать (как бы насовсем)?

Sub СледующаяСноска()
Dim cX As Long, cY As Long, i As Byte
If ActiveDocument.Footnotes.Count = 0 Then

Dim lRetVal As VbMsgBoxResult
Dim interval As Long 'message will display this time (msec) unless it is stopped by clicking [OK]
        interval = 3000

lRetVal = MsgboxOKDrop("Обычных сносок еще никто не вставил!" & vbCrLf & _
        "Возможно, есть концевые сноски!", vbOKOnly + vbInformation, "Обычных сносок нет!", interval)

    ElseIf Selection.Information(wdInFootnote) Then
        Application.Run "GoToNextFootnote"
    Else ' Если курсор в основном тексте
        Application.Run "GoToNextFootnote"
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
                For i = 0 To 2
                    SetCursorPos cX + i, cY + i
                    Dim Start
                    Start = Timer ' текущее время в секундах
                    Do While Timer < Start + 0.05
                    Loop
                Next i
Dim F As Footnote
    Set F = Selection.Characters.First.Footnotes(1)
    ' наличие следующей сноски
    Set R = Selection.Range.GoTo(What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1)
    If R.Start <= Selection.Start Then

        MsgBox "Это последняя сноска"

    End If
    End If
End Sub

30

Re: Как выполнить условие в зависимости от места курсора в документе?

auto-teacher пишет:

...
А первое - самозакрывающееся сообщение - состоит из двух частей (красной и зеленой).
Я именно про это спрашиваю: каждый раз надо и красное и зеленое включать в качестве сообщения или можно красную часть где-нибудь для всех описать (как бы насовсем)?
...

Красная часть - это операторы объявления переменных и присвоения начального значения переменной  interval  - это можно разместить один раз в начале подпрограммы

31

Re: Как выполнить условие в зависимости от места курсора в документе?

Даже не верится, что можно считать удовлетворенными мои требования, заявленные в начале темы!
Вот до чего вы меня довели:

Sub СледующаяСноска()
Dim cX As Long, cY As Long, i As Byte

    ' Общая часть гаснущих сообщений
Dim lRetVal As VbMsgBoxResult
Dim interval As Long 'message will display this time (msec) unless it is stopped by clicking [OK]
interval = 4000

If ActiveDocument.Footnotes.Count = 0 Then

    ' Первое гаснущее сообщение
        lRetVal = MsgboxOKDrop("Обычных сносок еще никто не вставил!" & vbCrLf & _
        "Возможно, есть концевые сноски!", vbOKOnly + vbInformation, "Отсутствие сносок в тексте", interval)

    ElseIf Selection.Information(wdInFootnote) Then
        Application.Run "GoToNextFootnote"
    Else ' Если курсор в основном тексте
        Application.Run "GoToNextFootnote"
            ActiveWindow.GetPoint cX, cY, 0&, 0&, Selection.Range
                For i = 0 To 2
                    SetCursorPos cX + i, cY + i
                    Dim Start
                    Start = Timer ' текущее время в секундах
                    Do While Timer < Start + 0.05
                    Loop
                Next i
Dim F As Footnote
    Set F = Selection.Characters.First.Footnotes(1)
    ' наличие следующей сноски
    Set R = Selection.Range.GoTo(What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1)
    If R.Start <= Selection.Start Then

    ' Второе гаснущее сообщение
        lRetVal = MsgboxOKDrop("Это последняя сноска в тексте!" & vbCrLf & _
        "Дальше можно не искать!", vbOKOnly + vbInformation, "Проверка сносок", interval)

    End If
    End If
End Sub

Сам модуль Messaging импортирован и размещен, как велено, в разделе Modules главного шаблона normal.dotm там же, где и NewMacros.

Так я и программистом стану... на старости лет!

32

Re: Как выполнить условие в зависимости от места курсора в документе?

Однако, не зря говорится: "Улучшать можно до бесконечности!"
Так и тут: если курсор находится выше первой сноски, то при попытке перейти к пред. сноске макрос как слепой котенок молча тыкается и выполняет втихаря ненужный код.
А если курсор находится ниже последней сноски, то при попытке перейти к след. сноске вообще    выдается сообщение об ошибке.

33

Re: Как выполнить условие в зависимости от места курсора в документе?

Модератору: срочно разжалуйте меня в сержанты! Рано мне еще звездочки крепить!

34

Re: Как выполнить условие в зависимости от места курсора в документе?

yshindin пишет:

Красная часть - это операторы объявления переменных и присвоения начального значения переменной  interval  - это можно разместить один раз в начале подпрограммы

Dim lRetVal As VbMsgBoxResult
Dim interval As Long 'message will display this time (msec) unless it is stopped by clicking [OK]
        interval = 3000

lRetVal = MsgboxOKDrop("Первая строка сообщения." & vbCrLf & _
        "Вторая строка сообщения.", vbOKOnly + vbInformation, "Заголовок окна", interval)

Так как теперь я во многих макросах стал использовать гаснущие сообщения (при помощи модуля Messaging), возник вопрос: можно ли красную часть - объявление переменных и присвоение значений - размещать не в каждой подпрограмме, где должно быть гаснущее сообщение, а один раз - в самом начале модуля с моими макросами NewMacros или в модуле Messaging?
А то слишком часто его приходится повторять.

35

Re: Как выполнить условие в зависимости от места курсора в документе?

Попробовал применить описание Public вместо Dim, и вроде бы подействовало.

36

Re: Как выполнить условие в зависимости от места курсора в документе?

Вождь пишет:

Вот небольшой пример всех нужных вам опций:

Sub A()
    ' текущая область
Dim R As Range
    Set R = Selection.Range
    ' переход к следующей сноске
    Selection.GoTo What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1
    ' никуда не перешли
    If (R.Start <> Selection.Start) Or (R.End <> Selection.End) Then
    ElseIf Selection.Characters.First.Footnotes.Count <= 0 Then
        MsgBox "Впереди нет сносок"
        Exit Sub
    End If
    ' текущая сноска
Dim F As Footnote
    Set F = Selection.Characters.First.Footnotes(1)
    ' наличие следующей сноски
    Set R = Selection.Range.GoTo(What:=wdGoToFootnote, Which:=wdGoToNext, Count:=1)
    If R.Start <= Selection.Start Then
        MsgBox "Это последняя сноска"
    End If
End Sub

Это поиск и определение последней сноски при движении вниз. А если то же самое, но вверх? Что надо изменить?