Добавил:
sora.alai.102@gmail.com Делаю работы на заказ. Какие именно? Пишите. Или регайтесь на бирже, где я работаю: https://vsesdal.com/promo?ref=748568 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Хрусталева Е. Ю. Язык запросов 1С-Предприятия 8 (2013)

.pdf
Скачиваний:
2182
Добавлен:
25.11.2018
Размер:
31.3 Mб
Скачать

Обход выборки результата запроса, содержащего данные табличной части

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

Как уже объяснялось ранее в разделе "Как получить данные из табличной части документа в качестве вложенной таблицы", при выполнении запроса к основной таблице поле результата запроса, содержащее данные из табличной части (например,

ЗаказТовара.Состав), будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе табличной части.

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

Ниже приводится пример процедуры встроенного языка, в которой обрабатываются как реквизиты документа, так и данные его табличной части и выводятся в окно сообщений

(листинг 2.26).

Листинг 2.26. Пример обработки результата запроса, выбирающего данные из документа с табличной частью

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

Внутри цикла обхода вложенной выборки реквизиты документа и данные его табличной части выводятся в окно сообщений в виде одной строки. Чтобы сложить строки, в запросе получаются текстовые представления от ссылочных полей (Клиент, Товар) с помощью функции ПРЕДСТАВЛЕНИЕ().

подробнее

О функции Представление() рассказано в разделе «Как получить текстовое представление ссылочного поля».

Этот пример можно посмотреть в демонстрационной конфигурации «Язык запросов», прилагающейся к книге, в обработке Работа с запросами.

Обработка результатов запроса с помощью конструктора запроса

В предыдущих примерах обхода выборки результаты запроса выводились в окно сообщений, но это сделано только для упрощения примера. На самом деле результаты выполнения запросов выводятся обычно в табличный документ, таблицу значений и т. п.

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

Обход выборки

Откроем модуль формы и вызовем из контекстного меню пункт Конструктор запроса с обработкой результата. Подтвердим, что мы хотим создать новый запрос. После этого откроется конструктор запроса с обработкой результата (рис. 2.37).

Рис. 2.37. Окно конструктора запроса с обработкой результата

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

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

Далее, как и в обычном конструкторе, определим исходные данные для запроса. На закладке Таблицы и поля перенесем табличную часть Состав документа ЗаказТовара в список источников запроса и выберем из этой таблицы поля: Товар, Количество и Сумма. Для того чтобы выбрать поля основной таблицы документа Клиент и Дата, раскроем поле Ссылка табличной части Состав, выберем эти поля и получим обращение через точку от ссылки – ЗаказТовараСостав.Ссылка.Клиент и ЗаказТовараСостав.Ссылка.Дата (рис. 2.38).

Рис. 2.38. Окно конструктора запроса с обработкой результата

Затем перейдем на закладку Итоги и укажем, какие итоги нужно рассчитать для результата запроса. В окно Группировочное поле перенесем поля выборки запроса

Клиент и Товар, а в окно Итоговое поле перенесем поля Количество и Сумма (рис. 2.39).

Рис. 2.39. Окно конструктора запроса с обработкой результата

Тем самым мы указали, что для каждого клиента по каждому товару из документа ЗаказТовара нужно подсчитать суммарное количество полей Количество и Сумма.

Нажмем ОК. Конструктор запроса с обработкой результата сформирует следующий фрагмент кода (листинг 2.27).

Листинг 2.27. Фрагмент процедуры для обхода выборки из результата запроса, созданный с помощью конструктора запроса с обработкой результата

Если мы сравним этот фрагмент с процедурой выполнения запроса (см. листинги 2.24, 2.25), в котором обходилась выборка с типом обхода ПоГруппировкам, то мы увидим, что конструктор запроса с обработкой результата сделал практически всю работу, за исключением самой программной обработки выборок. Эти фрагменты в тексте листинга 2.27 выделены жирным шрифтом, и их должен заполнить сам разработчик.

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

рассчитываются итоги для полей Клиент и Товар. Соответственно, чтобы обойти групповые итоги и детальные записи результата запроса, конструктор создал три вложенных друг в друга цикла для обхода выборок – выборки по группе записей Клиент, вложенной в нее выборки по группе Товар и вложенной в нее выборки детальных записей. Для групповых записей получается выборка с типом обхода ПоГруппировкам, а для детальных записей – с прямым типом обхода.

Вывод в табличный документ

Теперь с помощью конструктора выведем результат этого же запроса в табличный документ. Поскольку табличный документ заполняется данными на сервере, а выводится пользователю на клиенте, сначала создадим реквизит формы Результат типа ТабличныйДокумент, который и будет содержать данные результата запроса, и перетащим его в дерево элементов формы обработки. После этого создадим в модуле формы небольшую заготовку (листинг 2.28).

Листинг 2.28. Процедуры для вывода результата запроса в табличный документ

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

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

что мы хотим создать новый запрос.

На закладке конструктора Обработка результатов в группе Тип обработки выберем опцию Вывод в табличный документ, все остальные опции оставим без изменения (рис. 2.40).

Рис. 2.40. Окно конструктора запроса с обработкой результата

Далее, как и в предыдущем случае, определим исходные данные для запроса. При выборе из таблицы ЗаказТовара.Состав ссылочных полей Клиент и Товар конструктор автоматически добавит в список выборки текстовое представление этих полей, полученное с помощью функции Представление(), рис. 2.41.

Рис. 2.41. Окно конструктора запроса с обработкой результата

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

подробнее

О функции Представление() рассказано в разделе «Как получить текстовое представление

ссылочного поля».

Рекомендации по оптимизации запросов при выводе ссылочных полей в отчет даны в

разделе "Исключить вывод ссылочных полей в отчет".

Нажмем ОК. Конструктор запроса создаст подчиненный объект обработки (в которой мы поместили процедуру для вывода результата запроса в табличный документ) – макет табличного документа с полями, перечисленными в выборке запроса. Исходя из текста запроса, в макете присутствуют области итоговых группировок Клиент, Товар и область для вывода детальных записей, а также области для вывода заголовка и подвала табличного документа, шапки и подвала таблицы (рис. 2.42).

Рис. 2.42. Макет табличного документа, созданный конструктором

Также в функции ЗаполнитьТД() (откуда был вызван конструктор) конструктор запроса с обработкой результата сформирует следующий фрагмент кода (листинг 2.29).

Листинг 2.29. Фрагмент процедуры для вывода результата запроса в табличный документ, созданный с помощью конструктора запроса с обработкой результата

В результате в процедуре ЗаполнитьТД() сначала методом ПолучитьМакет() получается макет табличного документа с именем, указанным в конструкторе (см. рис. 2.40). Затем создается и выполняется запрос, определенный в конструкторе. Затем методом ПолучитьОбласть() получаются области табличного документа, заданные в макете. После этого табличный документ ТабДок, переданный в процедуру, очищается, и в него методом Вывести() выводятся области заголовка и шапки таблицы, полученные из макета. Затем начинается автоматическая группировка строк табличного документа методом НачатьАвтогруппировкуСтрок(), так как в конструкторе запроса с обработкой результата была по умолчанию включена опция Группировать строки (см. рис. 2.40).

Далее, как и предыдущем случае (см. листинг 2.27), начинается обход трех вложенных друг в друга выборок – итоговых группировок Клиент, Товар и детальных записей. В цикле обхода каждой выборки параметры соответствующих областей табличного документа, определенные в макете, заполняются данными выборок, и затем области с указанием уровня выборки выводятся в табличный документ методом Вывести(). Параметр Уровень этого метода используется для автоматической группировки строк результирующего табличного документа.

В заключение заканчивается автоматическая группировка строк табличного документа, и в него выводятся области подвала документа и подвала таблицы, полученные из макета.

Таким образом, при вызове процедуры ВыводВТабличныйДокумент() в поле табличного документа мы получим следующий результат (рис. 2.43).

Рис. 2.43. Вывод результата запроса в табличный документ

Мы видим, что в табличном документе записи сгруппированы по клиентам и товарам, по ним рассчитаны итоги, и мы можем свернуть или развернуть эти уровни благодаря группировке строк табличного документа.