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