Разбираем по кусочкам новый «ленточный» интерфейс Word 2007. Здесь нет и не будет советов о том, как его сделать похожим на Word 2003. Только усовершенствования уже существующего. Также приглашаю посетить мой блог, посвященный работе с макросами в Word.

Напоминаю, что все коды программ, приведенных в блоге, вы используете на свой страх и риск. Не забывайте создавать резервные копии.

понедельник, 28 июня 2010 г.

Элемент dropDown — выпадающий список

Как раз раздумывал над очередной темой, как её подсказала сама жизнь: просьба рассказать об элементе comboBox и сетования одного из посетителей WordExpert на неудобную работу с автотекстом. Постараюсь убить двух зайцев сразу.
Итак, задача: сформировать список из элементов автотекста, содержащихся в шаблоне, на котором основан документ. При выборе элемента из списка, вставлять его в документ.
Как всегда, начнём с XML-схемы. На ленту поместим группу "Автотекст" с выпадающим списком и кнопкой для обновления этого списка, если при работе с документом мы добавим элемент автотекста шаблон. В качестве списка я буду использовать не comboBox, а dropDown. Они абсолютно идентичны, но comboBox позволяет принимать текст, введённый пользователем. Нам это не нужно, поэтому используем dropDown.
1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="RibbonLoading">
3 <ribbon startFromScratch="false">
4 <tabs>
5 <tab idMso="TabHome">
6 <group id="grAutoText" label="Автотекст">
7 <dropDown id="ddAutoText"
8 onAction="ddAutoText_onAction"
9 getItemLabel="ddAutoText_getItemLabel"
10 getItemSupertip="ddAutoText_getItemSupertip"
11 getItemCount="ddAutoText_getItemCount"
12 getItemID="ddAutoText_getItemID"
13 getSelectedItemIndex="ddAutoText_getSelectedItemIndex" >
14
15 </dropDown>
16 <button id="btnRefresh"
17 label="Обновить"
18 imageMso="RecurrenceEdit"
19 onAction="btnRefresh_onAction" />
20 </group>
21 </tab>
22 </tabs>
23 </ribbon>
24 </customUI>

Пояснения к атрибутам элемента dropDown.

  • onAction — процедура, вызываемая при нажатии на пункте списка

  • getItemLabel — процедура для задания текста элемента списка

  • getItemSupertip — процедура для задания текста расширенной подсказки элемента списка

  • getItemCount — процедура для задания количества элементов списка

  • getItemID — процедура для задания идентификаторов элементво списка (необязательная)

  • getSelectedItemIndex — процедура для выбора определённого элемента списка


Кнопка совершенно обычная и никаких трудностей у вас не должна вызвать, если вы дошли до создания списка. Если же возникли трудности, то ознакомьтесь с этой заметкой. Сохраняем шаблон и открываем его в Word, не забыв перед этим получить заготовку для кода VBA. Для этого в программе Ribbon XML Editor, которую я настоятельно рекомендую к использованию, предусмотрена специальная функция : вы можете автоматически получить заготовки для всех динамических атрибутов, указанных в XML-схеме и сохранить их в виде модуля *.bas для последующего импорта в документ.
Теперь код VBA. Открываем шаблон в Word, импортируем сохранённый модуль с процедурами ленты и доводим его до такого состояния:
1 Option Explicit
2 Dim tmp As Template
3 Dim bb As BuildingBlocks
4 Dim MyRibbon As IRibbonUI
5
6 ' (компонент: customUI, атрибут: onLoad), 2007
7 Sub RibbonLoading(ribbon As IRibbonUI)
8 Set tmp = ActiveDocument.AttachedTemplate
9 Set bb = tmp.BuildingBlockTypes(wdTypeAutoText).Categories("Общие").BuildingBlocks
10 Set MyRibbon = ribbon
11 End Sub
12
13 'ddAutoText (компонент: dropDown, атрибут: onAction), 2007
14 Sub ddAutoText_onAction(control As IRibbonControl, selectedId As String, selectedIndex As Integer)
15 bb(selectedIndex).Insert Where:=Selection.Range, RichText:=True
16 End Sub
17
18 'ddAutoText (компонент: dropDown, атрибут: getItemLabel), 2007
19 Sub ddAutoText_getItemLabel(control As IRibbonControl, index As Integer, ByRef label)
20 label = bb(index + 1).Name
21 End Sub
22
23 'ddAutoText (компонент: dropDown, атрибут: getItemSupertip), 2007
24 Sub ddAutoText_getItemSupertip(control As IRibbonControl, index As Integer, ByRef superTip)
25 superTip = bb(index + 1).Value
26 End Sub
27
28 'ddAutoText (компонент: dropDown, атрибут: getItemCount), 2007
29 Sub ddAutoText_getItemCount(control As IRibbonControl, ByRef count)
30 ' Dim tmp As Template
31 count = bb.count
32 End Sub
33
34 'ddAutoText (компонент: dropDown, атрибут: getItemID), 2007
35 Sub ddAutoText_getItemID(control As IRibbonControl, index As Integer, ByRef id)
36 id = bb(index + 1).Name
37 End Sub
38
39 'ddAutoText (компонент: dropDown, атрибут: getSelectedItemIndex), 2007
40 Sub ddAutoText_getSelectedItemIndex(control As IRibbonControl, ByRef index)
41 index = 0
42 End Sub
43
44 'btnRefresh (компонент: button, атрибут: onAction), 2007
45 Sub btnRefresh_onAction(control As IRibbonControl)
46 MyRibbon.InvalidateControl "ddAutoText"
47 End Sub

В результате получим вот такой симпатичный список

В конце, несколько замечаний. Как видно из кода, для выборки элементов автотекста используется только одна категория: "Общие". Если автотекст распределён по нескольким категориям, они не будут видны. Если нужно распределить по категориям, то либо создавать столько списков, сколько в шаблоне категорий автотекста, либо использовать не список, а динамическое меню. Естественно это потребует переделки кода.
Пример шаблона

3 коммент.:

Анонимный комментирует...

Большое спасибо, то что нужно!

p.s.
В процедуре ddAutoText_onAction опечатка, для корректной работы должно быть:

bb(selectedIndex + 1).Insert Where:=Selection.Range, RichText:=True

alex.viter комментирует...

Совершенно верно. В приложенном файле эта ошибка исправлена. Это происходит, потому что нумерация пунктов меню начинается с нуля, а элементы коллекции BuildingBlocks нумеруются, начиная с единицы

Rolf комментирует...

Спасибо вам, Александр! От того самого посетителя Word Expert!
Только мне потребовалось полгода понятьзачем надо кнопочка обновить автотекст! :)Ещё полгода буду создавать свой шаблон!
На кого же вы нас покинули в своей Канаде