Я работаю разработчиком в компании «Сибтех», и последние полгода мы занимаемся переносом VBA-макросов из Microsoft Office в Р7-Офис.
И я хочу поделиться, как это было и почему это так важно.
Почему после замены офисного пакета могут перестать работать привычные процессы
Всё дело в макросах. Для многих пользователей они остаются незаметными, потому что работают в фоновом режиме. Сотрудник нажимает кнопку, и отчёт готов. Он не задумывается, что за этой кнопкой стоят тысячи строк кода, десятки листов, внешние файлы и запросы к базе данных.
Но когда происходит смена программного обеспечения, многие из привычных функций перестают работать. То, что раньше занимало три секунды, теперь может требовать нескольких часов ручной работы. А это тормозит целые отделы: бухгалтерию, планово‑экономический отдел, отдел отчётности. Цепная реакция наступает довольно быстро.
Поэтому при переходе на новое ПО важно оценивать не только совместимость документов, но и совместимость автоматизированных сценариев. И здесь мы столкнулись с проблемой, которую часто недооценивают.
Что мы на самом деле переносим, когда говорим о макросах
Если спросить руководителя компании, что в ней автоматизировано, он, скорее всего, перечислит 1С, CRM‑систему и другое дорогое ПО. Но в большинстве организаций VBA‑макросы фактически выполняют роль небольших информационных систем. Они могут быть написаны много лет назад, постепенно дорабатываться разными сотрудниками и не иметь никакой документации.
Мы видели макросы, которые писались десять лет назад, потом их правил один сотрудник, потом другой, потом третий. Никто не описывал логику работы, никто не комментировал код. И когда приходит время переходить на Р7‑Офис, выясняется, что вся эта автоматизация перестаёт работать.
Сотрудник привык нажимать одну кнопку и получать готовый отчёт. За этой кнопкой могут находиться несколько тысяч строк VBA‑кода, десятки листов, внешние файлы и запросы к базе данных. И всё это нужно не просто перенести, а воссоздать в новой среде с другим языком и другой объектной моделью.
Почему VBA-код не запускается в Р7-Офис
Тут всё довольно просто. Microsoft Office использует язык программирования VBA и собственную объектную модель для работы с документами. В Р7‑Офис для автоматизации используется язык JavaScript. Синтаксис, конструкции и сама объектная модель в этих языках принципиально различаются.
Код, написанный для Microsoft Office, в Р7 просто не будет работать. Он либо выдаст ошибку, либо выполнится с непредсказуемым результатом. Дело не в том, что одна система хуже, а другая лучше. Просто они говорят на разных языках. Задача состоит не в переводе строк кода, а в переносе смысла: что макрос должен сделать с документом, какие данные обработать и какой результат получить.
Мы довольно быстро поняли, что автоматический перевод строк не работает. Нужно понимать логику, восстанавливать бизнес‑правила и переносить не код, а функциональность.
С чем мы справляемся почти без проблем
Относительно простые случаи можно конвертировать без особых проблем. К ним относится базовая работа с ячейками: чтение и запись значений, перебор строк и столбцов, простые циклы и условия, математические операции и работа с отдельными листами.
Например, типовой VBA‑макрос суммирует значения из трёх диапазонов и записывает результат в нужные ячейки. После конвертации в JavaScript код остаётся понятным и сохраняет структуру. Но на практике нам требуется гораздо больше функций. Когда бухгалтеру нужно быстро составить баланс, макрос на сумму значений по столбцам мало чем поможет.
Что оказалось внезапным
Когда я только начинал работу в этом проекте, даже не предполагал, что существует столько подводных камней.
1. Несовпадение объектных моделей. Одни и те же действия в Microsoft Excel и Р7‑Офис выполняются разными методами. Некоторые функции могут отсутствовать или иметь ограничения. Часть команд можно заменить напрямую, часть требует обходного решения, а часть требует изменения логики работы макроса. Мы потратили много времени на то, чтобы составить карту соответствий между объектными моделями, и этот процесс до сих пор продолжается.
2. Работа с внешними приложениями. Макросы, взаимодействующие с внешними системами, представляют отдельный класс сложности. Это макросы, которые контактируют с Outlook, Word, COM‑объектами, вызывают внешние исполняемые программы, работают с файловой системой и сетевыми каталогами. В Р7‑Офис эти сценарии реализуются иначе, а иногда и вовсе требуют перепроектирования.
3. Пользовательские формы. Конструкция VBA UserForm не имеет прямого аналога в JavaScript‑среде Р7‑Офис. Воспроизведение интерфейсов форм требует использования плагинов и веб‑технологий. Это не просто техническая задача, это ещё и дизайнерская: нужно сохранить привычный пользователю интерфейс, но реализовать его на других технологиях.
4. Обработчики событий. События открытия книги, изменения ячейки, нажатия кнопки или сохранения документа могут отличаться по способу реализации. То, что в VBA выглядело как одна строка, в JavaScript может превратиться в несколько десятков строк с дополнительной логикой.
5. Недокументированная бизнес‑логика. В процессе длительной эксплуатации в код вносились изменения разными разработчиками. Часть логики реализована без формального описания требований. При конвертации важно понимать, как именно работал старый макрос, а не просто переписывать строки кода.
Что мы переделывали, потому что первый вариант не работал
Как только мы взяли реальные файлы от заказчиков, выяснилось, что парсер не понимает вложенные объекты, например цепочки вызовов с листами и диапазонами, и превращал код в бессмысленную кашу. Пришлось переписывать его с нуля. То же самое касается и пользовательских форм. Отдельной болью стала работа с внешними приложениями, особенно с Outlook, потому что в Р7-Офис нет доступа к COM, поэтому один из макросов пришлось полностью перепроектировать и отправлять письма через веб-сервис. Систему автоматической конвертации мы переписывали три раза, пока не нашли баланс между автоматизацией и читаемостью кода. Каждая переделка отнимала время и нервы, но без этих ошибок мы бы не поняли, как на самом деле устроены реальные макросы, и не смогли бы сделать надёжное решение.
Что нужно сделать до того, как мы начнем перенос
Перед тем как начинать процесс конвертации, мы всегда рекомендуем заказчикам выполнить несколько простых шагов. Это кажется очевидным, но на практике именно этот этап часто пропускают, что приводит к путанице и потерям времени.
-собрать все файлы с макросами;
-удалить дубликаты;
-определить владельца процесса;
-согласовать критерии приемки
В сложных случаях перенос макроса становится поводом привести в порядок старую автоматизацию: убрать дубли, описать правила расчёта и зафиксировать ответственных за процесс.
Пример преобразования реального макроса и результаты
Вот реальный код из нашей практики. Задача: перенести макрос, который использовался в производственной компании для обработки табличных данных. Он проверял корректность переданного номера таблицы, записывал это значение в служебную ячейку, переключался на соответствующий лист, определял последнюю заполненную строку с помощью границ ячеек и формировал рабочий диапазон для дальнейшей обработки.
Исходный код:

Итоговый вариант:

Что бы мы сделали иначе, если бы начинали сегодня
Наверное, мы бы не пытались сделать универсальный автоматический конвертер с первой же версии. Стоило бы выпустить минимальный продукт, который умеет переносить только самые частые сценарии, и дорабатывать его на основе реальных замечаний, а не наших предположений. Можно было сразу заложить в архитектуру возможность ручной правки кода после автоматической конвертации, потому что в любом случае без неё не обойтись. Ну и тратить больше времени на анализ реальных макросов до начала разработки, а не в процессе, когда исправлять ошибки уже было дорого
А еще можно было раньше начать привлекать к тестированию реальных пользователей, потому что они находят проблемы, о которых мы даже не догадываемся, и мы бы не боялись признавать, что какие-то макросы проще переписать с нуля, чем конвертировать, к сожалению.
Тг: anndmmsib
ссылка на оригинал статьи https://habr.com/ru/articles/1059330/