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