Как обратиться к экспортной процедуре или функции другого справочника в 1С?

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

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

Вызов экспортного метода из модуля объекта

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

Для обращения к методу модуля объекта требуется экземпляр этого объекта. Если логика привязана к конкретному элементу базы данных, алгоритм вызова выглядит следующим образом:

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

Посмотрим на пример кода с безопасной проверкой полученных данных:


СсылкаНаЭлемент = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1");
Если Не СсылкаНаЭлемент.Пустая() Тогда
    ОбъектСправочника = СсылкаНаЭлемент.ПолучитьОбъект();
    Результат = ОбъектСправочника.НашаЭкспортнаяФункция();
КонецЕсли;

Важные риски прямого вызова через ПолучитьОбъект():

  1. Ошибка времени выполнения: если поиск не найдет элемент, метод вернет пустую ссылку. Попытка вызвать метод ПолучитьОбъект() от пустой ссылки вызовет аварийное падение программы с ошибкой «Значение не является значением объектного типа».
  2. Неоправданная нагрузка на СУБД: метод ПолучитьОбъект() полностью считывает все данные элемента, включая табличные части. Если функция не изменяет и не использует специфические данные конкретной записи, чтение объекта создает лишнюю нагрузку.
  3. Транзакционные блокировки: при вызове ПолучитьОбъект() внутри транзакции накладываются блокировки на запись таблицы базы данных, что может приводить к конфликтам блокировок при многопользовательской работе.

Инициализация объекта без поиска в базе данных

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


НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
Результат = НовыйОбъект.НашаЭкспортнаяФункция();

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

Оптимальное решение: перенос кода в модуль менеджера

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

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

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


// В модуле менеджера справочника Номенклатура:
// Функция РассчитатьСкидку(Сумма) Экспорт
// ...
// КонецФункции

// Вызов из любого другого справочника или документа:
Результат = Справочники.Номенклатура.РассчитатьСкидку(1000);

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

Универсальный подход: вынос логики в общий модуль

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

Разберем порядок действий:

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

Пример прямого вызова:


Результат = РасчетныеМеханизмыСервер.НашаУниверсальнаяФункция(Параметр1, Параметр2);

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

Контекст выполнения на клиенте и сервере

Обратим внимание на клиент-серверное разделение платформы: модули объектов и модули менеджеров справочников выполняются исключительно на стороне сервера. При работе в управляемом интерфейсе обратиться напрямую к методам Справочники... из клиентских процедур формы (с директивой &НаКлиенте) невозможно. Для выполнения таких операций необходимо перейти в контекст сервера с помощью директив &НаСервере или &НаСервереБезКонтекста.

← На главную