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

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

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

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

Рис. 2.53. Получение всех родителей для элемента иерархического справочника

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

Создание запроса из произвольного источника

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

Для реализации поставленной задачи с помощью свойства глобального контекста Метаданные нам нужно обойти коллекцию всех документов, существующих в конфигурации, и всех табличных частей этих документов. И при этом динамически сформировать текст запроса, объединяющего запросы, которые получают данные из каждой табличной части каждого документа (листинг 2.44).

Листинг 2.44. Динамическое формирование текста запроса

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

("Документ." + ИмяДокумента + "." + ИмяТЧ + " КАК Товары").

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

После выхода из циклов мы присоединяем к общему запросу секцию описания итогов по полю Источник. Это сделано просто для лучшего визуального восприятия, чтобы таким образом сгруппировать товары, относящиеся к одному документу.

Чтобы посмотреть текст запроса, сформированного в результате обхода документов и их табличных частей, установим точку останова на строку РезультатЗапроса = Запрос.Выполнить(). Запустим «1С:Предприятие» в режиме отладки. После остановки программы двойным щелчком выделим слово Запрос и нажмем кнопку Вычислить выражение (Shift + F9) на панели инструментов Отладка конфигурации. Выделим строку

Текст в окне Результат и нажмем кнопку Показать значения в отдельном окне (или

F2) над окном результата, и мы увидим динамически сформированный текст запроса (рис. 2.54).

Рис. 2.54. Отладка текста запроса

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

Рис. 2.55. Создание запроса из произвольного источника

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

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

В случае, если нас интересует общий список товаров, независимо от того, в каком документе он используется, то можно убрать из запроса секцию описания итогов. Для того чтобы перечень товаров не повторялся, для объединения запросов нужно использовать конструкцию ОБЪЕДИНИТЬ, а не ОБЪЕДИНИТЬ ВСЕ. Результат запроса в этом случае нужно обходить линейным способом.

Создание кросс-отчета

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

Такая возможность может понадобиться при построении различных кросс-отчетов, представляющих информацию в табличном виде. Хотя кросс-отчеты легче, быстрее и, главное, методически правильнее формировать с помощью системы компоновки данных, в этом разделе мы покажем, как получить данные для кросс-отчета и вывести его в табличный документ с помощью встроенного языка.

Особенность получения данных для кросс-отчета (см. рис. 2.56) состоит в том, что при этом нужно, чтобы запрос внутри родительской группировки (например, по товарам) получил не только те вложенные группировки (например, по клиентам), по которым есть данные (продажи), но и те, по которым данных нет. Например, группировку по клиенту Орлов для товара Туфли и группировку по клиенту Соколов для товара Молоко. То есть чтобы в каждой строке таблицы было одинаковое количество столбцов, иначе таблица «поедет». Поэтому при получении вложенных группировок нужно использовать третий параметр ВСЕ метода выборки Выбрать().

Рассмотрим пример. Предположим, нам необходимо получить кросс-отчет по продажам товаров различным покупателям. Список товаров необходимо вывести в строках таблицы, а покупателей – в колонках (рис. 2.56).

Рис. 2.56. Кросс-отчет по продажам товаров

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

подробнее

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

Данные для отчета будут получаться при выполнении следующего запроса (листинг 2.45).

Листинг 2.45. Запрос для получения данных

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

Этот тип обхода мы рассматривали подробно в разделе «Обход по группировкам». Как уже говорилось, тип обхода передается первым параметром в метод выборки Выбрать(). Но в данном случае нам понадобится использовать второй и третий параметр этого метода.

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

Поясним назначение этих параметров на конкретном примере. Для решения поставленной задачи создадим следующую клиентскую процедуру (листинг 2.46).

Листинг 2.46. Вывод результата отчета в табличном документе

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

Процедура формирования табличного документа выглядит следующим образом (листинг

2.47).

Листинг 2.47. Заполнение данными табличного документа

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

Рис. 2.57. Макет табличного документа

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

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

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

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

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

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

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

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

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

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

Рис. 2.58. Кросс-отчет по продажам товаров

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

Вывод итогов по периодам с заданной периодичностью

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

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

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

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

Листинг 2.48. Вывод результата отчета в табличном документе

В серверную внеконтекстную функцию СформироватьОтчетСДополнениемДат()

помимо самого табличного документа передаются также даты начала и окончания отчетного периода, которые вводятся в полях формы обработки перед формированием табличного документа.

Процедура формирования табличного документа выглядит следующим образом (листинг

2.49).

Листинг 2.49. Заполнение данными табличного документа