При разработке в конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как «1С:Документооборот», «Зарплата и управление персоналом 3.1» или «1С:ERP», программисты часто сталкиваются с задачей: получить значение дополнительного реквизита еще до того, как объект будет записан в базу данных — для этого подойдёт комплект инструментов для разработки и отладки кода БСП. Сложность заключается в том, что дополнительные реквизиты не являются статичными метаданными — они добавляются на форму динамически в момент её создания.
В этой статье мы подробно разберем, как программно «достучаться» до этих данных, проанализируем структуру их имен и рассмотрим наиболее надежные способы решения задачи.
Самый быстрый, но требующий понимания внутренней логики БСП способ — это обращение к реквизиту формы по его уникальному имени. Имя динамического реквизита на форме генерируется по определенному шаблону. Рассмотрим, как это работает.
Имя элемента обычно строится следующим образом:
ДополнительныйРеквизитЗначение_ [GUID Набора] _ [GUID Свойства]
При этом важно помнить, что в именах реквизитов 1С символы дефиса в GUID заменяются на латинскую букву x. Разберем пример кода, который позволяет получить значение, зная эти идентификаторы:
// Пример обращения к реквизиту на клиенте
ИмяРеквизита = "ДополнительныйРеквизитЗначение_A8E213D4x0433x11E9x8E47x002590D75ACA_90981DC8x08DBx11E9x8E47x002590D75ACA";
ЗначениеРеквизита = ЭтаФорма[ИмяРеквизита];
Сообщить("Текущее значение: " + ЗначениеРеквизита);
Плюсы: Работает мгновенно на клиенте без серверных вызовов.
Минусы: Жесткая привязка к GUID делает код негибким. Если доп. реквизит будет пересоздан, код перестанет работать.
Более правильный и универсальный метод — использование коллекции Свойства_ОписаниеДополнительныхРеквизитов, которая присутствует на форме объекта в конфигурациях БСП. Эта коллекция содержит сопоставление ссылок на свойства (из ПВХ ДополнительныеРеквизитыИСведения) и реальных имен реквизитов на форме.
Давайте проанализируем алгоритм поиска нужного значения по шагам:
Свойство совпадает с нашей ссылкой.ИмяРеквизитаЗначение.Рассмотрим реализацию этого метода:
&НаКлиенте
Процедура ПолучитьЗначениеДопРеквизита()
// 1. Получаем ссылку на доп. реквизит (лучше кешировать или передавать с сервера)
СсылкаНаСвойство = ПолучитьСсылкуНаСвойствоСервер("Вид работ");
НазваниеРеквизитаНаФорме = "";
// 2. Ищем имя программного реквизита в служебной коллекции формы
Для Каждого Описание Из Свойства_ОписаниеДополнительныхРеквизитов Цикл
Если Описание.Свойство = СсылкаНаСвойство Тогда
НазваниеРеквизитаНаФорме = Описание.ИмяРеквизитаЗначение;
Прервать;
КонецЕсли;
КонецЦикла;
// 3. Получаем значение из динамического реквизита формы
Если ЗначениеЗаполнено(НазваниеРеквизитаНаФорме) Тогда
ЗначениеВидРабот = ЭтаФорма[НазваниеРеквизитаНаФорме];
Сообщить("Выбран вид работ: " + ЗначениеВидРабот);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьСсылкуНаСвойствоСервер(ИмяСвойства)
Возврат ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию(ИмяСвойства);
КонецФункции
Многие начинающие разработчики пытаются найти значения в табличной части Объект.ДополнительныеРеквизиты (или Объект.ДополнительныеЗначения в «1С:Документооборот»). Однако часто в процедуре ПередЗаписью эта таблица оказывается пустой — для таких случаев есть инструмент динамической настройки контроля ввода данных. Почему так происходит?
Дело в том, что БСП синхронизирует данные между динамическими реквизитами формы и табличной частью объекта непосредственно в момент записи. Чтобы принудительно «протолкнуть» данные из формы в переменную Объект на клиенте, можно использовать метод:
ЭтаФорма.ЗаписатьВОбъект();
После этого вызова в серверном контексте можно будет найти значение простым перебором табличной части:
&НаСервере
Процедура ПроверитьДопРеквизитыВОбъекте()
Для Каждого СтрокаДопРеквизита Из Объект.ДополнительныеРеквизиты Цикл
// Здесь можно обращаться к СтрокаДопРеквизита.Свойство и СтрокаДопРеквизита.Значение
// Данные уже будут актуальны, даже если документ еще не записан в БД
КонецЦикла;
КонецПроцедуры
Если ваша конфигурация достаточно современная, рекомендуется использовать методы общего модуля УправлениеСвойствами. Это наиболее «чистый» способ с точки зрения архитектуры 1С.
Функция УправлениеСвойствами.ЗначениеСвойства(Объект, Свойство) позволяет получить значение, абстрагируясь от того, где оно находится — на форме или в базе данных. Проанализируем пример использования этого программного интерфейса:
// На сервере
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Вид ремонта");
Значение = УправлениеСвойствами.ЗначениеСвойства(Объект, СвойствоСсылка);
Если Значение = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Капитальный ремонт") Тогда
// Выполняем логику по установке обязательных связей
КонецЕсли;
При работе с расширениями в «1С:Документооборот» или другими крупными системами в клиент-серверном режиме разработчики часто жалуются, что точки останова не срабатывают — поможет инструмент для пошаговой отладки кода 1С в режиме Предприятия. Без отладчика крайне сложно понять, почему Объект.ДополнительныеРеквизиты кажется пустым.
Для решения этой проблемы убедитесь, что:
-debug.Резюме: Если вам нужно быстрое решение на клиенте — используйте ЭтаФорма[ИмяРеквизита] через поиск в коллекции Свойства_ОписаниеДополнительныхРеквизитов. Если вы работаете на сервере в процедурах обработки данных — используйте методы модуля УправлениеСвойствами или принудительную синхронизацию через ЗаписатьВОбъект().