При программном добавлении дополнительных реквизитов в конфигурациях 1С, таких как 1С:Управление торговлей 11.4, разработчики часто сталкиваются с ситуацией, когда созданный реквизит не появляется в формах или списках до тех пор, пока его не открыть вручную в режиме предприятия и не пересохранить. Это вызывает недоумение, поскольку кажется, что все необходимые шаги по созданию объекта выполнены. Давайте разберем эту проблему и найдем ее решение.
Основная сложность заключается в том, что недостаточно просто создать элемент ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения. Этот объект лишь описывает само свойство (его заголовок, имя, тип значения), но для его полноценного функционирования в системе 1С его необходимо связать с определенным "Набором свойств" того объекта метаданных, для которого он предназначен. Без этой привязки система не будет знать, к какому справочнику или документу относится новый реквизит, и, соответственно, не отобразит его.
Изначально разработчик предложил следующий код для создания дополнительного реквизита:
Функция ПолучитьСвойство(ИмяРеквизита, НаборСвойствРеквизита, ДлинаСтроки=0)
ЭлементПВХ_Ссылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", ИмяРеквизита);
Если ЭлементПВХ_Ссылка = Неопределено ИЛИ ЭлементПВХ_Ссылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка() Тогда
ЭлементПВХ_Нов = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьЭлемент();
ЭлементПВХ_Нов.Заголовок = ИмяРеквизита;
ЭлементПВХ_Нов.Имя = ИмяРеквизита;
ЭлементПВХ_Нов.НаборСвойств = НаборСвойствРеквизита;
ЭлементПВХ_Нов.Наименование = ЭлементПВХ_Нов.Заголовок+" ("+ЭлементПВХ_Нов.НаборСвойств+")";
ЭлементПВХ_Нов.ТипЗначения = Новый ОписаниеТипов("Строка",,,,Новый КвалификаторыСтроки(ДлинаСтроки));
Попытка
ЭлементПВХ_Нов.Записать();
ЭлементПВХ_Ссылка = ЭлементПВХ_Нов.Ссылка;
Исключение
Сообщить("Не удалось создать свойство " + ИмяРеквизита);
КонецПопытки;
КонецЕсли;
Возврат ЭлементПВХ_Ссылка;
КонецФункции
Мы видим, что этот код корректно создает и заполняет элемент плана видов характеристик, определяющий дополнительный реквизит: задается заголовок, имя, тип значения и указывается НаборСвойствРеквизита. Однако, после записи элемента ЭлементПВХ_Нов.Записать(), реквизит все равно оставался "невидимым" в пользовательском интерфейсе. Причина в том, что хотя ссылка на "Набор свойств" была указана в самом реквизите, сам "Набор свойств" не был проинформирован о новом реквизите и не обновил свою структуру.
В ходе отладки и анализа, было обнаружено, что для полноценной интеграции дополнительного реквизита в систему, его необходимо не только создать, но и добавить в коллекцию дополнительных реквизитов соответствующего "Набора свойств" и затем записать сам "Набор свойств". Это критически важный шаг, который многие упускают.
Что такое "Набор свойств"?
В системе 1С "Набор свойств" (объекты типа Справочник.НаборыДополнительныхРеквизитовИСведений) представляет собой контейнер или группу дополнительных реквизитов, которые относятся к определенному объекту метаданных. Например, если мы хотим добавить доп. реквизиты к справочнику "Номенклатура", то сначала мы создаем (или находим существующий) элемент этого справочника, который будет отвечать за доп. реквизиты номенклатуры. Именно в этот элемент, в его табличную часть "ДополнительныеРеквизиты", и следует программно добавлять ссылки на новые свойства. Без этого новый реквизит не будет ассоциирован с целевым объектом и, следовательно, не появится в его формах и не будет доступен для использования.
Давайте рассмотрим исправленный код, который учитывает необходимость привязки созданного реквизита к набору свойств:
Функция ПолучитьСвойство(ИмяРеквизита, НаборСвойств_Ссылка, ДлинаСтроки=0)
// 1. Поиск существующего реквизита.
// Рекомендуется использовать поле "Имя" для поиска, если оно уникально и известно заранее.
// Однако, "Заголовок" также может быть использован, если нет риска дублирования.
ЭлементПВХ_Ссылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", ИмяРеквизита);
Если ЭлементПВХ_Ссылка = Неопределено ИЛИ ЭлементПВХ_Ссылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка() Тогда
// 2. Создание нового элемента ПланаВидовХарактеристик.ДополнительныеРеквизитыИСведения.
ЭлементПВХ_Нов = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьЭлемент();
ЭлементПВХ_Нов.Заголовок = ИмяРеквизита;
ЭлементПВХ_Нов.Имя = ИмяРеквизита; // Желательно задавать уникальное имя для программного обращения.
ЭлементПВХ_Нов.НаборСвойств = НаборСвойств_Ссылка;
ЭлементПВХ_Нов.Наименование = ЭлементПВХ_Нов.Заголовок+" ("+ЭлементПВХ_Нов.НаборСвойств+")";
ЭлементПВХ_Нов.ТипЗначения = Новый ОписаниеТипов("Строка",,,,Новый КвалификаторыСтроки(ДлинаСтроки));
Попытка
// 3. Запись созданного элемента ПВХ.
ЭлементПВХ_Нов.Записать();
ЭлементПВХ_Ссылка = ЭлементПВХ_Нов.Ссылка;
Исключение
Сообщить("Не удалось создать свойство " + ИмяРеквизита);
Возврат Неопределено; // В случае ошибки возвращаем Неопределено
КонецПопытки;
КонецЕсли;
// 4. Добавим наш реквизит в набор дополнительных реквизитов справочника.
// Это ключевой шаг, который делает реквизит видимым и активным.
НаборСвойств_Объект = НаборСвойств_Ссылка.ПолучитьОбъект();
Если НаборСвойств_Объект.ДополнительныеРеквизиты.Найти(ЭлементПВХ_Ссылка, "Свойство") = Неопределено Тогда
ЭлементНС_Нов = НаборСвойств_Объект.ДополнительныеРеквизиты.Добавить();
ЭлементНС_Нов.Свойство = ЭлементПВХ_Ссылка;
// Здесь можно заполнить другие свойства элемента набора, например, "ВидСравнения".
// ЭлементНС_Нов.ВидСравнения = Перечисления.ВидыСравненияСвойств.Равно;
НаборСвойств_Объект.Записать(); // 5. Запись самого объекта Набора свойств.
КонецЕсли;
Возврат ЭлементПВХ_Ссылка;
КонецФункции
Разберем по шагам, что изменилось и почему это работает:
ПланаВидовХарактеристик.ДополнительныеРеквизитыИСведения: Если реквизита нет, мы создаем новый элемент плана видов характеристик. Заполняем его основные свойства: Заголовок (для отображения пользователю), Имя (для программного обращения, рекомендуется уникальность), НаборСвойств (ссылка на элемент справочника НаборыДополнительныхРеквизитовИСведений), Наименование и ТипЗначения.НаборСвойств_Ссылка.ПолучитьОбъект(). Затем мы проверяем, не содержится ли наш новый реквизит уже в табличной части ДополнительныеРеквизиты этого набора. Если его там нет, мы добавляем новую строку в эту табличную часть и устанавливаем ее поле Свойство равным ссылке на наш только что созданный элемент ПВХ.ДополнительныеРеквизиты, необходимо записать сам объект "Набор свойств" НаборСвойств_Объект.Записать(). Только после этой записи изменения в структуре набора свойств будут сохранены в базе данных, и система 1С сможет корректно отобразить новый дополнительный реквизит на формах целевого объекта.Вместо того чтобы самостоятельно реализовывать всю логику создания и привязки дополнительных реквизитов, мы можем использовать стандартный общий модуль УправлениеСвойствами, который входит в состав Библиотеки стандартных подсистем (БСП) платформы 1С:Предприятие.
Преимущества использования БСП:
УправлениеСвойствами предоставляет высокоуровневые функции, которые инкапсулируют все необходимые действия по созданию, изменению, записи значений и отображению дополнительных реквизитов, упрощая код разработчика.Мы рекомендуем изучить методы этого модуля (например, УправлениеСвойствами.СоздатьДополнительныйРеквизит или аналогичные) и использовать их при разработке, чтобы ваш код был более надежным и поддерживаемым. Если ваша конфигурация включает БСП, это всегда предпочтительный путь.
Помимо основного решения, давайте рассмотрим несколько важных нюансов, которые могут возникнуть при работе с дополнительными реквизитами:
Заголовок – это пользовательское представление дополнительного реквизита. Оно отображается в формах, отчетах и списках, и может быть изменено пользователем в режиме предприятия.Имя – это уникальный идентификатор реквизита. Обычно он генерируется системой (например, с добавлением GUID) или задается программистом для программного доступа. Для надежного программного поиска реквизита, особенно в коде, мы рекомендуем использовать поле Имя, если оно известно и гарантированно уникально, поскольку Заголовок может быть изменен пользователем, что нарушит логику поиска. Однако, как было отмечено, при ручном создании имя может быть пустым, а при интерактивном — генерироваться с идентификатором. Поэтому при выборе поля для поиска следует учитывать специфику конфигурации и способ создания реквизита.В заключение, мы выяснили, что для успешного программного добавления дополнительного реквизита в 1С:Управление торговлей 11.4 и других конфигурациях на платформе 1С:Предприятие 8 необходимо не только создать сам элемент ПланаВидовХарактеристик.ДополнительныеРеквизитыИСведения, но и критически важно добавить его в коллекцию ДополнительныеРеквизиты соответствующего элемента справочника НаборыДополнительныхРеквизитовИСведений и затем записать этот набор. Мы также рассмотрели альтернативные пути с использованием БСП и важные нюансы, которые помогут вам избежать распространенных ошибок.