Не смотря на очевидные успехи импортозамещения в сфере программного обеспечения, есть ряд трудностей «переходного периода», которые существенно усложняют жизнь миллионам пользователей на необъятных просторах нашей страны. Одна из таких «головных болей» – макросы. При переходе на российские офисные пакеты, требуется переписать множество VBA-макросов для MS Office. При этом, макросам на VBA посвящено множество книг и интернет-ресурсов. А вот про макросы в отечественных «офисах» информацию, пока, приходится собирать по крупицам.

В этой статье предлагается пример разработки макроса в табличном редакторе «МойОфис Таблица». Разработчики «МойОфис» не только заложили возможности расширения базовой функциональности своего «офиса» с помощью макросов, но и снабдили пользователей толковым «Справочником макрокоманд на языке программирования Lua».

Попробуем решить тривиальную задачу сравнения двух таблиц. В «экселевском» файле Verify.xlsx 3 листа – Contract, Act, Result. В таблице Contract содержатся данные о договорных объемах работ, в Act – о фактически выполненных.

Таблица Result – пустой лист. Требуется в Result сопоставить договорные и фактические объемы работ и визуализировать расхождения. Если объём выполненных работ превышает договорной – ячейки таблицы зальём зелёным, если выполнение меньше договора – ячейки красные. Если показатели совпадают – нет заливки.
Для написания нашего макроса понадобится «МойОфис Стандартный. Домашняя версия», эта статья, Справочник макрокоманд на языке программирования Lua, Учебное пособие Работа с табличным редактором «МойОфис Таблица» и базовые знания языка программирования Lua.

Сначала нам необходимо получить доступ к данным на листах Contract, Act. Для этого в «МойОфис» предусмотрен объект DocumentAPI.Document. Вообще-то, в
терминах языка программирования Lua это таблица. Но что бы не путаться с терминами, назовём это объектом. Создадим три экземпляра этого объекта и поместим их в локальные переменные:

Запустив этот макрос, можно убедиться в его работоспособности.
В программировании, для работы с массивами данных используют циклический перебор элементов массива. Наша задача – не исключение. Чтобы организовать перебор ячеек в каком-либо диапазоне, нужна такая система адресации ячеек, при которой на каждой итерации (повторении) адрес ячейки меняется на следующий в данном диапазоне. Разработчики «МойОфис» создали объект DocumentAPI.CellPosition, в котором адрес определяется парой целых чисел – индекс строки и индекс столбца. Если перебирать диапазон по строкам, то в адресе нужно изменять только индекс строки. Индекс первой строки – ноль. Создадим локальную переменную переменную currentRow (строка 4). И, наконец, положим в переменную диапазон который будет обработан (строка 5). Это первый столбец первого листа – все доступные строки.

Получить элементы диапазона firstRange можно используя метод enumerate(). В начале напишем простой цикл for:

Нормальная работа макроса – 20 строк "Ok!" в терминале. Именно столько элементов в массиве firstRange. Теперь добавим условие обработки элемента – только если ячейка не пустая:

В 8 строке использован cell:getFormattedValue() – метод, возвращающий содержимое текущей ячейки cell. Это содержимое сравнивается с пустой строкой, и если сравнение возвращает True, цикл прерывается командой break. Если всё так, то при выполнении этого скрипта в терминале уже не 20 а только 8 строк "Ok!" – именно столько заполненных ячеек в этом диапазоне, остальные пусты.
Теперь добавим в тело цикла несколько переменных: props – содержит метод настройки оформления ячейки (строка 11); work – доступ к ячейкам первого столбца листа Result (строка 12); unit – единицы измерения объема работ из второй колонки листа Contract (строка13); vol_contract – объем работ из третьей колонки листа Contract (строка 14); vol_fact – фактический объем работ из третьей колонки листа Act (строка 15). При этом, для перебора всех массивов кроме firstRange, необходимо на каждой итерации увеличивать индекс строки на единицу (строка 19):

Запустив макрос в таком виде, получим в терминале 8 строк с единицами измерения и числами.
Добавим в наш код еще одно логическое выражение – назначение цвета фона ячейки в соответствии с условиями: красная заливка, зелёная заливка или без заливки. В переменной props хранится таблица свойств текущей ячейки. Нас интересует свойство props.backgroundColor:

Наконец, расставим все значения по их местам на листе Result. Нулевая колонка ("A") заполняется данными из текущей ячейки – строка 25. Следующая – колонка с индексом 1 ("B"), заполняется содержимым переменной unit (строка 26). Далее, в колонки 2 ("C") и 3 ("D") записываются данные из переменных vol_contract и vol_fact, соответственно (строки 27 и 28). Ячейки последней колонки заливаются соответствующим цветом (строка 29).

В результате получим такую таблицу:

В данном макросе не понадобилось производить математических вычислений, поэтому, всё отработало корректно. Однако, если «распечатать» тип данных из ячеек, то обнаружится, что это не числа, а строки. И использование арифметики Lua, тем более модуля math не получится. Стандартная для Lua "tonumber()" возвращает nil. Для вычислений в макросе нужно написать дополнительную функцию преобразования строкового значения в число.

Эта статья не о работе с таблицами «МойОфис», а о возможностях макрокоманд. Конечно, отвыкать от привычного Excel с его колоссальным функционалом – дело весьма не комфортное, но опыт написания данного макроса в «МойОфис» свидетельствует о широких возможностях автоматизации обработки табличных данных и без Microsoft.
Надеюсь эта статья окажется актуальной. Если так, то тему можно будет продолжить.

Комментарии (10)


  1. CBET_TbMA
    18.04.2023 14:01
    +1

    нашим надо было сразу SQL для работы с таблицами делать... прросто макросы это очень слабо по сравнению с Excel и google таблицами


  1. myoffice_ru
    18.04.2023 14:01
    +6

    @SergBedin66, здравствуйте! Спасибо за вашу статью. Мы рады, что вы оценили использование макросов в нашем продукте и поделились впечатлениями с хабрасообществом.

    В знак признательности хотим подарить вам книгу — «Программирование на языке LUA» Роберту Иерузалимски, специальное издание от МойОфис.

    Напишите нам, пожалуйста, в личные сообщения, куда вам можно отправить подарок. Спасибо!


    1. jobless
      18.04.2023 14:01

      Что то не находится информация о таком издании. Оно ещё не вышло или это шутка такая? :)


      1. myoffice_ru
        18.04.2023 14:01

        Добрый день! С разрешения автора оригинальной книги Роберту Иерузалимски (на фото ниже) мы выпустили это издание ограниченным тиражом для наших клиентов и партнеров.

        В продаже его, к сожалению, найти нельзя, но мы можем порекомендовать вам оригинальное издание: https://dmkpress.com/catalog/computer/programming/978-5-97060-203-4/


        1. jobless
          18.04.2023 14:01

          Жаль. Оригинальное я вам сам могу подарить. )))


    1. starfair
      18.04.2023 14:01
      +2

      Всё это конечно хорошо, что не стоите на месте, и пытаетесь внести автоматизацию в свои продукты. Но, она у вас уже довольно много лет (кажется, лет 6 минимум), а у вас до сих пор нет мега важной для таблиц возможности вставлять в ячейку значения вычисленного макросом по типу: =Имя_моего _макроса(Аргументы....). И почему макросы у вас можно вызвать исключительно только через боковую панель расширений? Почему в документах нельзя напрямую вызвать макрос ни через поля формы документа, ни через встраиваемые в документ контролы? Это же ну не сложно, если вы (разработчики офиса) работаете на уровне программирования структуры документов! Или например, у вас зачем то разделены макросы на макросы (по сути просты программные скрипты) и расширения (по сути те же макросы, но с визуальными формами). Но при этом, последние написать задача не тривиальная мягко говоря, так как нет визуального конструктора форм и писать их надо фактически вовне (встроенный редактор вообще не заточен под расширения). Да и поддерживаемые средства не подразумевают много привычных форм интерфейса. Нет даже многостраничных TabControl. Далее, насколько я понял из изучения вашего API, нет возможности в одном расширении использовать несколько форм и увязывать их в какую-то бизнес логику. Ваше так сказать IDE под макросы не работает с автодополнением вашего же API и всю информацию надо искать либо по хелпу, либо по документации. Ребята, на дворе уже заканчивается первая четверть 21 века, а у вас до сих пор средства программирования ваших макросов 90х годов прошлого. Притом, что судя по всему, вы то используете уже готовые решения (опенсоурс либы), к которым давным давно прикручены и автодополнения, и визуальные конструкторы. И это всё даже в опенсоурсе лежит!
      Ну как так то?! Если вы позиционируете себя как центральное решение импортозамещения в вопросах электронного офиса, то вот такие моменты, для огромного числа организаций активно использующих VBA макросы в MS Office, просто ставят крест на покупку ваших решений, так как очень многие сложные вопросы заполнения разной информации в внутренних документах решались именно через макросы, а у вас и 10% от возможностей (тоже уже очень устаревших, кстати) майкрософта не реализовано!


  1. dubinsky
    18.04.2023 14:01

    Спасибо за статью! Очень легко читается!


  1. lmapro
    18.04.2023 14:01
    +1

    Спасибо за статью. Но это опять уровень "пройти по ячейкам, покрасить фон".

    Думаю, всех офис-разработчиков мучает один большой вопрос: повторное использование кода. А именно, возможность вызвать из макроса другой макрос, или какие-то функции, модули и т. п. Есть возможность и будет ли в будущем? Пока, я понимаю, если у меня какая-то повторяющаяся операция, и я должен Ctrl+C -> Ctrl+v в другой макрос, что ли? Без этого ни о какой полноценной замене VBA и говорить не стоит.


    1. Surrogate
      18.04.2023 14:01

      Полностью поддерживаю!

      Хотелось бы увидеть объектные модели приложений пакета МойОфис (желательно в графическом виде). Это позволить понять возможности автоматизации…


  1. myoffice_ru
    18.04.2023 14:01
    +1

    Видим, что тема макросов популярна и вызывает живой интерес на Хабре)

    Пользуясь случаем, приглашаем всех желающих на наши лекции в Хаб Знаний МойОфис.

    Завтра, 20 апреля, будем говорить про разработку надстроек в продуктах МойОфис.

    Также в нашем архиве доступны записи предыдущих лекций:

    1. Разработка макросов. Введение в Lua

    2. Разработка макросов для текстового редактора

    3. Разработка макросов для табличного редактора