Как нам извлечь и повторно использовать уже исполняющийся код в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← К списку

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

Динамическое выполнение кода: операторы Выполнить() и ВычислитьВыражение()

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

Оператор Выполнить()

Оператор Выполнить() (или Execute() в англоязычном варианте) позволяет выполнить произвольный блок кода, переданный в виде строки. Это мощный инструмент для создания гибких и настраиваемых решений. Мы можем использовать его для выполнения различных команд встроенного языка, но есть важные ограничения, которые следует учитывать:

  1. Нельзя объявлять процедуры и функции: Внутри строки, передаваемой в Выполнить(), невозможно объявить новые процедуры или функции.
  2. Нельзя использовать ключевое слово Возврат: Если нам нужно получить результат выполнения, мы не можем использовать прямой возврат значения. Вместо этого, мы должны присвоить результат заранее определенной переменной, которая будет доступна после выполнения блока кода.

Рассмотрим пример использования Выполнить():


Перем РезультатВыполнения;
ТекстКода = "
    Число1 = 10;
    Число2 = 20;
    РезультатВыполнения = Число1 + Число2;
";
Выполнить(ТекстКода);
Сообщить("Результат выполнения: " + РезультатВыполнения); // Выведет "Результат выполнения: 30"

В этом примере мы объявляем переменную РезультатВыполнения до вызова Выполнить(), и затем внутри динамически исполняемого кода присваиваем ей значение. Это позволяет нам получить результат работы динамического кода.

Оператор ВычислитьВыражение()

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

Посмотрим на пример:


СтрокаВыражения = "2 + 2 * 3";
Результат = ВычислитьВыражение(СтрокаВыражения);
Сообщить("Результат выражения: " + Результат); // Выведет "Результат выражения: 8"

ПеременнаяДляВычисления = 100;
ЕщеОдноВыражение = "ПеременнаяДляВычисления / 10";
Результат2 = ВычислитьВыражение(ЕщеОдноВыражение);
Сообщить("Еще один результат: " + Результат2); // Выведет "Еще один результат: 10"

Важно понимать, что оба эти оператора выполняют код в текущем контексте, имея доступ к объявленным переменным и глобальным функциям.

Извлечение и анализ кода из конфигурации

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

Выгрузка конфигурации в файлы

Одним из наиболее эффективных способов получить доступ к коду конфигурации является ее выгрузка в файлы. Этот механизм доступен в режиме Конфигуратора и позволяет получить всю структуру конфигурации, включая текст модулей, в виде набора текстовых файлов (XML, TXT и т.д.). Основной файл выгрузки — Configuration.xml, но код процедур и функций будет находиться в отдельных файлах модулей.

После выгрузки мы можем программно обрабатывать эти файлы. Для чтения текста из файлов в 1С мы можем использовать объект ТекстовыйДокумент или ЧтениеТекста (TextReader).

Рассмотрим шаги, как мы могли бы это сделать:

  1. Выгрузка конфигурации: В Конфигураторе используем меню "Конфигурация" -> "Сохранить конфигурацию в файл..." или "Конфигурация" -> "Выгрузить конфигурацию в файлы...".
  2. Чтение файлов модулей: После выгрузки мы получим папки с модулями объектов, форм, общими модулями и так далее. Мы можем программно обойти эти файлы.
  3. Поиск нужного кода: Если нам нужен конкретный фрагмент кода (например, текст процедуры, которая была обнаружена через ЗамерПроизводительности), мы можем открыть соответствующий файл модуля и найти нужную процедуру или функцию по имени.

Пример чтения файла:


ИмяФайлаМодуля = "C:\ПутьКВыгрузке\ОбщиеМодули\МойОбщийМодуль.bsl"; // Пример пути

Попытка
    Чтение = Новый ЧтениеТекста(ИмяФайлаМодуля, КодировкаТекста.UTF8);
    ТекстМодуля = Чтение.ПрочитатьДоКонца();
    Чтение.Закрыть();
    Сообщить("Содержимое модуля:" + Символы.ПС + ТекстМодуля);
Исключение
    Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
КонецПопытки;

Однако, у этого подхода есть существенные недостатки, как мы выяснили в ходе обсуждения:

  1. Сложность автоматизации: Программная выгрузка конфигурации в файлы из режима 1С:Предприятие невозможна. Этот процесс требует ручных действий в Конфигураторе.
  2. Особенности модулей: Код может находиться в разных модулях (клиентских, серверных), иметь одинаковые имена процедур/функций в разных контекстах, и зависеть от метаданных, которые также нужно будет переносить.
  3. Зависимости: Простое копирование текста функции может не сработать, так как она может использовать другие процедуры, функции или объекты метаданных, которые не будут доступны в новом контексте.

Поэтому, этот метод чаще используется для анализа кода разработчиком, а не для автоматизированного переноса функционала.

Повторное использование функционала через Расширения конфигурации

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

Рассмотрим, как расширения помогают нам:

  1. Добавление нового функционала: Мы можем добавлять свои общие модули, формы, отчеты, обработки и даже изменять объекты метаданных.
  2. Изменение существующего кода: С помощью аннотаций, таких как &Вместо, &Перед, &После, мы можем перехватывать вызовы процедур и функций основной конфигурации, изменять их логику или дополнять ее.

Например, если нам нужно изменить поведение существующей процедуры МояПроцедура в общем модуле основной конфигурации, мы можем создать расширение и в нем определить такую же процедуру с аннотацией &Вместо:


// В расширении, в общем модуле с тем же именем, что и в основной конфигурации
&Вместо("МояПроцедура")
Процедура МояПроцедура_Вместо(Параметр1, Параметр2)
    // Здесь мы можем реализовать свою логику,
    // которая полностью заменит исходную процедуру.
    Сообщить("Выполнена процедура из расширения!");
    // Если нужно вызвать исходную процедуру, используем:
    // ПродолжитьВызов(Параметр1, Параметр2);
КонецПроцедуры

Расширения — это мощный инструмент для адаптации и доработки, особенно актуальный для "самописок" или старых конфигураций, в которые необходимо внедрять функционал БСП (Библиотеки стандартных подсистем) или другой типовой логики. При правильном использовании расширения позволяют избежать головной боли при обновлении основной конфигурации.

Интеграция и взаимодействие между информационными базами

Иногда задача "получить исполненный код" означает не извлечение текста, а вызов функционала из одной информационной базы в другой. Для этого существуют различные механизмы интеграции:

HTTP-сервисы

HTTP-сервисы являются одним из наиболее гибких и современных способов организации взаимодействия между базами 1С, особенно если базы расположены удаленно или нужно обеспечить взаимодействие через интернет. Мы можем опубликовать экспортные функции общего модуля или модуля объекта как HTTP-сервис, который будет доступен для вызова из других систем.

При использовании HTTP-сервисов важно тщательно продумать структуру передаваемых параметров (документов, справочников и т.д.), так как они должны быть сериализуемы и понятны обеим сторонам.

COM-соединение

Для взаимодействия между базами 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. API: Использование опубликованных прикладных интерфейсов для взаимодействия.
  2. Обмен данными через XML, CSV, JSON: Эти форматы активно используются для выгрузки и загрузки данных, а также для интеграции с внешними системами. 1С предоставляет инструменты для работы с ними.
  3. Универсальная обработка "Выгрузка и загрузка данных XML": Позволяет производить разовый или регулярный обмен данными между базами.
  4. "Конвертация данных, редакция 2" (КД2): Специализированная конфигурация для создания правил обмена данными между различными базами 1С.
  5. OData: Стандартизированный протокол для доступа к данным, который может быть использован для выгрузки данных из 1С.

Организация кода и использование общих модулей

Для эффективного повторного использования кода внутри одной конфигурации, крайне важно правильно структурировать его с помощью общих модулей. Общие модули предназначены для хранения процедур и функций, которые вызываются из разных частей системы.

Мы должны размещать повторяющийся код в общих модулях, чтобы избежать дублирования и упростить поддержку. Общие модули могут быть:

  1. Клиентскими: Выполняются на стороне клиента.
  2. Серверными: Выполняются на стороне сервера.
  3. Глобальными: Их экспортные процедуры и функции можно вызывать без указания имени модуля.

Пример вызова серверной экспортной функции из клиентского кода:


// В ОбщемМодуле1 (свойство "Сервер" установлено)
Функция МояСервернаяФункция(Параметр) Экспорт
    // Логика, выполняющаяся на сервере
    Возврат Параметр * 2;
КонецФункции

// В МодулеФормы (клиентский код)
Процедура ПриНажатииКнопки()
    Результат = ОбщийМодуль1.МояСервернаяФункция(5);
    Сообщить("Результат с сервера: " + Результат); // Выведет "Результат с сервера: 10"
КонецПроцедуры

Правильная организация кода в общих модулях значительно упрощает его повторное использование и поддержку.

Заключение

Как мы видим, задача "получить исполненный код" в 1С может иметь множество интерпретаций и, соответственно, множество решений. Выбор конкретного подхода всегда зависит от нашей цели:

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

← К списку