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