В чем смысл конструкции ОбщегоНазначения.ОбщийМодуль и зачем она используется в 1С

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

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

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

Проблема жестких связей в конфигурации

Рассмотрим стандартную ситуацию: в коде одного модуля мы напрямую вызываем процедуру из другого модуля. Проанализируем, что происходит на уровне платформы. Система создает жесткую статическую связь. Если в конфигурации по какой-то причине будет отсутствовать целевой общий модуль (например, его забыли объединить или намеренно удалили подсистему), то вся конфигурация не пройдет проверку синтаксиса и просто не запустится.

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

Обеспечение модульности и внедрение БСП по частям

Одной из ключевых особенностей БСП является возможность её выборочного внедрения. Разработчик может включить в свою конфигурацию только те подсистемы, которые ему необходимы (например, «Контактная информация» и «Печать», но без «ЕГАИС» или «Маркировки»).

Выясним, как ведет себя код в таких условиях. Если бы разработчики БСП использовали прямые вызовы, им пришлось бы писать сотни условий #Если (директив препроцессора) или постоянно вручную комментировать участки кода при исключении подсистем. Благодаря конструкции ОбщийМодуль(), код остается универсальным. Рассмотрим логику, которую предлагает БСП:

  1. Система проверяет наличие подсистемы в метаданных.
  2. Если подсистема есть, она получает ссылку на её общий модуль через строку.
  3. Если подсистемы нет, вызов просто игнорируется или обрабатывается исключением, не прерывая работу всей программы.

Пример использования: проверка наличия подсистемы

Разберем конкретный пример кода, который часто встречается в проектах, где функционал может быть отключен или физически удален из метаданных. Допустим, нам нужно вызвать метод подсистемы взаимодействия с ЕГАИС, но мы не уверены, что она присутствует в данной сборке программы.


Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ИнтеграцияЕГАИС") Тогда
    МодульЕГАИС = ОбщегоНазначения.ОбщийМодуль("ИнтеграцияЕГАИСВызовСервера");
    Результат = МодульЕГАИС.ИнициироватьИнтерфейс();
КонецЕсли;

В данном примере, если подсистемы ИнтеграцияЕГАИС нет в дереве конфигурации, программа не «вывалится» с ошибкой при запуске. Условие просто не выполнится, и код пойдет дальше. Это критически важно для тиражных решений, которые имеют множество вариантов поставки.

Динамический вызов и универсальные механизмы

Иногда имя модуля заранее неизвестно и определяется данными из базы (например, оно хранится в регистре сведений или справочнике). Проанализируем ситуацию, когда необходимо реализовать паттерн «Стратегия», где алгоритм обработки зависит от настроек пользователя.

Вместо громоздких конструкций Если... ИначеЕсли, можно использовать программное получение модуля:


ИмяМодуля = НастройкиОбработки.ИмяОбщегоМодуля; // Получаем строку "МодульОбработкиЗаказов"
МодульОбработчик = ОбщегоНазначения.ОбщийМодуль(ИмяМодуля);
МодульОбработчик.ВыполнитьДействие(Параметры);

Этот подход делает код лаконичным и позволяет добавлять новые модули-обработчики без изменения основного алгоритма вызова. Достаточно прописать имя нового модуля в настройках.

Влияние на разработку и поддержку

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

Для минимизации этих неудобств опытные разработчики рекомендуют использовать специальные комментарии для системы 1С:Enterprise Development Tools (EDT) или просто оставлять пояснения для коллег. Также в последних версиях платформы и БСП механизмы анализа кода становятся умнее, но «строковый» вызов всегда будет требовать чуть больше внимания при поиске связей.

Техническая реализация внутри БСП

Если мы заглянем «под капот» функции ОбщегоНазначения.ОбщийМодуль(), то увидим, что она чаще всего использует оператор Вычислить(). Это встроенная функция платформы 1С, которая исполняет строку как фрагмент кода.

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

  1. Принимается строка с именем модуля.
  2. Проверяется, не является ли строка пустой.
  3. Выполняется команда Возврат Вычислить(ИмяМодуля);.

Благодаря этому возвращается объект (общий модуль), к экспортным методам которого можно обращаться через точку. Хотя Вычислить() работает чуть медленнее прямого обращения, в масштабах бизнес-логики (например, при записи документа или формировании отчета) эта задержка абсолютно незаметна и составляет миллисекунды.

Выводы

Мы выяснили, что конструкция ОбщегоНазначения.ОбщийМодуль() — это не «бред» и не попытка искусственно усложнить жизнь программисту. Это осознанный инструмент для достижения следующих целей:

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

← На главную