При разработке в среде 1С:Предприятие 8 часто возникает необходимость автоматизировать заполнение служебных реквизитов. Типичный пример — запись системного имени справочника в специальный реквизит элемента при его изменении или перед записью в базу данных. Это может потребоваться для интеграционных процессов, ведения логов, построения универсальных отчетов или динамического управления правами доступа.
В этой статье мы подробно разберем, как решить эту задачу наиболее оптимальным и изящным способом, рассмотрим разницу между свойствами метаданных, а также проанализируем различные варианты реализации в зависимости от контекста выполнения кода.
Прежде чем переходить к написанию кода, давайте разберемся, как платформа 1С хранит информацию о структуре объектов конфигурации. Объект метаданных справочника имеет несколько ключевых свойств, которые начинающие разработчики часто путают между собой:
Имя — это уникальный идентификатор объекта в конфигураторе (например, Номенклатура или Контрагенты). Именно это имя используется в программном коде для обращения к таблицам базы данных. Метод возвращает значение типа Строка.Синоним — это понятное пользователю представление объекта, которое отображается в интерфейсе системы (например, Товары и услуги). Синоним может быть локализован на разные языки.ПолноеИмя() — это метод, который возвращает тип объекта конфигурации вместе с его именем через точку (например, Справочник.Номенклатура). Очень полезно при написании универсальных обработок и запросов.Для решения нашей задачи — заполнения реквизита ИмяСправочника — нам понадобится именно свойство Имя, так как оно стабильно, не зависит от интерфейсного языка пользователя и однозначно определяет объект метаданных.
Рассмотрим наиболее надежный способ решения задачи. Если логика заполнения реквизита должна срабатывать всегда, независимо от того, как именно элемент записывается в базу (вручную пользователем через форму, программно при обмене данными, или при загрузке из внешнего файла), код необходимо размещать в модуле объекта справочника.
Для этого мы задействуем предопределенный обработчик события ПередЗаписью. Проанализируем пример реализации:
Процедура ПередЗаписью(Отказ)
// Проверяем, заполнено ли наименование элемента справочника
Если ЗначениеЗаполнено(Наименование) Тогда
// Получаем имя текущего справочника через метаданные объекта
// Конструкция ЭтотОбъект.Метаданные().Имя вернет строку "Номенклатура"
ИмяСправочника = ЭтотОбъект.Метаданные().Имя;
КонецЕсли;
КонецПроцедуры
Почему этот вариант оптимален?
ЭтотОбъект.Метаданные() работает мгновенно, так как контекст объекта уже содержит ссылку на его описание в конфигурации.Иногда требуется, чтобы пользователь видел заполненное системное имя справочника на экране сразу же, как только он введет или изменит наименование на форме, еще до нажатия кнопки «Записать».
Здесь важно помнить об особенностях архитектуры управляемого приложения 1С. На клиенте переменная Объект является не полноценным справочником, а имеет тип ДанныеФормыСтруктура. У этого типа данных нет прямого метода Метаданные(). Попытка вызвать его на клиенте приведет к синтаксической ошибке.
Рассмотрим два пути решения этой проблемы в модуле управляемой формы.
Поскольку форма конкретного справочника жестко привязана к своему типу объекта, мы можем использовать простую текстовую строку. Это самый быстрый способ, не требующий обращения к серверу:
&НаКлиенте
Процедура НаименованиеПриИзменении(Элемент)
// Напрямую присваиваем строковое значение реквизиту формы
Объект.ИмяСправочника = "Номенклатура";
КонецПроцедуры
Если мы пишем универсальный код (например, в шаблоне формы или общей форме, которая используется для разных справочников), жестко прописывать имя строкой нельзя. В этом случае нам потребуется кратковременный вызов сервера без контекста формы:
&НаКлиенте
Процедура НаименованиеПриИзменении(Элемент)
// Вызываем серверную функцию для получения имени объекта метаданных
Объект.ИмяСправочника = ПолучитьИмяСправочникаНаСервере();
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьИмяСправочникаНаСервере()
// Получаем имя справочника через глобальную коллекцию Метаданные
// Используем обращение к конкретной ветке метаданных
Возврат Метаданные.Справочники.Номенклатура.Имя;
КонецФункции
При написании программного кода в системе 1С:Предприятие крайне важно соблюдать стандарты разработки, зафиксированные на ИТС. Неправильная работа с метаданными может привести к критическому падению производительности конфигурации при увеличении объема данных.
Выделим ключевые правила оптимизации:
Метаданные.НайтиПоТипу(ТипЗнч(ЭтотОбъект)) без крайней необходимости. Глобальный поиск по всей структуре конфигурации работает значительно медленнее, чем прямое обращение к методу Метаданные() конкретного объекта.ОбщегоНазначения:
// Пример получения имени объекта метаданных с использованием механизмов БСП
ИмяОбъекта = ОбщегоНазначения.ИмяОбъектаМетаданных(ТипЗнч(Ссылка));
Использование БСП позволяет кэшировать результаты обращений к метаданным, что существенно снижает нагрузку на сервер при повторных вызовах функций.
Применяя данные подходы на практике, вы сможете создавать надежный, быстродействующий и соответствующий стандартам код, который легко пройдет любой технический аудит.