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