Как в 1С обратиться к табличной части документа-основания и исправить ошибку в параметрах запроса?

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

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

Анализ типичных ошибок при работе с запросом к документу-основанию

Рассмотрим частые ошибки, которые приводят к исключениям времени выполнения:

  1. Несоответствие имени параметра в тексте запроса и в коде: если в секции ГДЕ запроса указано условие Товары.Ссылка = &ДокументОснование, то передавать параметр необходимо именно с именем "ДокументОснование", а не "Ссылка". Метод Запрос.УстановитьПараметр("ДокументОснование", Значение) ожидает точного совпадения имени.
  2. Ошибочный синтаксис обращения к полям вложенной таблицы: конструкция вида Документ1.Товары.(НаименованиеТовара, Цена) используется только при обращении к таблице шапки Документ.Документ1 для получения вложенной таблицы. Если в секции ИЗ источником выступает реальная таблица табличной части Документ.Документ1.Товары, имена колонок указываются через псевдоним таблицы: Товары.НаименованиеТовара, Товары.Цена.
  3. Попытка прочитать реквизит через менеджер документа: выражение Документы.Документ1.ДокументОснование обращается к менеджеру метаданных, у которого нет данных конкретного записанного документа. Для работы с реквизитами необходима конкретная ссылка на существующий документ.
  4. Контекст выполнения: в модуле менеджера нет контекста конкретного объекта (отсутствуют свойства ЭтотОбъект, Ссылка или реквизиты). Все ссылки и параметры должны явно передаваться в вызываемые процедуры и функции.

Вариант 1. Получение данных табличной части с помощью запроса (рекомендуемый способ)

Использование языка запросов является наиболее производительным и правильным подходом в стандартах разработки 1С. Запрос считывает из СУБД только запрошенные колонки, не загружая лишние данные в оперативную память.

Разберем пример правильного запроса, где мы выбираем строки табличной части Товары документа Документ1 по ссылке, переданной в качестве параметра:


Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |	Товары.НаименованиеТовара КАК НаименованиеТовара,
    |	Товары.Цена КАК Цена
    |ИЗ
    |	Документ.Документ1.Товары КАК Товары
    |ГДЕ
    |	Товары.Ссылка = &ДокументОснование";

Запрос.УстановитьПараметр("ДокументОснование", СсылкаНаДокумент1);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Обработка полученных строк
    НоваяСтрока = ЭтотОбъект.Товары.Добавить();
    НоваяСтрока.НаименованиеТовара = Выборка.НаименованиеТовара;
    НоваяСтрока.Цена = Выборка.Цена;
КонецЦикла;

Вариант 2. Заполнение табличной части в обработчике «ОбработкаЗаполнения»

Платформа 1С не хранит ссылку на документ-основание автоматически, если соответствующий реквизит не создан в конфигураторе. Чтобы сохранить связь между документами, добавим в шапку нового документа реквизит ДокументОснование (с типом ссылки на исходный документ).

При интерактивном или программном вводе на основании вызывается событие ОбработкаЗаполнения в модуле объекта. Проанализируем, как правильно обработать входящие данные заполнения:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.Документ1") Тогда
        
        // Сохраняем ссылку на основание в реквизите шапки
        ЭтотОбъект.ДокументОснование = ДанныеЗаполнения;
        
        // Считываем данные табличной части основания через запрос
        Запрос = Новый Запрос;
        Запрос.Текст =
            "ВЫБРАТЬ
            |	Товары.НаименованиеТовара КАК НаименованиеТовара,
            |	Товары.Цена КАК Цена
            |ИЗ
            |	Документ.Документ1.Товары КАК Товары
            |ГДЕ
            |	Товары.Ссылка = &ДокументОснование";
            
        Запрос.УстановитьПараметр("ДокументОснование", ДанныеЗаполнения);
        
        ТаблицаТоваров = Запрос.Выполнить().Выгрузить();
        ЭтотОбъект.Товары.Загрузить(ТаблицаТоваров);
        
    КонецЕсли;
    
КонецПроцедуры

Вариант 3. Чтение данных через объектную модель

Если требуется быстро получить данные из объекта без написания запроса, можно обратиться к табличной части через ссылку или объект документа. Однако обратите внимание: разыменование ссылки вида Ссылка.Товары.Выгрузить() неявно считывает документ целиком из базы данных, что может приводить к дополнительной нагрузке на систему при больших объемах данных.

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


// Получаем таблицу значений с нужными колонками напрямую из ссылки
ТаблицаЗначений = ДокументОснование.Товары.Выгрузить(, "НаименованиеТовара, Цена");

// Загружаем данные в табличную часть текущего документа
ЭтотОбъект.Товары.Загрузить(ТаблицаЗначений);

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

← На главную