Что я собираюсь рассказать в этой серии статей?

В  моих  же планах на эту серию статей   - раскрыть вам некоторые, на мой взгляд,  не самые  очевидные аспекты написания макросов для офисного пакета  «Р7-Офис» версии десктоп.  Думаю, многое из мною здесь написанного вряд ли будет вами легко найдено в открытом доступе.  Кое – что конечно  имеется в «секретных Телеграмм чатах» (в которых я  и сам много чего подчерпнул и даже считался там типа эксперта), но некоторые данные,  не найдёте наверное даже там.  Я надеюсь,  изложенные  в этих  статьях мысли, будут стоить потраченных вами  усилий на их чтение. Ну а если вам не интересны мои рассуждения на тему текущего положения дела с макросами и плагинами в редакторе «Р7» - смело пропускайте эту вводную статью и ждите следующих.

Пока мой план на статьи таков:

  1. Введение в общие проблемы написания макросов в «Р7»(эта статья)

  2. Средства взаимодействия с пользователем в макросах АПИ «Р7»

  3. Мое собственное решение для построения сложных форм в макросах

  4. Прочее (по результатам  этих статей, будет зависить от вашего мнения)

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

Для чего я это пишу?

Ранее я уже обращался к проблемам автоматизации в отечественном  офисном  пакете «МойОфис», и опубликовал здесь ряд статей по отладке (и кстати, планирую ещё вернуться к нему, но позже). А теперь у меня накопился опыт по другому решению от отечественных разработчиков:  офисному пакету «Р7», который до недавнего времени являлся просто  форком опенсоурс редактора «OnlyOffice», только в «упаковке» для внутреннего рынка. Но с августа 2024 это увы, далеко не так, и их пути всё дальше расходятся. Но  относительно общая база,  всё ещё позволяет использовать исходники последнего, для понимания работы АПИ в «Р7».

За время работы, я столкнулся со многими проблемами, которые приходилось решать, и по каждой из них можно писать отдельные статьи. Но я решил для начала сосредоточится на той, которая многим покажется неочевидной и даже - неважной, а ведь по сути, она мало где освещена.

Чтобы понять, зачем вообще писать статьи на такие темы, я в этой вводной, хотел бы сперва просто сделать небольшой обзор по проблемам программирования макросов в «Р7», ибо пока не погрузишься в сам процесс, о многом просто наивно думаешь хорошо. Конечно, информация об разных аспектах автоматизации в  «Р7»(и «OnlyOffice»)  уже давно описана. Есть официальные источники по АПИ. Есть разного рода курсы по написанию макросов и плагинов (к написанию некоторых из них я причастен  непосредственно). Это все легко найти в интернете. Но но когда касаешься задачи в достаточно узком, и казалось бы - простом вопросе, как взаимодействие с пользователем в рамках макросов, то всё становится не столь уж и простым! Почему я так утверждаю, я и хотел бы изложить в этой статье, чтобы читатель мог понять, для чего ему читать следующие статьи этой серии.
Итак, моё краткое видение, что собой представляет сам «Р7» и его АПИ, с которым придется бороться.

Об мне

Я, Шумаков Виталий, программист с почти 30 летним стажем. По воле судьбы, занимаюсь последние годы различными задачами автоматизации тех или иных процессов. Кроме того, многие годы был на стороне внедрения программных продуктов, и хорошо знаю обе стороны этого процесса. Долгое время я занимался в основном VBA в CorelDraw, где стал относительно известным разработчиком, благодаря своим макросам по разработке чертежей для станков c ЧПУ. Но, потом случилось сами знаете что, и моя множественная клиентская база, была отрезана вместе с нашей банковской системой от возможностей финансовой поддержки моей работы. А внутри страны, увы, все не столь радужно ибо рынок этот достаточно специфичный. Так я и вернулся к вопросам автоматизации в сфере бизнес процессов. Так как в силу тех же обстоятельств, стало активно развиваться внедрение отечественного ПО, то решил обратить внимание именно в эту сторону. Достаточно активно поковырял «Мой офис», и написал несколько статей сюда, на Хабр, за что и получил «инвайт» прямо от администрации. Благодаря этим статьям, меня нашел один из здешних постоянных авторов, и пригласил меня поучаствовать в своем стартапе, как ведущего разработчика, но уже в другом офисном пакете отечественной разработки - в Р7. Мы сотрудничали некоторый период времени (два года), за которые я успел достаточно глубоко изучить разные аспекты работы с этим редактором (в основном табличной его части), в том числе и весьма глубоко скрытые от глаз обычного пользователя. Благо, что его исходный аналог OnlyOffice — до сих пор является open source и позволяет понять многие моменты в работе. По пути я изучил „с нуля“ совсем не характерные для моих прежних интересов frontend разработку и язык JavaScript (но экспертом здесь я так и не стал, так что мои решения могут для опытных в этих вопросах программистов показаться дилетантскими, что так и есть!). Заодно узнал много нового для себя из мира BI, так как никогда не тяготел к этому направлению. Так же успел опробовать много разных способов решения задач связи между офисным редактором и внешним миром. Поучаствовал в проектах по переводу макросов из MS Office в Р7 для очень крупного заказчика и ощутил всю "боль" таких работ! Создал свой редактор для макросов в Р7 и разработал модульную систему для упрощения работы в его макросах. А так же, ещё много чего, о чем я рассказывать не буду из‑за контрактных обязательств. В силу определённых обстоятельств, я теперь снова „в свободном плаванье“, и бывшему работодателю желаю всяческих успехов, ибо продукты мы сделали классные! Надеюсь, у него всё получится далее и без моей помощи!
Но мой накопленный опыт и знания — они со мной, и продолжают „мучать“ мой пытливый мозг. Я продолжаю уже чисто самостоятельно свои поиски и предлагаю вам, ознакомится с некоторыми моими личными наработками!

Кратко про «Р7»

Офисный пакет «Р7», видимо исходя из реализации идей «мультиплатформенности», являет собой скомбинированное в одно целое,   клиент-серверное web приложение. "Бэкэнд" часть написана на высокоуровневых  языках  C#  и С++, с использование фреймфорка Qt (для десктоп и мобильных решений)  и отвечает за внутренние механизмы по работе с  документом и рендеринг содержимого пользователю. А "фронтэнд" предоставляет собой пользовательский графический интерфейс и АПИ для автоматизации. Причем, запускается этот «комбайн» сразу как одно целое приложение, и вся «кухня» по взаимодействию этих двух  частей скрыта от глаз пользователя.
Поскольку в работу бэкэнда мы вмешиваться не можем, то нам оставляют лишь возможность работать только на уровне фронэнда.  Вот про это я и буду дальше говорить.

Что же такое « frontend» слой в «Р7»?

Наверное, для упрощения себе жизни (но не нам!), разработчики «OnlyOffice/Р7», решили построить графический интерфейс с пользователем, а заодно и АПИ любой автоматизации, на базе хорошо обкатанного и надежного web движка браузера Chromium. Думаю, особо представлять его нет смысла, ибо на его ядре крутится, наверное, где-то 80-90% всех веб-браузеров. Chromium, если верить статье на Википедии,   сам по себе давно opensource  (с 2008 года), и открыт под BCD лицензией.  На  его базе построено помимо браузеров, ещё и  огромное число так называемых WebApp  - приложений, которые чаще всего используют ядро для построения графического интерфейса, простого в разработке за счет  использования языка разметки HTML в связке с каскадными таблицами стилей CSS  и скриптовым языком JavaScript. По этому же принципу построена и видимая пользователям часть редактора «Р7».  Но конечно же, всё не так просто! Разработчиками  была проделана очень большая работа, для интеграции АПИ базового ядра редактора с кодом Chromium-а.

Написанное  АПИ для вызовов из javascript   весьма обширное и покрывает многие аспекты работы редакторов (пишу именно так, во множественном числе, потому что  в бэкэнд ядре их несколько, как минимум три – текстовый, табличный и презентаций). Но открытая и документированная для пользователя часть, представляет собой значительно урезанную версию всего АПИ, которая оставляет «за скобками» очень многие потребности в работе!  На момент написания статьи, к примеру, в табличном редакторе нет, официального АПИ доступа к сводным таблицам, к фильтрам ячеек,к некоторым аспектам форматирования и много ещё к чему. А те функции АПИ что открыты -  зачастую имеют либо довольно много багов, либо скрытых «особенностей», которые мало того что никак не документированы, но и по сути чаще всего не признаются как баги. И в итоге, это всё, для программиста отдельная головная боль!

Ну и что же делать, если официального АПИ оказалось мало для решения задач, а решать их надо?
К счастью, для пытливого ума нет преград! Если перевести редактор с помощью ключа загрузки «-ascdesktop-support-debug-info» (он кстати сам по себе наследие использования Chromium) в режим с запуска с возможностью отладки, то контекстным меню, например  на контролах или формах редактора, можно выводить привычный для  многих пользователей браузеров DevTools:

Вызов отладчика DevTools в Р7
Вызов отладчика DevTools в Р7

А  в нём уже(ура! ),  можно получать, переведя редактор или плагин  в останов,  доступ к внутренним глобальным объектам самого редактора:

Глобальные объекты в отладчике, в том числе и для доступа к документам
Глобальные объекты в отладчике, в том числе и для доступа к документам

И это значит - есть возможность  увидеть  остальное javascript АПИ текущего редактора (хотя бОльшая часть из него обсфуркцированая и мало что даст), которое не описывается официально, и через которое можно получать доступ к управлению большинством официально скрытых объектов в модели данных документов!

Впрочем, тут  есть огромное НО! Для 99% пользователей, это скорее пагубный путь, ибо любое малейшее неверное использование этого АПИ приводит в лучшем случае к краху документа! В худшем -  к «падению» всего редактора, даже без возможности сохранить документ! Тем не менее, о  малой части  из этого скрытого АПИ, которая более-менее уже исследована и может использоваться  сравнительно безопасно, я вам поведаю, так как для многих стоявших передо мной (думаю и не только передо  мной) задач, просто не существует пока иного пути, кроме как использовать такие вот «костыли» в виде скрытых функций АПИ.

Сразу обозначу: у меня нет возможности и задачи расписывать все особенности и всё скрытое АПИ, которым можно пользоваться для целей автоматизации. Я и сам его не знаю в должной мере, ибо никогда не ставил себе такую цель  - глубоко узнать все скрытые возможности. Да и тема у меня сейчас так же очень узкая. Скрытое  же АПИ весьма обширное и в разы превосходит официальное.

Особенности объектной модели документов в «Р7»

Так как я не знаю уровень подготовки читающих этот текст, я так же опишу свой взгляд (в малом объеме из того, что мог бы расписать) на некоторые  особенности открытой части АПИ в «Р7», из-за которых приходится городить весь  этот «огород» в дальнейшем.

  1. У вас нет возможности записать свои ручные действия и далее воспроизвести их, чтобы автоматизировать таким способом какие-то свои  рутинные ручные действия. Даже в «МойОфис» такая функция есть, а вот в «Р7» – извините! Только хардкор! Только ручное набивание кода с полным предварительным пониманием, что вы хотите добиться, а как это можно сделать.

  2. Забудьте о самом верхнем уровне абстракции модели классов в «MS Office» – Application! В модели «Р7» просто нет некой главенствующей части, которая бы собой символизировала сам редактор, и предоставляла бы сервисные функции предназначенные для координации работы пользователя в целом. Вы НЕ СМОЖЕТЕ, к примеру, получить список открытых в редакторах  документов. И доступа к другим открытым документам получить не сможете! В API  «Р7» вы можете получить доступ ТОЛЬКО  к текущему документу в котором вы вызываете макрос или плагин!

  3. Так же вам не удастся, к примеру, штатно в фоновом режим подгружать документы в редактор, для считывания из них каких-либо данных. С недавних пор можно  использовать внешние ссылки на такие документы. Тогда связанные по ссылке данные будут считываться при открытии основного документа или при его  принудительном обновлении. Но через АПИ этот процесс просто недоступен! Да и сам линки  все равно остаются пока ненадёжным и часто глючат.  Поэтому, для гарантированной надежности получения данных, в итоге приходится городить загрузку документов в память плагина или макроса сторонними js библиотеками (если такие  есть для нужного формата документов). Или же использовать внешние средства в виде запущенных во вне редактора  вэб прокси серверов, и получать доступ к файлам с их помощью (на чем сейчас строится уже целая своя, небольшая индустрия, но сейчас не про неё).

  4. Объектная модель документов, лишь внешне напоминает ту, что имеется в «MS Office». В целом применяются похожие структуры данных и их иерархии. Названия объектов, атрибутов и методов почти одинаковые везде, для схожих  по своей сути частей документа. Но особенности языка плюс видимо какие - то свои мысли разработчиков, иногда дают другое наименование функций и некоторых объектов. И если копать глубже, то приходишь к выводу: эти  аналогии зачастую - довольно поверхностные и поэтому чаще всего не выйдет напрямую транслировать синтаксические названия при переводе макроса из «МС Офиса» на  VBA  в макросы «Р7» на javascript.  Кстати, именно поэтому, обычно не получается у Искусственного Интеллекта писать  даже сравнительно простые макросы сразу работающими, так как ИИ быстро начинает галлюцинировать несуществующими в АПИ «Р7(OnlyOffice)» объектами,  функциями и атрибутами, придумывая их на ходу,  по аналогии с известными ему АПИ объектной модели  из микрософтовского офиса,  референсным для подобных задач.

  5. Как следствие из предыдущего пункта, и из-за разности базовых особенностей языков, которые используются для автоматизации, не всегда аналогичны и аргументы и их последовательность при вызовах методов классов. Поэтому, у вас всегда должна быть под рукой шпаргалка по фукнциям АПИ, или же настроено автодополнение, чтобы не ошибиться, что и в какой последовательности вы передаёте при вызовах функций. Поскольку javascript типо-независимый язык, то очень легко передать внутрь не ту последовательность данных, и потом очень долго вылавливать ошибки, которая появляются из-за этого, но о которых чаще всего, консоль отладчика пользователя  просто не оповещает!

  6. Однопоточная модель работы javascript.При больших объемах расчётных данных, которые нужно прогнать через макрос или плагин,  это просто огромная «боль» из-за медлительности всех действий. Ещё и  вся «красота» для сложных алгоритмов требующих последовательно-параллельных ветвлений в рабочих алгоритмах. Кое-что для выполнения подобных алгоритмов конечно можно реализовывать через Promise, но это все равно приводит к сильному  ухудшению понимания js кода. Не говоря уже про то, что  вся внутренняя работа с данными в общем то идет в асинхронном режиме, что может приводить к неопределённости конечных результатов, так как не всегда понятно, какие действия пользователя внутри документа окончатся первыми, и что выводится в итоге как результат для вызов через callCommand() в плагинах. А в макросах что либо серьезное писать по обработке данных даже не стоит и пробовать! В общем, не предназначен javascript изначально для таких задач, и поэтому и написание сложных алгоритмов обработки данных, это задача не для слабаков.

  7. Странные методологические просчеты разработчиков. Некоторые,  в общем  очевидные  за долгие годы работы миллионов пользователей методы, просто не предусмотрены изначально. Вот, например, не отключается расчет формул и перерисовка экрана при изменении данных в таблицах. Если в листах  есть формулы в больших количествах, то любые действия в документах по изменению данных  приводят к запуску циклов расчетов по всей книге сразу! И это никак не отменить, даже пользователем через меню самого редактора! Не предусмотрено, и всё!

  8. Песочница в макросах. Макросы по сути – это вызов функции eval(), в которую передается записанный как строка код макроса. Процедура опасная и при любых неверных действиях – приводящая к серьезным проблемам. Поэтому написать нормально работающий макрос, который чуть сложнее, чем раскрашивание ячеек по цветам – это целое искусство, требующее терпения и хороших навыков по отладке в javascript.  Я бы вообще рекомендовал: сперва написать код для макроса и отладить его в куда более безопасных плагинах, и лишь потом сразу «оптом» переносить его в документы как макрос (сам  часто так и делаю).  Сам круг задач для макросов из-за использования для их выполнения eval(), сильно ограничен простыми задачами. Большой  код для макросов лучше не писать!

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

  10.  Все действия кода внутри eval() только в ‘strict mode’ (строгий режим), а значит - любая ошибка с объявлениями переменных приводит к остановкам выполнения, которые начинающим трудно понять и устранить. Отладить код макроса можно, по сути, только расставив ‘debugger’ в коде макроса и только потом при остановке в DevTools искать причины ошибок. Но если вы уже крутой программист на js, то все эти проблемы можно обойти или хотя бы - приглушить, и писать довольно серьезные макросы, «с подкидным и девушками пониженной социальной ответственности», как говорится. Часть решений я уже придумал за вас, и покажу вам возможные пути.

Думаю, дальше продолжать смысла нет, ибо проблем увы хватает и на их описание с разбором, можно потратить не одну статью (но я буду о них писать в других своих источниках, так что, как модно сейчас у блоггеров : «лайк и подписка» на них!). Моя же цель сейчас не ввести вас в депрессию, а напротив показать что и в «Р7» можно решать многие сложные задачи, только надо знать – как?!
В следующих статьях я опишу пка лишь одну из проблем, которую трудно решить штатными методами, и о которой я не писал в списке проблем: способы взаимодействия с пользователем из макросов.Сперва, я напишу про методы, которыми можно это сделать.  И делать нам это придется сразу в нештатным АПИ.

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

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