понедельник, 2 июля 2018 г.

Урок 17. Использование внешних изображений на ленте Access в версии RXE 7.5

Как уже говорилось на прошлых уроках, использовать внешние изображения на контролах (элементах управления) ленты Access чуточку сложнее, чем на лентах Excel, Word и PowerPoint. Для осуществления этого действия требуется работа не только в Ribbon XML Editor, но и в редакторе VBA приложения, а также в таблицах самой базы данных Access. Тем не менее, последние версии Ribbon XML Editor максимально упростили этот процесс.

Напомню, что вывод изображений в интерфейс Access можно осуществить двумя основными способами: либо с помощью события, заданного в параметре loadImage корневого тега customUI, либо с помощью события, заданного в параметре getImage в контролах. В первом случае изображения контролы грузятся один раз при первом их показе пользователю, а во втором их можно перезагружать, сбрасывая кеши изображений в VBA-коде методами InvalidateControl и Invalidate. Тогда при очередном показе загрузка изображений произойдёт снова, что полезно, если в процессе работы необходимо менять картинки на контролах интерфейса.

Давайте рассмотрим создание кнопки с собственным изображением на новой вкладке ленты Access по первому способу, используя новый функционал последней версии Ribbon XML Editor 7.5.

Предполагается, что нужный файл изображения 32х32 или 16х16 формата .png, который мы будем выводить на ленту, у нас уже есть. В противном случае, его можно скачать прямо отсюда:


Также предполагается, что файл базы данных Access, в который мы будем внедрять новый интерфейс, уже создан.

Шаг 1. Ввод XML-кода интерфейса

Итак, запускаем Ribbon XML Editor 7.5 и открываем файл базы данных Access. Замечу, что в редакторе можно открыть базы форматов .accdb, .accde, и .accdr, однако в последних двух случаях функционал будет несколько ограничен (нельзя будет автоматически интегрировать в базу модули с кодом). Поэтому всю работу ведём с .accdb.

После открытия базы в редакторе вставляем в окно xml-кода на вкладку интерфейса 2007 версии отчасти знакомый нам по прежним урокам код:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customUI loadImage="ЗагрузкаИзображений" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
    <ribbon startFromScratch="false">
        <tabs>
            <tab id="Вкладка1" label="Моя вкладка" insertBeforeMso="TabHomeAccess">
                <group id="Группа1" label="Моя группа">
                    <button id="Приветствие" label="Поприветствовать" image="Рука" />
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>
Тут мы формируем новую вкладку, на ней располагаем группу, внутри которой размещаем кнопку. Для размещения изображения на кнопке в параметре image прописываем идентификатор «Рука».

Если целевая версия нашего будущего интерфейса будет выше, и мы не стремимся к совместимости с 2007 версией офиса, то вставляем код на вкладку интерфейса 2010, 2013, 2016 и корректируем соответствующим образом параметр xmlns тега customUI (используем для этого функцию автодополнения Ctrl + Пробел). Внедрить код для обеих версий офиса, как это было в случае с Excel, Word и PowerPoint, в Access не получится.

Не забываем также задать имя нашего интерфейса, вписав его в поле, расположенное в правом нижнем углу редактора (на картинке отмечено красным прямоугольником):


Оно нам пригодится при выборе нашего интерфейса в настройках базы Access.

Для тех, кто ранее создавал интерфейсы для других приложений офиса, замечу, что в присвоении имени интерфейсу мы видим основное отличие Access. В базу Access можно сохранить не два (для разных версий), а несколько интерфейсов одной версии под разными именами. Ribbon XML Editor позволяет раскрыть поле с именем интерфейса, и переключаться между несколькими интерфейсами, добавлять новые, удалять ненужные, переименовывать и т.п.

Итак, сохраняем изменения. Сейчас у нас создана кнопка, но изображения на ней не будет, поскольку у нас нет ни макроса «ЗагрузкаИзображений», осуществляющего возврат картинок в контролы в зависимости от указанных в контролах в параметре image идентификаторов, ни самой картинки. Поэтому переходим к следующим шагам.

Шаг 2. Создание таблицы для хранения изображений

Теперь нам надо создать в базе Access специальную системную таблицу для хранения изображений. Нажимаем кнопку импорта в блоке работы с внешними изображениями:



Откроется окно работы с таблицей внешних изображений:



Раскроем верхний комбобокс и, просмотрев имена таблиц, находящихся в открытой базе данных, убедимся, что таблицы с изображениями в базе ещё нет. Кнопкой с крестиком очистим поле верхнего комбобокса, если мы случайно в него что-нибудь занесли, и нажимаем кнопку «Создать таблицу». Будет создана таблица с именем по умолчанию USYSRibbons_Images, которое будет занесено в поле комбобокса, а в поле второго комбобокса автоматически подставится название столбца этой таблицы, предназначенного для идентификаторов.

Замечу, что можно создать таблицу и с любым другим именем. Для этого перед нажатием кнопки создания следует вписать в поле верхнего комбобокса любое подходящее для этой таблицы имя. Поскольку мы создаём системную таблицу, то её имя должно начинаться с «USYS», но для большей информативности лучше начинать его с «USYSRibbons_». В имени таблицы также можно использовать пробелы и кириллицу.

Заполнение таблицы изображениями в Access мы оставим на потом, а пока переходим к следующему шагу. Окно работы с таблицей внешних изображений пока не закрываем, на следующем шаге оно нам понадобится.

Шаг 3. Добавление вспомогательного модуля в базу.

По факту интерфейс Access понимает только jpg-изображения. Чтобы заставить его работать с png, требуется подключить специальный VBA-модуль, код которого можно увидеть, нажав в окне работы с таблицей внешних изображений на кнопку «Модуль basGDIPlus». Откроется окно с кодом модуля, текст которого можно скопировать в буфер, сохранить в файл или сразу внедрить в базу. Нажмём на кнопку внедрения модуля в базу, и через пару секунд появится сообщение об успешном внедрении модуля.

Внимание! Если при внедрении возникли какие-то ошибки, возможно, у вас не совсем корректно установлен Microsoft Office или присутствуют другие проблемы в вашей системе. О способах их устранения можно прочитать во встроенной в Ribbon XML Editor справке, в разделе «Ошибки OLE при внедрении VBA-модуля в документ». Если же ошибку исправить не удалось, то можно сохранить модуль в файл, а затем импортировать его в базу уже из самого Access.

Справа от кнопки модуля basGDIPlus расположена кнопка со знаком вопроса. Нажав на неё, мы можем увидеть примеры использования модуля basGDIPlus с подробными комментариями. В них показана реализация двух способов вывода изображения в интерфейс. Как уже упоминалось ранее, мы будем использовать первый способ получения изображений, используя параметр loadImage корневого элемента интерфейса. Кстати, второй способ не сильно отличается от первого, и вы сами потом сможете изучить его.

Закрываем окна с кодом модулей. Перед закрытием окна поиска идентификаторов ещё раз убеждаемся, что оба комбобокса заполнены правильно. Нижнее поле пока остаётся пустым, поскольку созданная нами таблица ещё не заполнена. Нажимаем кнопку «ОК». Программа запоминает имя столбца с идентификаторами, и впоследствии будет доставать их оттуда в комбобокс внешних изображений основного окна для последующей их вставки нами в XML-код, как это происходит в случае с Excel, Word или PowerPoint.

Шаг 4. Генерация функции обратного вызова.

Теперь в нашей базе есть xml-код интерфейса, таблица для png-изображений и модуль для доставания png-картинки из вложения таблицы изображений и трансформирования этой картинки в распознаваемый интерфейсом объект StdPicture. Осталось написать процедуру обратного вызова «ЗагрузкаИзображений», в которой использовать подключённый модуль для возвращения объекта картинки в интерфейс.

Сгенерируем шаблон функции обратного вызова соответствующей кнопкой или сочетанием клавиш (Alt + F11). У нас получится вот такой шаблонный код функции «ЗагрузкаИзображений»:
Attribute VB_Name = "RibbonCallbacks"
Option Explicit    'Потребовать явного объявления всех переменных в файле

' (компонент: customUI, атрибут: loadImage), 2007
Sub ЗагрузкаИзображений(imageId As string, ByRef image)
    Dim ImageFilename As String
    ImageFilename = DLookup("Image", "USYSRibbons_Images", "Image_or_control_identifier='" & imageId & "'")
    Set image = basGDIPlus.AttachmentToPicture("USYSRibbons_Images", "Image", ImageFilename)
End Sub
В этом коде уже прописано всё, что нужно. Ничего не меняя внедрим этот модуль с функцией в базу Access так же, как мы это уже проделывали с модулем basGDIPlus.

Теперь можем запустить базу на выполнение соответствующей кнопкой или клавишей F9. Ribbon XML Editor закроет базу данных и откроет её в Access. Все остальные шаги будем проделывать уже в Access.

Шаг 5. Заполнение таблицы изображений в Access.

При открытии базы появится предупреждение системы безопасности об отключении запуска активного содержимого. Нажимаем кнопку «Включить содержимое».

Находим и открываем созданную нами таблицу изображений. Она имеет 4 столбца, но нам важны лишь 2 из них — Image_or_control_identifier и Image (в режиме таблицы вместо названия столбца показана скрепка). Столбец ID будет заполняться сам по мере добавления строк, а столбец Comment можно заполнить по желанию.

Заполняем таблицу — в поле Image_or_control_identifier заносим идентификатор изображения, в нашем случае это будет «Рука», а в поле Image в виде вложения добавляем подготовленный заранее файл картинки ладошки. Сохраняем изменения.

Замечу, что в поле вложения можно добавить несколько файлов, но нам следует добавлять по одному файлу на строку таблицы, чтобы правильно соблюсти соответствие картинки и её идентификатора.

Шаг 6. Подключение интерфейса в настройках базы Access.

У нас всё готово. Осталось лишь подключить интерфейс в настройках базы Access. Открываем настройку «Файл → Параметры → Текущая база данных → Параметры ленты и панелей инструментов → Имя ленты» и выбираем имя нашего интерфейса. Нажимаем кнопку ОК, закрываем и снова открываем базу. Появляется наша вкладка, при переходе на которую мы видим кнопку с нашим изображением.

На этом урок закончен, спасибо за внимание :-)

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

  1. Всё сделал и как бы робит но как и куда импортировать саму картинку я не понял!? Ошибка в "VBA" появляется окно на шаге:
    Sub ЗагрузкаИзображений(imageId As String, ByRef image)

    Цитата:
    Столбец ID будет заполняться сам по мере добавления строк, а столбец Comment можно заполнить по желанию.

    ...тут я не понял про "ID" и "Comment" где это вообще?

    ОтветитьУдалить
    Ответы
    1. Это внутри базы данных Access. Обращайте внимание на заголовки шагов. Речь идёт о таблице в самом Access.

      Удалить
  2. Итак... Доброго дня!
    Теперь понял. Оказывается нужно было сделать вот это:
    Для отображения таблиц – наводим стрелку на “Все объекты Access”, правый клик и выбираем “Параметры навигации>Показывать системные объекты”.

    У меня всё ещё есть проблема!

    =====================================================================================================================

    1. Создал базу "Database4_TEST.accdb" разместил вот по такому пути:
    C:\Users\ПОЛЬЗОВАТЕЛЬ\AppData\Roaming\Microsoft\AddIns\
    2. Вставил XML-код:
    https://my-files.ru/3v4hun
    (тут выложить не получается выскакивает надпись - "Ваш код HTML не может быть принят: Недопустимый тег: BUTTON").

    Использовал на вкладке:
    "2010, 2013, 2019 (customUI14.xml)"

    ***
    P.S. - "TabHomeAccess" - потому что "TabHome" не работает!

    3. Имя интерфейса задал "Интерфейс1"
    4. Работа с таблицей внешних изображений:
    В выпадающем списке уже имелись 2 таблицы:
    USYSRibbons
    USYSRibbons_RXEOptions

    Далее внизу у меня вот так:
    http://tiny.cc/vbxq6y
    http://tiny.cc/87wq6y

    5. Версия "Office 2019" активированная сопутствующим активатором, скачана отсюда - https://diakov.net/8561-kms-tools-by-ratiborus.html
    6. Модуль basGDIPlus - внедрен успешно!
    7. Процедуру обратного вызова «ЗагрузкаИзображений» - внедрен успешно!
    8. Цитата:
    При открытии базы появится предупреждение системы безопасности об отключении запуска активного содержимого. Нажимаем кнопку «Включить содержимое».

    ...Такой надписи не было а было такое - http://tiny.cc/qq0q6y

    9. Записал скринкаст чтобы не мучиться с картинками (последние штрихи):
    https://www.screencast.com/t/uXRjLNg2qpQ9



    Технический вопрос:
    Посмотрел на ютаре видеоурок и там окно широко распахнуто http://tiny.cc/gsvq6y у меня же в этом месте просто "ачейка" которую я могу расширить только по горизонтали. Как задавать нужный мне размер для просмотра данных в ячейке?

    ОтветитьУдалить
    Ответы
    1. Что-то сломали они в Office 2019, пытаюсь разобраться. Ни одного макроса не видит...

      Удалить
    2. По поводу вертикального размера ячеек — у меня в 2019-м всё прекрасно раздвигается. Мышью навожу на левое поле между строками, курсор меняется, и тащу.

      Удалить
    3. Пока что мои исследования показали, что если в документе более одного модуля, то офис не видит процедур в них. Прямое указание процедуры вместе с именем модуля вида RibbonCallbacks.ЗагрузкаИзображений тоже почему-то не работает. Раньше это работало.

      Удалить
    4. Кстати, это не только в Access такая фигня. В Excel тоже, только что проверил. Думаю, что и в Word и PowerPoint тоже! Стоит добавить второй модуль, и всё, приложение перестаёт видеть функции и подпрограммы в них. Глюк нового Офиса.

      Удалить
    5. Причину проблемы я выяснил. Модуль для вывода изображений basGDIPlus был рассчитан на работу в 32-битных версиях офиса. Выслал вам патч по почте.

      Удалить
  3. Ну ладно вот скринкаст, у меня двигает ячейку только так:
    https://www.screencast.com/t/QqeWWmhFB
    Мож кнопку какую зажать нужно или в настройках что то прописать/включить?

    ОтветитьУдалить
    Ответы
    1. Эх, невнимательно вы меня читаете )) Цитирую: «Мышью навожу на левое поле между строками, курсор меняется, и тащу.» А вы на левое поле курсор не выводите, пытаетесь его так зацепить. Ширину же вы раздвигаете на верхнем поле, а не на самой таблице.

      Удалить
    2. Наверно я неточно выражаюсь. Скажем, не левое поле, а фиксированный столбец слева.

      Удалить
    3. Цитирую:
      фиксированный столбец слева.

      ААААААААААААААА! Теперь я понял тут такая же технология как в "EXCEL" если хотим расширить горизонтально.
      ...так ещё вопрос! Если расширяем то синхронно расширяются и соседние ячейки. Как расширять только нужную строку?

      Удалить
    4. Не знаю. Может, отдельно расширить нельзя?

      Удалить
    5. Нашёл VBA вроде для этой цели - http://www.leadersoft.ru/rus/market/db/products/60/help/884.html
      Но как запустить не знаю (в Excel и в WORD с этим проще).

      Удалить
    6. Ну это же для модуля отчётов, другое совсем...

      Удалить
    7. Вот что ответил мне один эксперт в области "Access":

      ЦИТИРУЮ:
      Это нельзя сделать в Access. Такое возможно в Excel.
      Но можно сделать в форме, надо немного поработать с VBA.

      Удалить
  4. UPD:
    А эти проблемы с модулями вы решить не можете?

    А я не понял про модули для "EXCEL" и "WORD". Посмотрел все уроки у меня всё 0Кей. Осталось посмотреть только "Урок 18".
    Или вы решили проверить описанный способ в "Урок 17" и в других приложениях Office и тоже не робит?

    ОтветитьУдалить
    Ответы
    1. Проблему решил, патч вам выслал.
      Да, я проверил остальные приложения, сунув в них этот же модуль для проверки. Естественно все приложения тоже заглючили. Потом уж выяснил, что декларации внешних функций были прописаны как для 32-битного офиса, а выполнялся модуль в 64-битном. Сейчас должно быть всё в порядке.

      Удалить