Почему не создаются строки в табличной части документа по результатам запроса?

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

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

Анализ исходной ситуации

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

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

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

Шаг 1: Проверка данных в базе данных

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

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

Шаг 2: Отладка результата запроса

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


РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
    Сообщить("Внимание: Запрос вернул пустую таблицу! Проверьте параметр СсылкаТВ.");
Иначе
    ТаблицаРезультата = РезультатЗапроса.Выгрузить();
    Сообщить("Запрос нашел строк: " + ТаблицаРезультата.Количество());
КонецЕсли;

Если сообщение говорит о том, что строк 0, значит проблема в данных или в условии ГДЕ. Проверьте значение переменной СсылкаТВ. Она должна иметь тип ссылки именно того документа, к которому идет обращение в тексте запроса (Документ.ТаблицаВодители).

Шаг 3: Оптимизация заполнения через ЗаполнитьЗначенияСвойств

Посмотрим на код заполнения строк в цикле. Ручное присвоение каждого реквизита (Стр.Маршрут = Выборка.Маршрут и т.д.) — это трудоемкий процесс, в котором легко допустить опечатку. Разберем более современный и быстрый способ с использованием функции ЗаполнитьЗначенияСвойств.

Эта функция автоматически сопоставляет имена полей в источнике (выборке запроса) и в приемнике (строке ТЧ). Для этого достаточно, чтобы псевдонимы в запросе полностью совпадали с именами реквизитов ТЧ.


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

Обратите внимание: В исходном запросе автора поле называлось КМ, а записывалось в Километры. При использовании ЗаполнитьЗначенияСвойств поле в запросе нужно переименовать: ТаблицаВодителиВодители.ПробегЗаДень КАК Километры.

Шаг 4: Использование метода Загрузить()

Если задача состоит в полной замене строк табличной части данными из запроса, наиболее эффективным методом будет Загрузить(). Этот метод работает на порядок быстрее, чем цикл Добавить(), так как выполняется одной операцией на уровне платформы.

Разберем алгоритм использования этого метода:

  1. Подготавливаем запрос так, чтобы имена колонок (псевдонимы) совпадали с именами реквизитов табличной части документа-приемника.
  2. Выгружаем результат запроса в таблицу значений.
  3. Используем метод Объект.ИмяТЧ.Загрузить(ТаблицаИзЗапроса).

// 1. Получаем таблицу значений из запроса
ТаблицаДанных = Запрос.Выполнить().Выгрузить();

// 2. Загружаем данные в ТЧ (старые строки будут удалены автоматически)
Маршруты.Загрузить(ТаблицаДанных);

Важный нюанс: Метод Загрузить полностью очищает ТЧ перед вставкой. Если в ТЧ есть колонки, которых нет в запросе (например, вычисляемые поля), они будут заполнены значениями по умолчанию (ноль или пустая ссылка). В этом случае после загрузки можно пройтись циклом по ТЧ и дозаполнить нужные данные.

Шаг 5: Проблема отображения на форме

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

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

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

Итоговые рекомендации

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

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

← На главную