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

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

Как раз раздумывал над очередной темой, как её подсказала сама жизнь: просьба рассказать об элементе comboBox и сетования одного из посетителей WordExpert на неудобную работу с автотекстом. Постараюсь убить двух зайцев сразу.
Итак, задача: сформировать список из элементов автотекста, содержащихся в шаблоне, на котором основан документ. При выборе элемента из списка, вставлять его в документ.
Как всегда, начнём с XML-схемы. На ленту поместим группу "Автотекст" с выпадающим списком и кнопкой для обновления этого списка, если при работе с документом мы добавим элемент автотекста шаблон. В качестве списка я буду использовать не comboBox, а dropDown. Они абсолютно идентичны, но comboBox позволяет принимать текст, введённый пользователем. Нам это не нужно, поэтому используем dropDown.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="RibbonLoading">
 <ribbon startFromScratch="false">
  <tabs>
   <tab idMso="TabHome">
    <group id="grAutoText" label="Автотекст">
     <dropDown id="ddAutoText"
          onAction="ddAutoText_onAction"
          getItemLabel="ddAutoText_getItemLabel"
          getItemSupertip="ddAutoText_getItemSupertip"
          getItemCount="ddAutoText_getItemCount"
          getItemID="ddAutoText_getItemID"
          getSelectedItemIndex="ddAutoText_getSelectedItemIndex" >

     </dropDown>
     <button id="btnRefresh"
         label="Обновить"
         imageMso="RecurrenceEdit"
         onAction="btnRefresh_onAction" />
    </group>
   </tab>
  </tabs>
 </ribbon>
</customUI>

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

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

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

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

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

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

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


Кнопка совершенно обычная и никаких трудностей у вас не должна вызвать, если вы дошли до создания списка. Если же возникли трудности, то ознакомьтесь с этой заметкой. Сохраняем шаблон и открываем его в Word, не забыв перед этим получить заготовку для кода VBA. Для этого в программе Ribbon XML Editor, которую я настоятельно рекомендую к использованию, предусмотрена специальная функция : вы можете автоматически получить заготовки для всех динамических атрибутов, указанных в XML-схеме и сохранить их в виде модуля *.bas для последующего импорта в документ.
Теперь код VBA. Открываем шаблон в Word, импортируем сохранённый модуль с процедурами ленты и доводим его до такого состояния:
Option Explicit
Dim tmp As Template
Dim bb As BuildingBlocks
Dim MyRibbon As IRibbonUI

' (компонент: customUI, атрибут: onLoad), 2007
Sub RibbonLoading(ribbon As IRibbonUI)
  Set tmp = ActiveDocument.AttachedTemplate
  Set bb = tmp.BuildingBlockTypes(wdTypeAutoText).Categories("Общие").BuildingBlocks
  Set MyRibbon = ribbon
End Sub

'ddAutoText (компонент: dropDown, атрибут: onAction), 2007
Sub ddAutoText_onAction(control As IRibbonControl, selectedId As String, selectedIndex As Integer)
  bb(selectedIndex).Insert Where:=Selection.Range, RichText:=True
End Sub

'ddAutoText (компонент: dropDown, атрибут: getItemLabel), 2007
Sub ddAutoText_getItemLabel(control As IRibbonControl, index As Integer, ByRef label)
  label = bb(index + 1).Name
End Sub

'ddAutoText (компонент: dropDown, атрибут: getItemSupertip), 2007
Sub ddAutoText_getItemSupertip(control As IRibbonControl, index As Integer, ByRef superTip)
  superTip = bb(index + 1).Value
End Sub

'ddAutoText (компонент: dropDown, атрибут: getItemCount), 2007
Sub ddAutoText_getItemCount(control As IRibbonControl, ByRef count)
'  Dim tmp As Template
  count = bb.count
End Sub

'ddAutoText (компонент: dropDown, атрибут: getItemID), 2007
Sub ddAutoText_getItemID(control As IRibbonControl, index As Integer, ByRef id)
  id = bb(index + 1).Name
End Sub

'ddAutoText (компонент: dropDown, атрибут: getSelectedItemIndex), 2007
Sub ddAutoText_getSelectedItemIndex(control As IRibbonControl, ByRef index)
  index = 0
End Sub

'btnRefresh (компонент: button, атрибут: onAction), 2007
Sub btnRefresh_onAction(control As IRibbonControl)
  MyRibbon.InvalidateControl "ddAutoText"
End Sub

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

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