Консультация № 147542
17.10.2008, 15:05
0.00 руб.
17.10.2008, 17:18
0 5 1
Коллеги. Необходима помощь по настройке списка закладок в пользовательском меню по положению их в тексте документа.
Итак, есть свой пункт меню (код ниже) для Word 2003, который содержит вложенное меню со списком команд. Первая команда предназначена для сортировки. Вторая и последующая команды представляют собой список имен закладок (имеющихся в документе). Эти закладки по умолчанию отсортированы по алфавиту.

Задача: по клику на команде "Сортировать по положению" список закладок в меню обновляется в соответствии с их размещением в тексте документа. У команды появляется флажок (иконка), показывающая пользователю, что установлена эта сортировка. Повторный клик на команде восстанавливает сортировку по алфавиту и убирает иконку.

Для того, чтобы получить список по положению, нужно заменить оператор "For Each bm In ActiveDocument.Bookmarks" на "For Each bm In ActiveDocument.Range.Bookmarks". Но вот как это организовать в коде по вызову команды OnAction - я не могу сообразить. Что именно написать в вызываемой по OnAction процедуре? Как реализовать такую сортировку по выбору команды меню?
Подскажите пожалуйста.
Спасибо за помощь.

Приложение:
Sub MyMenu()
Dim cb As CommandBar
Dim cbP As CommandBarPopup
Dim cbbTop As CommandBarButton
Dim cbbBM As CommandBarButton
Dim bm As Bookmark

Set cb = CommandBars.ActiveMenuBar

Set cbP = CommandBars.FindControl(Tag:="Restore")
If Not cbP Is Nothing Then
cbP.Delete
End If

Set cbP = cb.Controls.Add(Type:=msoControlPopup, Before:=cb.Controls.Count + 1)
With cbP
.Caption = "Мое меню"
.Tag = "Restore"
.BeginGroup = True
End With

'Добавляем команду в самый верх меню
Set cbbTop = cbP.Controls.Add(Type:=msoControlButton)

'?????????Здесь нужен обработчик!!!
With cbbTop
.Caption = "Сортировать по положению"
.OnAction = ""
End With

'Другие команды в меню
For Each bm In ActiveDocument.Bookmarks 'сортировка закладок по алфавиту
Set cbbBM = cbP.Controls.Add(Type:=msoControlButton)
With cbbBM
.Caption = bm.Name
.Style = msoButtonCaption
End With
Next bm

Set cb = Nothing
Set cbbTop = Nothing
Set cbbBM = Nothing
End Sub

Обсуждение

Неизвестный
18.10.2008, 15:26
общий
это ответ
Здравствуйте, Кокин Антон Вадимович!
Вам необходимо объявить переменную для хранения выбранного пользователем способа сортировки (напр. BookmarkOnRange As boolean)
Для замены порядка следования команд меню необходимо его перерисовать, а в коде прорисовки использовать значение этой переменной.
В Вашем случае можно для выбора коллекции в зависимости от виде сортировки воспользоваться оператором Iif.
Для обработки команды меню каждой команде устанавливается свойство OnAction, которое содержит название процедуры, выполняемой при нажатии пункта меню.
Процедура для изменения типа меню должна менять значение переменной BookmarkOnRange и вызывать создание меню заново.


Приложение:
'-----=====добавляем переменную для хранения типа меню
Dim BookmarkOnRange As Boolean
'-----=====

Sub MyMenu()
Dim cb As CommandBar
Dim cbP As CommandBarPopup
Dim cbbTop As CommandBarButton
Dim cbbBM As CommandBarButton
Dim bm As Bookmark

Set cb = CommandBars.ActiveMenuBar

Set cbP = CommandBars.FindControl(Tag:="Restore")
If Not cbP Is Nothing Then
cbP.Delete
End If

Set cbP = cb.Controls.Add(Type:=msoControlPopup, Before:=cb.Controls.Count + 1)
With cbP
.Caption = "Мое меню"
.Tag = "Restore"
.BeginGroup = True
End With

'Добавляем команду в самый верх меню
Set cbbTop = cbP.Controls.Add(Type:=msoControlButton)

'?????????Здесь нужен обработчик!!!
With cbbTop
'-----===== меняем название кнопки в зависимости от типа меню
Iif(BookmarkOnRange, .Caption = "Сортировать по положению", .Caption = "Сортировать по алфавиту")
'-----===== обработчик задается именем процедуры
.OnAction = "ChangeMenuRange"
End With

'Другие команды в меню
For Each bm In ActiveDocument.Bookmarks 'сортировка закладок по алфавиту
'-----=====перебираем закладки в нужном порядке
For Each bm In Iif(BookmarkOnRange, ActiveDocument.Range.Bookmarks , ActiveDocument.Bookmarks)
Set cbbBM = cbP.Controls.Add(Type:=msoControlButton)
With cbbBM
.Caption = bm.Name
.Style = msoButtonCaption
End With
Next bm

Set cb = Nothing
Set cbbTop = Nothing
Set cbbBM = Nothing
End Sub

'-----===== а это обаботчик нажатия пункта меню
Sub ChangeMenuRange
'-----=====меняем тип сортирвки меню
BookmarkOnRange = not BookmarkOnRange
'-----===== и перерисовываем меню
MyMenu
End Sub
Неизвестный
20.10.2008, 17:29
общий
Alec, хочу уточнить вопрос: оператор Iif возвращает булево значение. Так? То есть строку с этим оператором надо записать так:
Код:
 .Caption = IIf(bBkmOnRange, .Caption = "Сортировать по положению", .Caption = "Сортировать по алфавиту") 
?
Однако у меня наименование принимает именно булево значение. Либо я не так делаю...
И что именно означает ваше
'?????????Здесь нужен обработчик!!!
? Нужен код?
Спасибо.
Неизвестный
21.10.2008, 16:23
общий
Все сделал и для этого макроса все работает как положено. Но есть другой код, где все работает в шаблоне, но не в документе с подключенным шаблоном. Создам новый вопрос. Спасибо.
Неизвестный
23.10.2008, 15:07
общий
Да, что-то намудрил... Все правильно, думал об одном, писал другое. Здесь можно воспользоваться If..else..end if, тогда вместо
Iif(BookmarkOnRange, .Caption = "Сортировать по положению", .Caption = "Сортировать по алфавиту")
нужно написать
If BookmarkOnRange then
.Caption = "Сортировать по положению"
else
.Caption = "Сортировать по алфавиту"
end if
или

.Caption = Iif(BookmarkOnRange, "Сортировать по положению", "Сортировать по алфавиту")

Надеюсь моя ошибка не сильно помешала, приношу свои извинения.
PS.
'?????????Здесь нужен обработчик!!! - это оставшийся Ваш комментарий
Неизвестный
23.10.2008, 15:12
общий
Alec, я разобрался (хоть и не без труда, но так и лучше для понимания) и ваш совет ОЧЕНЬ мне помог. БОльшое спасибо. Без него я бы думал еще дольше. К тому же узнал о новой и полезной функции.
Форма ответа