При переносе данных из внешних источников (например, из файлов Excel) или сторонних баз часто возникает необходимость программно заполнить пользовательские реквизиты объектов. В конфигурациях на базе Библиотеки Стандартных Подсистем (БСП), таких как 1С:Зарплата и Управление Персоналом 3.1, пользовательские свойства хранятся в табличной части ДополнительныеРеквизиты соответствующего справочника или документа.
Рассмотрим по шагам, как устроена эта механизация, почему возникает ошибка при попытке присвоить строковое имя свойству и как правильно программно заполнять доп. реквизиты разных типов.
Табличная часть ДополнительныеРеквизиты у объектов (например, у справочника ФизическиеЛица) содержит две ключевые колонки:
ПланыВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения.Главная ошибка, которую часто совершают разработчики на начальном этапе — попытка записать в колонку Свойство обычное текстовое наименование (строку). В этом случае платформа не может преобразовать строку в ссылку на ПВХ, и поле остается пустым.
// ОШИБКА: Запись строки вместо ссылки
НоваяСтрока = СпрОбъект.ДополнительныеРеквизиты.Добавить();
НоваяСтрока.Свойство = "Удостоверение"; // Так делать нельзя!
Для корректного заполнения поля Свойство необходимо сначала найти нужный элемент в плане видов характеристик ДополнительныеРеквизитыИСведения. Проанализируем основные способы поиска:
Способ 1. Поиск по полному наименованию
Платформа 1С при создании дополнительных реквизитов автоматически формирует наименование элемента ПВХ с уточнением владельца в скобках. Например, для свойства с заголовком "Удостоверение" у справочника физических лиц полное наименование в базе будет "Удостоверение (Физические лица)".
СвойствоУдостоверение = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Удостоверение (Физические лица)", Истина);
Способ 2. Поиск по реквизиту "Заголовок"
В плане видов характеристик ДополнительныеРеквизитыИСведения реквизит Заголовок индексируется. В нем хранится именно то название, которое пользователь видит на форме. Это избавляет от необходимости угадывать скобки и уточнения в наименовании.
СвойствоУдостоверение = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", "Удостоверение");
СвойствоДатаВыдачи = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", "Дата выдачи");
Заполнение колонки Значение зависит от типа данных самого реквизита:
ЗначенияСвойствОбъектов. При поиске такого значения крайне важно учитывать его владельца (само свойство из ПВХ).
// Поиск значения свойства с учетом владельца
ЗначениеВУ = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("ВУ",,, СвойствоУдостоверение);
Собраем рабочий пример кода для обхода Excel-файла и загрузки данных у физических лиц:
// Предварительно находим ссылки на свойства
СвойствоУдост = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", "Удостоверение");
СвойствоДата = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Заголовок", "Дата выдачи");
КодФизЛицо = Лист.Cells(к, 2).Value;
ФизЛицо = Справочники.ФизическиеЛица.НайтиПоКоду(КодФизЛицо);
Если ЗначениеЗаполнено(ФизЛицо) Тогда
СпрОбъект = ФизЛицо.ПолучитьОбъект();
// 1. Заполняем реквизит типа "Дополнительное значение"
СтрокаУдост = СпрОбъект.ДополнительныеРеквизиты.Найти(СвойствоУдост, "Свойство");
Если СтрокаУдост = Неопределено Тогда
СтрокаУдост = СпрОбъект.ДополнительныеРеквизиты.Добавить();
СтрокаУдост.Свойство = СвойствоУдост;
КонецЕсли;
ТекстЗначения = СокрЛП(Лист.Cells(к, 4).Value);
ЗначениеСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ТекстЗначения,,, СвойствоУдост);
СтрокаУдост.Значение = ЗначениеСвойства;
// 2. Заполняем реквизит типа "Дата"
СтрокаДата = СпрОбъект.ДополнительныеРеквизиты.Найти(СвойствоДата, "Свойство");
Если СтрокаДата = Неопределено Тогда
СтрокаДата = СпрОбъект.ДополнительныеРеквизиты.Добавить();
СтрокаДата.Свойство = СвойствоДата;
КонецЕсли;
СтрокаДата.Значение = Дата(Лист.Cells(к, 5).Value);
СпрОбъект.Записать();
КонецЕсли;
Обратите внимание: перед добавлением новой строки методом Добавить() рекомендуется выполнять поиск существующей строки через Найти(). Это предотвратит дублирование реквизитов у физического лица при повторном запуске обработки.
В конфигурации 1С:ЗУП 3.1 присутствует штатный механизм работы со свойствами — общий модуль УправлениеСвойствами. Вместо ручной работы с табличной частью объекта можно использовать процедуру УправлениеСвойствами.ЗаписатьСвойстваУОбъекта.
Для этого формируется массив структур с описанием записываемых свойств:
НаборСвойств = Новый Массив;
// Формируем структуру для первого реквизита
СвойстваУдост = Новый Структура;
СвойстваУдост.Вставить("Свойство", СвойствоУдост);
СвойстваУдост.Вставить("Значение", ЗначениеСвойства);
НаборСвойств.Добавить(СвойстваУдост);
// Формируем структуру для второго реквизита
СвойстваДата = Новый Структура;
СвойстваДата.Вставить("Свойство", СвойствоДата);
СвойстваДата.Вставить("Значение", ДатаВыдачи);
НаборСвойств.Добавить(СвойстваДата);
// Записываем свойства через штатный модуль БСП
УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СпрОбъект, НаборСвойств);
СпрОбъект.Записать();
Если вам необходимо загрузить данные для большого числа элементов (например, более 1000 физических лиц), проанализируем важные рекомендации:
ОбменДанными.Загрузка = Истина.
СпрОбъект.ОбменДанными.Загрузка = Истина;
СпрОбъект.Записать();