При работе с платформой 1С:Предприятие часто возникает задача, связанная с необходимостью получить доступ к уже исполняемому коду, повторно использовать его или даже динамически выполнить фрагменты кода. Эта задача может быть интерпретирована по-разному: от желания "вытащить" текст процедуры из замера производительности до потребности в интеграции функционала между различными базами или динамического исполнения строк кода. Давайте вместе разберемся в возможных подходах и инструментах, которые предоставляет платформа 1С для решения этих задач.
Если наша цель — не извлечь уже существующий код из конфигурации, а динамически выполнить строку кода, которую мы формируем в процессе работы программы, то платформа 1С предоставляет для этого специальные операторы.
Выполнить()Оператор Выполнить() (или Execute() в англоязычном варианте) позволяет выполнить произвольный блок кода, переданный в виде строки. Это мощный инструмент для создания гибких и настраиваемых решений. Мы можем использовать его для выполнения различных команд встроенного языка, но есть важные ограничения, которые следует учитывать:
Выполнить(), невозможно объявить новые процедуры или функции.Возврат: Если нам нужно получить результат выполнения, мы не можем использовать прямой возврат значения. Вместо этого, мы должны присвоить результат заранее определенной переменной, которая будет доступна после выполнения блока кода.Рассмотрим пример использования Выполнить():
Перем РезультатВыполнения;
ТекстКода = "
Число1 = 10;
Число2 = 20;
РезультатВыполнения = Число1 + Число2;
";
Выполнить(ТекстКода);
Сообщить("Результат выполнения: " + РезультатВыполнения); // Выведет "Результат выполнения: 30"
В этом примере мы объявляем переменную РезультатВыполнения до вызова Выполнить(), и затем внутри динамически исполняемого кода присваиваем ей значение. Это позволяет нам получить результат работы динамического кода.
ВычислитьВыражение()Для более простых случаев, когда нам нужно вычислить одно выражение и получить его результат, мы можем использовать оператор ВычислитьВыражение(). Этот оператор принимает строку, содержащую выражение, и возвращает результат его вычисления. Он идеально подходит для ситуаций, где требуется получить значение на основе динамически формируемого выражения.
Посмотрим на пример:
СтрокаВыражения = "2 + 2 * 3";
Результат = ВычислитьВыражение(СтрокаВыражения);
Сообщить("Результат выражения: " + Результат); // Выведет "Результат выражения: 8"
ПеременнаяДляВычисления = 100;
ЕщеОдноВыражение = "ПеременнаяДляВычисления / 10";
Результат2 = ВычислитьВыражение(ЕщеОдноВыражение);
Сообщить("Еще один результат: " + Результат2); // Выведет "Еще один результат: 10"
Важно понимать, что оба эти оператора выполняют код в текущем контексте, имея доступ к объявленным переменным и глобальным функциям.
Иногда возникает задача не выполнить код, а получить его текстовое представление, например, для анализа, переноса или модификации. Платформа 1С напрямую не предоставляет функции для программного извлечения текста процедур и функций из модулей во время работы в режиме 1С:Предприятие. Однако, мы можем использовать обходные пути, связанные с выгрузкой конфигурации.
Одним из наиболее эффективных способов получить доступ к коду конфигурации является ее выгрузка в файлы. Этот механизм доступен в режиме Конфигуратора и позволяет получить всю структуру конфигурации, включая текст модулей, в виде набора текстовых файлов (XML, TXT и т.д.). Основной файл выгрузки — Configuration.xml, но код процедур и функций будет находиться в отдельных файлах модулей.
После выгрузки мы можем программно обрабатывать эти файлы. Для чтения текста из файлов в 1С мы можем использовать объект ТекстовыйДокумент или ЧтениеТекста (TextReader).
Рассмотрим шаги, как мы могли бы это сделать:
ЗамерПроизводительности), мы можем открыть соответствующий файл модуля и найти нужную процедуру или функцию по имени.Пример чтения файла:
ИмяФайлаМодуля = "C:\ПутьКВыгрузке\ОбщиеМодули\МойОбщийМодуль.bsl"; // Пример пути
Попытка
Чтение = Новый ЧтениеТекста(ИмяФайлаМодуля, КодировкаТекста.UTF8);
ТекстМодуля = Чтение.ПрочитатьДоКонца();
Чтение.Закрыть();
Сообщить("Содержимое модуля:" + Символы.ПС + ТекстМодуля);
Исключение
Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
КонецПопытки;
Однако, у этого подхода есть существенные недостатки, как мы выяснили в ходе обсуждения:
Поэтому, этот метод чаще используется для анализа кода разработчиком, а не для автоматизированного переноса функционала.
Когда речь идет о модификации или доработке существующих типовых конфигураций без снятия их с поддержки, расширения конфигурации являются наиболее предпочтительным и современным способом. Этот механизм позволяет "внедрять" новый код или изменять поведение существующего, не затрагивая основную конфигурацию.
Рассмотрим, как расширения помогают нам:
&Вместо, &Перед, &После, мы можем перехватывать вызовы процедур и функций основной конфигурации, изменять их логику или дополнять ее.Например, если нам нужно изменить поведение существующей процедуры МояПроцедура в общем модуле основной конфигурации, мы можем создать расширение и в нем определить такую же процедуру с аннотацией &Вместо:
// В расширении, в общем модуле с тем же именем, что и в основной конфигурации
&Вместо("МояПроцедура")
Процедура МояПроцедура_Вместо(Параметр1, Параметр2)
// Здесь мы можем реализовать свою логику,
// которая полностью заменит исходную процедуру.
Сообщить("Выполнена процедура из расширения!");
// Если нужно вызвать исходную процедуру, используем:
// ПродолжитьВызов(Параметр1, Параметр2);
КонецПроцедуры
Расширения — это мощный инструмент для адаптации и доработки, особенно актуальный для "самописок" или старых конфигураций, в которые необходимо внедрять функционал БСП (Библиотеки стандартных подсистем) или другой типовой логики. При правильном использовании расширения позволяют избежать головной боли при обновлении основной конфигурации.
Иногда задача "получить исполненный код" означает не извлечение текста, а вызов функционала из одной информационной базы в другой. Для этого существуют различные механизмы интеграции:
HTTP-сервисы являются одним из наиболее гибких и современных способов организации взаимодействия между базами 1С, особенно если базы расположены удаленно или нужно обеспечить взаимодействие через интернет. Мы можем опубликовать экспортные функции общего модуля или модуля объекта как HTTP-сервис, который будет доступен для вызова из других систем.
При использовании HTTP-сервисов важно тщательно продумать структуру передаваемых параметров (документов, справочников и т.д.), так как они должны быть сериализуемы и понятны обеим сторонам.
Для взаимодействия между базами 1С, расположенными на одном компьютере или в одной локальной сети, часто используется COM-соединение. Это позволяет одной базе выступать в роли COM-клиента и вызывать экспортные процедуры и функции другой базы (COM-сервера), а также работать с ее объектами.
Рассмотрим пример установки COM-соединения и вызова функции:
Попытка
COMСоединение = Новый COMОбъект("V83.COMConnector");
// Устанавливаем соединение с информационной базой
// СтрокаПодключения может быть: "File=""C:\Базы\МояБаза"";Usr=""Пользователь"";Pwd=""Пароль"""
СтрокаПодключения = "Srvr=""ИмяСервера:Порт"";Ref=""ИмяБазы"";Usr=""Пользователь"";Pwd=""Пароль""";
База = COMСоединение.Connect(СтрокаПодключения);
// Вызываем экспортную функцию в удаленной базе
Результат = База.МойОбщийМодуль.МояЭкспортнаяФункция(Параметр1, Параметр2);
Сообщить("Результат вызова функции через COM: " + Результат);
Исключение
Сообщить("Ошибка при работе с COM-соединением: " + ОписаниеОшибки());
КонецПопытки;
Однако, COM-соединение не подходит для работы через интернет.
Помимо HTTP-сервисов и COM, существуют и другие методы для обмена данными и функционалом:
Для эффективного повторного использования кода внутри одной конфигурации, крайне важно правильно структурировать его с помощью общих модулей. Общие модули предназначены для хранения процедур и функций, которые вызываются из разных частей системы.
Мы должны размещать повторяющийся код в общих модулях, чтобы избежать дублирования и упростить поддержку. Общие модули могут быть:
Пример вызова серверной экспортной функции из клиентского кода:
// В ОбщемМодуле1 (свойство "Сервер" установлено)
Функция МояСервернаяФункция(Параметр) Экспорт
// Логика, выполняющаяся на сервере
Возврат Параметр * 2;
КонецФункции
// В МодулеФормы (клиентский код)
Процедура ПриНажатииКнопки()
Результат = ОбщийМодуль1.МояСервернаяФункция(5);
Сообщить("Результат с сервера: " + Результат); // Выведет "Результат с сервера: 10"
КонецПроцедуры
Правильная организация кода в общих модулях значительно упрощает его повторное использование и поддержку.
Как мы видим, задача "получить исполненный код" в 1С может иметь множество интерпретаций и, соответственно, множество решений. Выбор конкретного подхода всегда зависит от нашей цели:
Выполнить() или ВычислитьВыражение().Всегда тщательно анализируйте задачу и выбирайте наиболее подходящий инструмент, чтобы создать надежное и поддерживаемое решение.
← К списку