Почему не заполняется табличная часть при вызове метода Загрузить()?

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

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

1. Основная причина: потеря колонок при вызове метода Свернуть()

Проанализируем частый сценарий: разработчик получает таблицу значений из запроса, выполняет над ней агрегацию и пытается загрузить результат в объект:


// Предварительная очистка табличной части перед загрузкой
Контрагенты.Очистить();
Контрагенты.Загрузить(Выборка);

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


// Исходная таблица содержит: Контрагент, Подтверждено, СчетР, СчетРасчетов, ВидЗадолженности
// Ошибочный вызов с указанием только одного поля группировки:
Выборка.Свернуть("Контрагент", "Подтверждено");

// В результате в таблице Выборка останутся ТОЛЬКО две колонки: "Контрагент" и "Подтверждено".
// Колонки "СчетР", "СчетРасчетов" и "ВидЗадолженности" будут удалены платформой.

Чтобы сохранить все необходимые для табличной части поля, перечислим их через запятую в первом параметре метода Свернуть():


Выборка.Свернуть("Контрагент, СчетР, СчетРасчетов, ВидЗадолженности", "Подтверждено");
Контрагенты.Загрузить(Выборка);

2. Особенности и правила работы метода Загрузить()

Выясним ключевые нюансы работы метода Загрузить() у табличных частей:

  1. Избыточность предварительной очистки: Метод Загрузить() по умолчанию полностью перезаписывает строки табличной части. Вызов Контрагенты.Очистить() перед загрузкой выполнять не обязательно.
  2. Сопоставление колонок по именам: Данные переносятся только в те реквизиты табличной части, имена которых в точности совпадают с именами колонок таблицы-источника (с учетом регистра). Если в источнике колонка называется СчетР, а в табличной части — СчетРасчетов, данные перенесены не будут. Лишние колонки из таблицы значений игнорируются, а отсутствующие поля в табличной части заполняются значениями по умолчанию.
  3. Автоматическая нумерация: Платформа автоматически пересчитывает стандартный реквизит НомерСтроки, формируя непрерывную последовательность начиная с 1.
  4. Отсутствие интерактивных событий: Метод не вызывает обработчики событий формы (например, ПриИзменении). Если при заполнении строк требуется пересчет сумм или зависимых реквизитов, их необходимо рассчитать программно до или после загрузки.
  5. Контроль типов данных: При несовпадении типов данных в колонке источника и реквизите табличной части платформа предпринимает попытку автоматического приведения. Если привести тип невозможно (например, строка передается в строго типизированное ссылочное поле), реквизит будет инициализирован пустой ссылкой.

3. Пошаговая диагностика проблемы в отладчике

Если данные не переносятся в табличную часть, выполним следующие диагностические действия:

  1. Установим точку останова непосредственно перед строкой с вызовом метода Загрузить().
  2. Откроем значение переменной-источника в окне просмотра отладчика и проверим:
    1. Количество строк в таблице значений (не пустая ли коллекция).
    2. Точный состав колонок и их наименования.
    3. Типы значений в ячейках.
  3. Сверим имена колонок таблицы значений с именами реквизитов табличной части в дереве метаданных конфигуратора.

4. Альтернативные варианты заполнения табличной части

Рассмотрим другие подходы к наполнению табличной части, которые применяются в зависимости от решаемой задачи.

Вариант А. Создание эталонной структуры колонок

Чтобы гарантированно исключить расхождение имен колонок, таблицу значений для заполнения можно выгрузить напрямую из структуры табличной части:


// Создаем пустую таблицу значений с точной структурой табличной части
ТаблицаДляЗаполнения = Контрагенты.ВыгрузитьКолонки();

// Заполняем таблицу данными через Запрос или вручную
// ...

// Загружаем обратно в документ
Контрагенты.Загрузить(ТаблицаДляЗаполнения);

Вариант Б. Построчный обход с использованием ЗаполнитьЗначенияСвойств

Если в процессе переноса данных требуется выполнять дополнительные проверки, условия или пересчет полей, используем цикл с функцией ЗаполнитьЗначенияСвойств():


Контрагенты.Очистить();

Для Каждого СтрДанных Из Выборка Цикл
    НоваяСтрока = Контрагенты.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрДанных);
    
    // При необходимости заполняем реквизиты с несовпадающими именами
    НоваяСтрока.СчетРасчетов = СтрДанных.СчетР;
КонецЦикла;

Вариант В. Контекстные ограничения тонкого клиента

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

← На главную