В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача: предоставить пользователю список документов (например, "Поступление товаров" или "Путевые листы") не через стандартный список, а внутри специальной обработки. Это необходимо для дальнейшей корректировки данных, массовой печати или специфической обработки строк. В данной статье мы разберем, как правильно реализовать заполнение таблицы на форме результатами запроса, рассмотрим типичные ошибки и предложим оптимальные способы решения.
Если ваша форма создана в рамках обработки или документа, наиболее простым способом будет использование Табличной части, определенной в дереве метаданных объекта. Это позволяет минимизировать программный код, так как платформа берет на себя часть работы по типизации данных.
Разберем процесс по шагам:
ТаблицаДокументов).ДокументСсылка.уатПоступлениеТоваровУслуг).ДатаНачала и ДатаКонца с типом Дата.Теперь проанализируем код серверной процедуры, которая будет заполнять эту таблицу:
&НаСервере
Процедура ЗаполнитьТаблицуНаСервере()
// Очищаем таблицу перед заполнением
Объект.ТаблицаДокументов.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| уатПоступлениеТоваровУслуг.Ссылка КАК Ссылка,
| уатПоступлениеТоваровУслуг.Дата КАК Дата,
| уатПоступлениеТоваровУслуг.Номер КАК Номер
|ИЗ
| Документ.уатПоступлениеТоваровУслуг КАК уатПоступлениеТоваровУслуг
|ГДЕ
| уатПоступлениеТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаКонца";
Запрос.УстановитьПараметр("ДатаНачала", Объект.ДатаНачала);
// Для корректного захвата всей даты конца периода используем КонецДня
Запрос.УстановитьПараметр("ДатаКонца", КонецДня(Объект.ДатаКонца));
РезультатЗапроса = Запрос.Выполнить();
// Загружаем результат запроса напрямую в табличную часть объекта
Объект.ТаблицаДокументов.Загрузить(РезультатЗапроса.Выгрузить());
КонецПроцедуры
Важный нюанс: Обратите внимание на использование метода Загрузить(). Как было отмечено в обсуждении, простая попытка присваивания Объект.ТаблицаДокументов = Запрос.Выполнить().Выгрузить() вызовет ошибку, так как табличная часть — это коллекция, а результат выгрузки запроса — это объект типа ТаблицаЗначений. Метод Загрузить() автоматически сопоставляет имена колонок таблицы значений с именами реквизитов табличной части.
Проанализируем ситуацию, когда после выполнения кода таблица на форме остается пустой или содержит пустые значения, хотя запрос явно что-то находит. Причина практически всегда кроется в несовпадении имен. Если в запросе вы написали ВЫБРАТЬ Ссылка КАК ДокументСсылка, а в табличной части реквизит называется просто Ссылка, платформа не сможет сопоставить эти поля, и данные не будут загружены.
Всегда проверяйте псевдонимы в тексте запроса (КАК ИмяПоля). Они должны символ в символ совпадать с именами реквизитов вашей таблицы на форме.
Иногда создание табличной части в самом объекте (в метаданных) избыточно. Например, если данные нужны только для временного отображения. В этом случае мы создаем реквизит непосредственно в редакторе формы с типом ТаблицаЗначений.
Рассмотрим, как работать с таким реквизитом, используя методы ЗначениеВРеквизитФормы и РеквизитФормыВЗначение. Это более профессиональный подход, разделяющий данные формы и данные объекта.
&НаСервере
Процедура ЗаполнитьТЗНаФорме()
// Преобразуем реквизит формы в объект ТаблицаЗначений для работы
ТЗ = РеквизитФормыВЗначение("ТаблицаНаФорме");
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка, Дата ИЗ Документ.уатПоступлениеТоваровУслуг ГДЕ Дата МЕЖДУ &ДН И &ДК");
Запрос.УстановитьПараметр("ДН", Объект.ДатаНачала);
Запрос.УстановитьПараметр("ДК", КонецДня(Объект.ДатаКонца));
// Выгружаем результат запроса в нашу переменную ТЗ
ТЗ = Запрос.Выполнить().Выгрузить();
// Возвращаем измененную таблицу обратно на форму
ЗначениеВРеквизитФормы(ТЗ, "ТаблицаНаФорме");
КонецПроцедуры
Если пользователю нужно просто видеть список документов для выбора и не предполагается сложная ручная корректировка каждой строки в памяти, стоит рассмотреть Динамический список. Выясним, почему это может быть удобнее:
Однако, как справедливо замечено в сообщениях форума, если ваша цель — дать пользователю возможность "поиграть" с цифрами в таблице перед печатью (не меняя сами документы в базе), то ТаблицаЗначений или ТабличнаяЧасть — единственный верный выбор.
Разберем, как сделать работу с полученной таблицей более эффективной:
1. Добавление "Галочек" (Пометок). Часто пользователю нужно распечатать не все документы из списка, а только выбранные. Добавьте в таблицу колонку Пометка с типом Булево. В запросе её можно инициализировать так: ВЫБРАТЬ ЛОЖЬ КАК Пометка, .... На форме эта колонка будет выглядеть как флажок.
2. Открытие документа из таблицы. Чтобы пользователь мог быстро проверить данные в документе, добавим обработчик события Выбор для таблицы:
&НаКлиенте
Процедура ТаблицаДокументовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отменяем стандартное действие
ТекущиеДанные = Элементы.ТаблицаДокументов.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Открываем форму документа
ПоказатьЗначение(, ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
3. Условное оформление. Если документ помечен на удаление или не проведен, это важно визуализировать. Используйте свойство формы УсловноеОформление, чтобы подсвечивать такие строки серым или красным цветом. Для этого обязательно выбирайте поле Проведен и ПометкаУдаления в вашем запросе.
Подводя итог, отметим, что выбор между табличной частью объекта и таблицей значений на форме зависит от архитектуры вашей обработки, но в обоих случаях критически важно соблюдать идентичность имен полей и типов данных при выгрузке из запроса.