Как исправить ошибку «Документ не выбран» при использовании метода ЗаполнитьЗначенияСвойств в 1С?

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

Метод ЗаполнитьЗначенияСвойств — один из самых популярных и часто используемых инструментов в арсенале разработчика 1С. Он позволяет быстро скопировать значения одноименных колонок, реквизитов или свойств из одного объекта в другой. Однако при его использовании программисты нередко сталкиваются с неочевидными ошибками платформы и даже дезинформирующими подсказками в Синтакс-помощнике (СП). В этой статье мы подробно разберем, почему возникает ошибка «Документ не выбран», как обойти скрытую опечатку в официальной справке 1С и как оптимизировать работу данного метода в высоконагруженных системах.

Разбор опечатки в Синтакс-помощнике (СП)

Давайте начнем с анализа документации, которая часто сбивает с толку не только новичков, но и опытных разработчиков. Если мы откроем Синтакс-помощник и найдем описание метода ЗаполнитьЗначенияСвойств, то в описании третьего параметра СписокСвойств мы увидим следующую фразу:

«Параметр игнорируется, если <Источник> задан».

Проанализируем эту фразу логически. Второй параметр Источник является строго обязательным для работы метода. Без источника платформа физически не сможет понять, откуда именно нужно переносить данные, и выполнение кода завершится аварийно. Как же тогда может игнорироваться список свойств, если источник задан всегда?

Перед нами классическая опечатка разработчиков платформы 1С, которая кочует из релиза в релиз уже много лет. На самом деле правильная логика работы метода звучит так:

Параметр <ИсключаяСвойства> (4-й параметр) полностью игнорируется платформой, если явно заполнен параметр <СписокСвойств> (3-й параметр).

Если мы жестко ограничиваем список переносимых реквизитов, платформе просто нет необходимости анализировать список исключений — она запишет только то, что указано в третьем параметре.

Выясняем причину ошибки «Документ не выбран»

Теперь перейдем к технической сути ошибки, с которой столкнулся автор темы. При попытке выполнить код:

ЗаполнитьЗначенияСвойств(обДокумент, ЭтаФорма, "Поставщик");

Платформа возвращает исключение: «Ошибка установки значения свойства 'Поставщик' по причине: Документ не выбран».

Давайте разберем по шагам, почему это происходит. Данная ошибка указывает на фундаментальное различие между понятиями Ссылка и Объект в экосистеме 1С:

  1. Метод ЗаполнитьЗначенияСвойств пытается напрямую записать данные в свойства приемника, переданного в первом параметре.
  2. Если переменная обДокумент содержит пустую ссылку на документ (тип ДокументСсылка.ИмяДокумента, например, когда документ еще не создан или не выбран на форме), платформа обращается к ссылочному типу.
  3. Ссылки в 1С неизменяемы. Они хранят только уникальный идентификатор записи (GUID) в базе данных и предназначены исключительно для чтения. Попытка записать любое значение в свойство пустой ссылки всегда приводит к ошибке «Документ не выбран».

Как правильно инициализировать приемник?

Чтобы метод отработал корректно, в качестве приемника мы обязаны передавать изменяемый объект базы данных (тип ДокументОбъект) либо структуру данных в оперативной памяти (например, реквизит формы типа ДанныеФормыСтруктура). Рассмотрим правильные сценарии инициализации.

Сценарий 1: Создание нового документа в коде

Если нам необходимо создать новый документ и заполнить его реквизиты данными из формы или другого источника, мы должны сначала получить объект нового документа:


НовыйДокумент = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
// Теперь приемник — это полноценный объект, готовый к записи
ЗаполнитьЗначенияСвойств(НовыйДокумент, ЭтаФорма, "Поставщик, ДоговорКонтрагента");
НовыйДокумент.Записать();

Сценарий 2: Изменение существующего документа

Если у нас есть ссылка на уже существующий в базе данных документ, перед заполнением его свойств обязательно нужно получить его объектную сущность с помощью метода ПолучитьОбъект():


Если ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
    ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    ЗаполнитьЗначенияСвойств(ДокументОбъект, ИсточникДанных, "Склад, Подразделение");
    ДокументОбъект.Записать();
КонецЕсли;

Сценарий 3: Работа в контексте формы

Если мы работаем непосредственно внутри модуля формы и хотим заполнить реквизиты текущего редактируемого объекта, в качестве приемника следует передавать реквизит формы напрямую (обычно это Объект на управляемой форме):


// Находясь в контексте модуля управляемой формы
ЗаполнитьЗначенияСвойств(Объект, ДанныеЗаполнения, "Организация, Контрагент");

Проблема производительности при HighLoad-нагрузках

Рассмотрим неочевидное поведение алгоритма 1С, которое может стать критическим фактором при оптимизации высоконагруженных систем или обработке больших массивов данных.

Внутренний алгоритм метода ЗаполнитьЗначенияСвойств всегда производит обход свойств источника, а не приемника. Платформа берет структуру источника и в цикле проверяет наличие соответствующих свойств у приемника.

Представим ситуацию: у нас есть тяжелый источник (например, строка таблицы значений или строка дерева значений, содержащая более 100 колонок/свойств), а в качестве приемника выступает простая структура, в которую нам нужно перенести всего 2-3 реквизита.

Если мы запустим ЗаполнитьЗначенияСвойств, платформа выполнит итерации по всем 100 свойствам источника. В масштабах циклов на сотни тысяч строк это вызовет катастрофическое падение производительности.

Решение для оптимизации: Если вам необходимо перенести лишь несколько конкретных полей из тяжелого объекта, откажитесь от универсального метода в пользу прямого явного присваивания. Это отработает в десятки раз быстрее:


// Медленный вариант (платформа обойдет весь Источник)
ЗаполнитьЗначенияСвойств(ПриемникСвязи, ТяжелыйИсточник, "Артикул, Количество");

// Быстрый вариант (прямое обращение к свойствам)
ПриемникСвязи.Артикул = ТяжелыйИсточник.Артикул;
ПриемникСвязи.Количество = ТяжелыйИсточник.Количество;

Особенности валидации списков свойств

Давайте разберем еще несколько критически важных нюансов, связанных с передачей строк-списков в параметры метода:

Понимание этих внутренних механизмов работы платформы 1С позволит вам избегать досадных ошибок на этапе разработки и писать действительно быстрый, надежный и оптимизированный код.

← На главную