четверг, 5 марта 2015 г.

Урок 9. Выполнение действия по нажатию кнопки.

На прошлом уроке мы познакомились с написанием функций для динамического возвращения значений атрибутов. Теперь мы напишем функцию, которая будет выполняться при нажатии на кнопку. Если мы рассмотрим все предлагаемые для button атрибуты, то увидим атрибут onAction. Именно в этом атрибуте и указывается функция, которая будет выполняться при нажатии на эту кнопку.

Добавим кнопке атрибут:

onAction="ОтобразитьПриветствие"

Сгенерируем шаблоны функций (Alt+F11), проконтролируем текущую раскладку, чтобы была русская, и скопируем в буфер шаблон для функции «ОтобразитьПриветствие». Затем закроем окно, запустим документ на выполнение, нажмём в Word Alt+F11, и вставим скопированное рядом нашей предыдущей с функцией. Внутри функции пишем команду вывода сообщения:

MsgBox "Приветствую тебя, мой повелитель!"

Сохраняем, всё закрываем, затем снова запускаем документ. Нажимаем на кнопку и получаем удовольствие.

Вместо вывода сообщения можно вызвать любую имеющуюся в Word команду. Выше я упоминал, что штатной кнопке нельзя присвоить внешнее изображение. Но можно создать свою кнопку, присвоить ей внешнее изображение, а в onAction прописать команду, выполняющуюся при нажатии штатной кнопки.

Давайте повесим на нашу кнопку команду открытия редактора Бейсика. Запускаем документ, переходим в редактор Бейсика, и правим наши функции. Сначала в функции «Поприветствовать» меняем название кнопки на, например, «Открыть редактор Бейсика» (можем изменить и имя самой функции, но тогда надо не забыть поменять его также и в атрибуте onAction). Затем в функции «ОтобразитьПриветствие» комментируем апострофам строку вывода приветствия, и пишем вместо неё строку:

ShowVisualBasicEditor = True

Сохраняем, закрываем редактор Бейсика, нажимаем на кнопку и… снова оказываемся в редакторе! Всё, как и задумывалось!

Теперь, вопрос: откуда я узнал, что редактор Бейсика открывается именно так? Всё очень просто. Для того, чтобы узнать, как программно проделать те или иные действия, можно штатными средствами Word просто создать макрос, и записав в него нужную последовательность действий, открыть его код и скопировать в нашу функцию. При этом не всегда стоит копировать код бездумно. Как правило, полученные макросы можно уточнить, убрать из них лишнее и т.п.

Замечу, что обучение записи макросов и программированию на VBA не входит в задачи наших уроков, но всё это очень легко осваивается самостоятельно. Особенно запись макросов. Для неё даже предусмотрена группа «Макросы» на вкладке «Вид» или группа «Код» с кнопкой «Запись макроса» на вкладке «Разработчик».

На сегодня закончим. В следующем уроке мы перейдём к важной теме - созданию надстроек.

16 комментариев:

  1. Классная прога, много спасибо. А нельзя ли маленькую главку с примерами использования других кнопок? Мне непонятно, как загружать списки в Combobox. Я правильно понимаю, что макросы для кнопок ленты аналогичны макросам для кнопок UserForm?

    ОтветитьУдалить
    Ответы
    1. Я не писал макросы для кнопок UserForm, поэтому не знаю. Про загрузку списков в комбобоксы при случае напишу, но позже. Пока я сам не пробовал это делать.

      Удалить
    2. Разобрался, как загружать динамические списки в ComboBox и DropDown. Код XML:



      Процедуры обратного вызова пишутся под каждый из параметров get, они все генерируются кнопкой VBE в Ribbon XML Editor. Если список создается на основе диапазона Excel, то примерно так:

      Sub ЗагрузитьСписокКол(control As IRibbonControl, ByRef count)
      Dim i As Integer
      Sheets("Лист3").Activate
      i = ActiveSheet.Range("A65536").End(xlUp).Row

      Range(Cells(1, 1), Cells(i, 1)).Copy Sheets("Лист2").Range("A1")

      Sheets("Лист2").Activate
      count = i

      End Sub

      Sub ЗагрузитьСписокЛ(control As IRibbonControl, index As Integer, ByRef label)
      label = Cells(index + 1, 1).Value
      End Sub

      Sub ЗагрузитьСписокИД(control As IRibbonControl, index As Integer, ByRef id)
      id = Cells(index + 1, 1)
      End Sub

      небольшое неудобство: при загрузке списка VBE чистит лист, и мне пришлось копировать список в первом макросе из листа 3 в лист 2. Нельзя ли как-то отменить такую страсть VBE к чистоте и порядку? Чтобы не копировать каждый раз один и тот же список. Нерациональное использование памяти и быстродействия. Но это так, мелочи. Прога вообще великолепная.

      Удалить
    3. После заполнения комбобокса данными с листа, данные на листе пропадают что ли? Вообще, странно. Но это ведь к VBA относится, а не к Ribbon XML Editor. Может, какие-то другие VBA-функции использовать, чтобы они не удаляли данные при переносе? Не знаю. Я не силён в VBA.

      Удалить
  2. Не отобразился почему-то XML. Вот:

    ОтветитьУдалить
  3. dropDown id="ChoisInstr" label="Выбор"
    getItemCount="ЗагрузитьСписокКол"
    getItemID="ЗагрузитьСписокИД"
    getItemLabel="ЗагрузитьСписокЛ"

    ОтветитьУдалить
  4. Нет, в VBA я точно очистку списка листа не прописывал. Это Ribbon XML Editor рулит. Ладно, будем разбираться. Но это решение тоже в принципе подходит, пользуйтесь на здоровье!

    ОтветитьУдалить
    Ответы
    1. Ribbon XML Editor выполняет только одну функцию. Он внедряет в документ xml-код, который описывает интерфейс, и код этот весь виден на первой вкладке. Ничего лишнего не внедряется. Всё остальное, в том числе и заполнение комбобоксов интерфейса Excel, происходит уже на стороне офиса средствами VBA. Поэтому и очистка ячеек на листе Excel может происходить только средствами офиса уже без всякого участия Ribbon XML Editor. Или я вас неправильно понял и чистится что-то другое?

      Удалить
  5. Правильно поняли. Может, и Excel виноват. Буду разбираться. Кстати, если вдруг будет нужна помощь с VBA, могу помочь.

    ОтветитьУдалить
  6. dolbodub

    Не понял как правильно использовать "ComboBox и DropDown"?
    Выложите уже готовый код для вставки в "Ribbon XML Editor".

    ОтветитьУдалить
    Ответы
    1. Затруднительно. В комментариях угловые скобки тегов глючат. Но, думаю, разберётесь без угловых скобок:
      ?xml version="1.0" encoding="UTF-8" standalone="yes"?
      customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"
      ribbon startFromScratch="false"
      tabs
      tab id="Tab1" label="Пример" insertBeforeMso="TabHome"
      group id="gr" label="Комбобокс"
      comboBox id="cb1" onChange="Смена"
      item id="i1" label="Пункт 1" /
      item id="i2" label="Пункт 2" /
      item id="i3" label="Пункт 3" /
      /comboBox
      /group
      /tab
      /tabs
      /ribbon
      /customUI

      Удалить
    2. Обработку выполняете в VBA, сгенерировав соответствующую процедуру обратного вызова.

      Удалить
    3. Кстати, не понимаю, почему у вас это вызвало проблемы. Автодополнение вам само подсказывает, как строить комбобоксы и дропдауны.

      Удалить
  7. Как исправить "Макрос не найден или отключен по соображению безопасности" ?????
    В настройках макросы разрешены, но при нажатии на кнопку выдается такая ошибка...

    onAction= указывает на функцию, которая прописана в Modules

    Не хочет запускать функцию при нажатии на кнопку...

    ОтветитьУдалить