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