Как программно прочитать и заполнить дополнительные реквизиты в 1C:ERP 2.4?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет IT и автоматизация бизнеса
← На главную

В современных конфигурациях, таких как 1С:ERP, Комплексная автоматизация или Управление торговлей, работа с дополнительными реквизитами (свойствами) объектов — это повседневная задача. Часто возникает ситуация, когда при выборе значения в одном поле (например, Контрагент) необходимо автоматически заполнить дополнительный реквизит в документе (например, Заказ клиента), основываясь на настройках этого контрагента.

Разберем подробно, как реализовать этот механизм программно, учитывая архитектурные особенности ERP 2.4 и использование Библиотеки Стандартных Подсистем (БСП).

Постановка задачи

У нас есть следующая ситуация:

  1. В справочнике Контрагенты добавлен дополнительный реквизит (тип Булево), например, «Обмен настроен».
  2. В документе Заказ клиента существует аналогичный дополнительный реквизит.
  3. Нам необходимо, чтобы при выборе контрагента в форме документа значение этого реквизита переносилось из справочника в документ автоматически.

Давайте проанализируем, где хранятся эти данные, как к ним правильно обращаться и выполнять изменение значения свойства.

Где хранятся дополнительные реквизиты?

В старых конфигурациях значения свойств часто хранились исключительно в Регистрах Сведений. Однако в ERP 2.4 (и других конфигурациях на базе свежих версий БСП) для хранения значений дополнительных реквизитов объектов используются Табличные Части самих объектов. Эта табличная часть обычно называется ДополнительныеРеквизиты.

Структура этой табличной части обычно проста:

Этап 1: Получение ссылки на свойство

Прежде чем мы сможем прочитать или записать значение, нам нужно знать, какое именно свойство мы ищем. Ссылку на свойство нельзя просто "угадать" или искать по наименованию в цикле (это неоптимально). В ERP свойства привязаны к Наборам.

Для правильного поиска ссылки на свойство (наш «ключ» к значению) нам нужно выполнить следующие действия:

  1. Найти предопределенный элемент справочника НаборыДополнительныхРеквизитовИСведений, соответствующий нашему объекту (например, для справочника контрагентов).
  2. Найти ссылку в ПВХ ДополнительныеРеквизитыИСведения, которая входит в этот набор и имеет нужное нам наименование (или заголовок).

Рекомендуем получить эту ссылку один раз (например, кэшировать или найти по уникальному идентификатору, если вы уверены, что базы идентичны) и использовать её в дальнейшем коде.

Этап 2: Чтение значения из справочника (Источника)

Посмотрим на функцию, которая позволяет прочитать значение доп. реквизита из объекта, зная ссылку на само Свойство. Мы будем искать строку в табличной части ДополнительныеРеквизиты.

Рассмотрим пример функции, которую можно разместить в общем модуле или модуле формы:


Функция ПолучитьЗначениеДопРеквизита(СсылкаНаОбъект, Свойство) Экспорт

    // Создаем структуру для отбора строк в табличной части
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Свойство", Свойство);
    
    // Используем метод НайтиСтроки, который работает быстрее полного перебора
    МассивСтрок = СсылкаНаОбъект.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);

    // Если массив пуст — значит, значение не задано
    Если МассивСтрок.Количество() = 0 Тогда
        Возврат Неопределено; // Или Ложь, в зависимости от логики
    Иначе
        // Возвращаем значение из первой найденной строки
        Возврат МассивСтрок[0].Значение;
    КонецЕсли;

КонецФункции

Важное примечание: При вызове этой функции с клиента (из формы документа) нам придется сделать серверный вызов (в некоторых случаях полезно использовать длительные операции), так как табличная часть справочника находится в базе данных.

Этап 3: Заполнение реквизита в документе (Приемнике)

Теперь разберем, как записать полученное значение в документ Заказ клиента. Поскольку мы находимся в форме документа и пользователь только что выбрал контрагента, документ еще не записан. Мы работаем с коллекцией Объект.ДополнительныеРеквизиты на форме.

Здесь алгоритм немного сложнее, чем при чтении. Нам нужно:

  1. Проверить, есть ли уже строка с таким свойством в таблице.
  2. Если есть — обновить значение.
  3. Если нет — добавить новую строку.

Рассмотрим код обработчика события ПриИзменении поля Контрагент:


&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    
    // Получаем значение из контрагента (вызов серверной функции)
    ЗначениеСвойства = ПолучитьЗначениеСвойстваКонтрагентаНаСервере(Объект.Контрагент);
    
    // Заполняем значение в текущем объекте (Заказ клиента)
    ЗаполнитьДопРеквизитВЗаказе(ЗначениеСвойства);
    
КонецПроцедуры

&НаСервере
Функция ПолучитьЗначениеСвойстваКонтрагентаНаСервере(КонтрагентСсылка)
    
    // Здесь нам нужно получить ссылку на ПВХ для Контрагента
    // Предположим, мы нашли её заранее или ищем по имени
    СвойствоКонтрагента = НайтиСвойствоПоИмени("ОбменНастроен", "Справочник_Контрагенты"); 
    
    Возврат ПолучитьЗначениеДопРеквизита(КонтрагентСсылка, СвойствоКонтрагента);
    
КонецФункции

&НаКлиенте
Процедура ЗаполнитьДопРеквизитВЗаказе(ЗначениеДляЗаписи)
    
    // Нам нужна ссылка на свойство именно для ДОКУМЕНТА (это может быть другой элемент ПВХ, чем у контрагента!)
    СвойствоДокумента = ПолучитьСвойствоДокументаНаСервере(); // Вспомогательная функция
    
    // Ищем строку в коллекции формы
    ПараметрыОтбора = Новый Структура("Свойство", СвойствоДокумента);
    НайденныеСтроки = Объект.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        // Обновляем существующую
        СтрокаТЧ = НайденныеСтроки[0];
        СтрокаТЧ.Значение = ЗначениеДляЗаписи;
    Иначе
        // Добавляем новую
        СтрокаТЧ = Объект.ДополнительныеРеквизиты.Добавить();
        СтрокаТЧ.Свойство = СвойствоДокумента;
        СтрокаТЧ.Значение = ЗначениеДляЗаписи;
        // Важно: ТекстоваяСтрока заполняется автоматически при записи или можно заполнить явно, если требуется представление
    КонецЕсли;

КонецПроцедуры

Профессиональный подход: использование БСП

В ERP 2.4 внедрена подсистема «Свойства», и, чтобы не писать "велосипеды" с поиском строк, можно воспользоваться инструментами общего модуля УправлениеСвойствами. Это более правильный, "каноничный" способ, если вы пишете код на сервере (например, в подписке на событие или при проведении).

Для чтения значений:


// Массив свойств, которые хотим прочитать
МассивСвойств = Новый Массив;
МассивСвойств.Добавить(НужноеСвойствоСсылка);

// Получаем соответствие Свойство -> Значение
Результат = УправлениеСвойствами.ПолучитьЗначенияСвойств(СсылкаНаОбъект, МассивСвойств);
Значение = Результат[НужноеСвойствоСсылка];

Для записи значений непосредственно в базу данных:


ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("Свойство");
ТаблицаЗначений.Колонки.Добавить("Значение");
НоваяСтрока = ТаблицаЗначений.Добавить();
НоваяСтрока.Свойство = НужноеСвойствоСсылка;
НоваяСтрока.Значение = Истина; // Наше булево значение

// Этот метод сам разберется: добавить строку или обновить, и запишет объект
УправлениеСвойствами.ЗаписатьЗначенияСвойств(СсылкаНаОбъект, ТаблицаЗначений);

Подводные камни и рекомендации

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

Используя этот подход, вы сможете гибко управлять заполнением дополнительных полей в ERP 2.4, сохраняя целостность данных и высокую производительность системы.

← На главную