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