Глава 6. Запросы
Запросы в системе 1 С:Предприятие 8.0 предназначены для выборки информации из базы данных. По сути, запрос - это обращение к системе с просьбой выбрать определенную информацию из базы данных, а часто не только выбрать, но и произвести некоторую обработку: сгруппировать, отсортировать, вычислить итоги.
Например, с помощью запроса можно легко выбрать всех сотрудников, занимающих определенную должность, или можно узнать объем продаж каждого товара в течение года с детализацией до месяца.
Стоит отметить, что в других системах с помощью запросов можно не только выбирать информацию из базы данных, но и изменять ее: добавлять, удалять и изменять записи в таблицах, управлять правами пользователей, создавать и модифицировать таблицы, поля, индексы и другие объекты базы данных. В системе 1С:Предприятие 8.0 запросы предназначены только для чтения данных. Изменять данные с помощью запросов нельзя, и тем более нельзя изменять структуру базы данных, что возможно только в режиме «Конфигуратор». Запись данных в 1С:Предприятии 8.0 производится только через объекты встроенного языка, что обеспечивает высокий уровень логической целостности базы данных.
Основная цель обычного языка программирования заключается в том, чтобы задать пошаговую программу для системы, то есть точно определить, как решать задачу. Цель же языка запросов состоит в том, чтобы сказать системе, что нужно получить, то есть потребовать результат. При этом нас не интересует, как именно система будет выполнять задание, т.е. план (алгоритм) выполнения запроса строится системой автоматически.
Приведем пример решения задачи обоими методами: с помощью языка программирования и с помощью запроса. Допустим, необходимо вывести сотрудников с окладом больше 10000 руб.
1- й способ. Используется язык программирования:
Выборка = Справочники.Сотрудники.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Оклад > 10000 Тогда
Сообщить(Выборка.Наименование + " имеет оклад " + Выборка.Оклад); КонецЕсли;
КонецЦикла;
2- й способ. Используется механизм запросов:
Запрос = Новый Запрос("
1 ВЫБРАТЬ * ИЗ Справочник.Сотрудники 1ГДЕ Оклад > 10000");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий () Цикл
Сообщить(Выборка.Наименование + " имеет оклад " + Выборка.Оклад); КонецЦикла;
Обратите внимание на особенности второго варианта с использованием запроса:
• внутри цикла не нужно фильтровать записи, поскольку запрос выполнил всю работу за нас;
• вариант с запросом обычно выполняется быстрее, так как в клиент-серверном варианте работы запрос выполняется на сервере и не требуется передавать по сети весь справочник, который может быть очень большим.
В клиент-серверном варианте работы 1 (
лПредприятия 8.0 запросы будут транслироваться в SQL для выполнения в среде MS SQL Server. Сервер баз данных предпримет необходимые действия для оптимизации запроса.
Даже если вы работает в файловом варианте, то вариант с запросом обычно эффективнее обычного цикла для обработки больших справочников, списков документов и извлечения данных из регистров.
Но необходимо иметь в виду, что при использовании запроса, результат целиком помещается в память, тогда как выборка, сформированная средствами встроенного языка, загружает информа-
цию порциями и позволяет перебрать большие списки объектов, не требуя значительного объема памяти.
Написание запроса требует не алгоритмического, а декларативного типа мышления, когда разработчик говорит не как сделать задачу, а что нужно получить в результате. При этом производится обработка не одной переменной или одной текущей строки, а всей таблицы или столбца. Разработчик должен мыслить множествам, чтобы решить поставленную задачу с помощью одного или нескольких запросов.
Заметим, что в приведенном выше примере мы рассмотрели самое простое применение механизма запросов. С помощью запросов можно не только отбирать нужные записи по любому условию, но также группировать, сортировать, подсчитывать итоги. И сейчас мы научимся все это делать!
Разработка в системе 1 ^Предприятие 8.0
Выполнение запроса
Для работы с запросами в системе 1 ^Предприятие 8.0 предусмотрено несколько специальных объектов, а именно:
• Запрос,
• РезультатЗапроса,
• ВыборкаИзРезультатаЗапроса.
Общая схема выполнения запроса такова:
1. Создание объекта типа Запрос с текстом запроса на специальном языке запросов.
2. Установка параметров запроса с помощью метода Установить-Параметр.
3. Выполнение запроса, получение результата.
4. Получение выборки из результата запроса или выгрузка результата в таблицу значений / дерево значений. Также есть возможность использовать результат запроса как источник данных для сводной таблицы.
5. Обработка выборки или таблицы значений (например, перебор строк) и выполнение действий, для которых был нужен запрос, например, вывод области при формировании отчета
Графически это можно представить следующим образом:
Приведем простой пример, иллюстрирующий выполнение типичного запроса:
//создание объекта Запрос
Запрос = Новый Запрос!”
(ВЫБРАТЬ Код, Наименование
I ИЗ Справочник.Номенклатура”);
//выполнение запроса и получение результата
РезультатЗапроса = Запрос .Выполнить О;
//получение выборки из результата запроса
Выборка = РезультатЗапроса.Выбрать();
//обход записей в выборке
Пока Выборка.Следующий() Цикл
//обращение к полям
Сообщить(Выборка.Наименование);
КонецЦикла;
Два основных элемента механизма запросов — это язык запросов и обход выборки из результата запроса. Именно в них заключена основная мощь механизма запросов, поэтому ниже они будут рассмотрены более подробно. Но прежде, чем мы перейдем к написанию запросов «с чистого листа», познакомимся с Конструктором запросов, который значительно упрощает освоение языка запросов.
Конструктор запросов
В системе 1С:Предприятие 8.0 существует Конструктор запросов, который рекомендуется начинающим пользователям для быстрого создания запросов. При использовании Конструктора вы застрахованы от синтаксических ошибок в запросе, и это превращает его в очень удобное средство для первоначального изучения языка запросов.
Конструктор запросов может быть вызван как в режиме «Предприятие», так и в режиме «Конфигуратор».
Ниже на рисунке показана первая закладка Конструктора запросов — «Таблицы и поля», на которой задается список выбираемых полей из одной или нескольких таблиц:
Вообще конструктор запросов имеет следующие закладки:
Таблицы и поля
На этой закладке выбираются нужные объекты путем переноса их из списка «База данных» в списки «Таблицы» и «Поля».
Связи
Эта закладка появляется, только если в запросе соединяются несколько несколько таблиц. Здесь можно настроить условия соединения.
Группировка
Если требуется сгруппировать результаты запроса, т.е. свернуть по группировочным полям, выберите поля, по которым будет выполнена группировка.
Условия
На этой закладке можно указать условия, по которым будет выполняться отбор исходных данных. По каждому полю можно выбрать вид условия и указать параметр.
Дополнительно
На этой закладке устанавливаются дополнительные настройки запроса, например, исключение повторяющихся записей, а также блокировка данных для изменения.
Объединения / Псевдонимы
Здесь можно объединить данные из нескольких таблиц, указав условия объединения. На этой же закладке назначаются псевдонимы полей.
Порядок
Если требуется, укажите условия сортировки полученной информации.
Итоги
На этой закладке определяется, по каким полям подсчитывать промежуточные итоговые данные, а также подсчитывать или нет общие итоги.
Выходная форма
Эта закладка появляется, если вызван конструктор выходных форм в дереве метаданных или в форме редактирования объекта метаданных. Конструктор выходных форм генерирует не только запрос, но и процедуру его обработки, а также макет.
Консоль запросов
Для системы 1 ^Предприятие 8.0 была создана удобная обработка «Консоль запросов», которая поставляется на дисках информационно-технологического сопровождения (ИТС). Эта обработка позволяет в режиме запуска «Предприятие» написать текст на языке запросов и тут же получить результат.
Ниже показано окно этой обработки:
?СНГСІ7№ ^ПрОГО?
t L) CMS - -
Способ выгрузи Сгыеок Запрос
I J V Выполнить <K П^ракіетры д
ШЕРСТЬ
*
И?
Сар^&очхик Ноигикланур® ЬДК Нон«іш,/ів.ьур*. |
ъ |
Поы&ткйУд |
Предопр |
Родите іь |
ЭтоГрртпа |
К. оо |
Наименоек-іие |
|
[ ЛО'ЖЬ |
южь |
|
истина |
оіш |
Смгзрегь |
іегкне |
по:**, |
ЛОЖЬ |
Сигар-РТЫ |
ложь |
тп2 |
Петр 1 леи им |
кты |
ясокь |
¦хжь |
|
негніе |
00003 |
Продуктъ |
терские надели* |
.псокь |
г,-іМЬ |
Продет гы |
исгшб |
0G0W |
Концигерсы# изделия |
Г іьяж Конфеты) |
ложь |
иже |
Кондитерские иадетмя |
Ложь |
00005 |
Грильяж КонФгтыІ |
•г ¦=- ч эчк-э Конфеть 1 |
ложь |
О жь |
Кондитерские издегмя |
ложь |
00006 |
белочка КонФетЫ |
Мишг*(к,оиФетыІ |
ложь |
|
Кендигерсі?** изделия |
Ижь |
огоо? |
Мишка Коифетыі |
^врі^Фис (коифоты] |
ЛОЖЬ |
ЛОЖЬ |
Кондитерские изделия |
ложь |
OOQns |
Барбарис (коис?ты] |
'Рр іктдемв Конфеты) |
ложь |
ЛОЖ? |
Кснаигерские изделия .ложъ |
іімгаэ |
Фруктовые Ксичреты) |
ГЯУЪТЖГ Сводная Таб/Ццд |
|
|
— |
|
|
|
Язык запросов
Для выполнения запроса необходимо составить текст на специальном языке запросов, который сильно отличается от обычного языка программирования по синтаксису и назначению.
Замечание. Язык запросов системы 1 ^Предприятие 8.0 очень похож на стандартный SQL
, но имеет некоторые отличия. Если вы знаете SQL, то изучить язык запросов 1 ^Предприятия 8.0 будет гораздо легче.
Все ключевые слова языка запросов 1 С:Предприятие 8.0 имеют английские эквиваленты, совпадающие там, где это возможно, со стандартным SQL. Например, ключевое слово ВЫБРАТЬ может быть заменено на SELECT, а ключевое слово ИЗ на FROM. Полный перечень английских эквивалентов приведен в документации.
В общем случае текст запроса строится по следующей схеме:
ВЫБРАТЬ <Список полей I
>
[ИЗ <Список таблиц-источников:»]
[ГДЕ <Список условий>]
[УПОРЯДОЧИТЬ ПО <Список полей > ] | [АВТОУПОРЯДОЧИВАНИЕ]
[СГРУППИРОВАТЬ ПО <Список полей>]
[ИТОГИ [<агрегатные функции>] ПО <Список полей> [, ОБЩИЕ]]
В квадратных скобках приведены необязательные конструкции. Вертикальной чертой разделены конструкции, предполагающие выбор одного из нескольких элементов. Все конструкции языка запросов с примерами их использования приведены ниже.
Предложение ВЫБРАТЬ / SELECT
Предложение ВЫБРАТЬ позволяет указать список полей для выборки. Если вместо перечня полей указана звездочка («
»), тогда это означает, что нужно выбрать все поля таблицы. Указание кон-
кретных полей позволяет выбрать только заданные колонки из исходной таблицы-источника запроса.
В качестве источника данных для запроса можно использовать справочники, документы, журналы документов, регистры и другие таблицы-источники.
Синтаксическая диаграмма конструкции ВЫБРАТЬ такова:
ВЫБРАТЬ [ РАЗ ЛИЧНЫЕ ] [ПЕРВЫЕ <Количество>] <:Список полей выборки I *>
Примеры:
ВЫБРАТЬ Наименование, Цена ИЗ Справочник.Товары ВЫБРАТЬ * ИЗ Справочник.Сотрудники
ВЫБРАТЬ Номер, Дата, Представление ИЗ Документ.РасходнаяНакладная ВЫБРАТЬ * ИЗ РегистрНакопления.Продажи
В системе 1 С:Предприятие 8.0 можно построить запрос без указания ключевого слова ИЗ, тогда список полей должен содержать полные имена таблиц, например:
ВЫБРАТЬ Справочник. Товары. Наименование, Справочник. Товары. Цена ВЫБРАТЬ Справочник.Сотрудники.*
Псевдонимы полей (КАК/AS)
Для поля может быть назначен псевдоним с помощью ключевого слова КАК. Это позволяет обращаться к полю по псевдониму при указании итогов и порядка сортировки, а также в результате запроса.
В следующем запросе для полей Наименование и ЕдИзм назначаются псевдонимы:
Результат запроса будет следующий:
ВЫБРАТЬ Наименование КАК Товар, Цена, ЕдИзм КАК ЕдиницаИзмерения ИЗ Справочник.Товары УПОРЯДОЧИТЬ ПО Товар |
Товар |
Цена |
Единица Измерения |
Бумага |
130 |
Пачка |
Вилы |
1000 |
Шт |
Грабли |
1500 |
Шт |
|
Ключевое слово КАК необязательно и может быть опущено, но для повышения наглядности его рекомендуется указывать, особенно на первых порах.
Ниже приведен пример того же запроса без ключевого слова
КАК:
ВЫБРАТЬ Наименование Товар, Цена, ЕдИзм ЕдиницаИзмерения ИЗ Справочник.Товары УПОРЯДОЧИТЬ ПО Товар
Ключевое слово РАЗЛИЧНЫЕ/DISTINCT
Ключевое слово РАЗЛИЧНЫЕ позволяет оставить в результате запроса только отличающиеся строки. Например, если мы выбираем контрагентов из документа РасходнаяНакладная, то вполне вероятно, что один и тот же контрагент, может встретиться в нескольких накладных, поэтому без ключевого слова РАЗЛИЧНЫЕ он будет присутствовать в результате запроса несколько раз.
Например, в результате приведенного ниже запроса несколько раз встречается контрагент ООО «Новый мир»:
ВЫБРАТЬ Контрагент ИЗ Документ.РасходнаяНакладная
Контрагент
ООО «Новый мир»
ЗАО «Стройметмаш»
ООО «Новый мир»
ООО «Механика»
Если же указать ключевое слово РАЗЛИЧНЫЕ, то повторяющиеся записи из результата запроса будут удалены:
ВЫБРАТЬ РАЗЛИЧНЫЕ Контрагент ИЗ Документ. РасходнаяНакладйая
rt,
f'
Контрагент
ООО «Новый мир»
ЗАО «Стройметмаш»
ООО «Механика»
Ключевое слово ПЕРВЫЕ / ТОР
Данное ключевое слово позволяет ограничить выборку несколькими первыми записями. Часто это ключевое слово применяется в комбинации с сортировкой (см. предложение УПОРЯДОЧИТЬ ПО).
Допустим, требуется выбрать 3 самых дорогих товара. Это реализуется следующим запросом:
ВЫБРАТЬ ПЕРВЫЕ 3 Наименование, Цена ИЗ Справочник.Номенклатура УПОРЯДОЧИТЬ ПО Цена УБЫВ
Результат запроса будет такой: |
Наименование |
Цена |
ЖК-Монитор LG Flatron 21” |
1500 |
Компьютер Formoza |
1450 |
ЖК-Монитор LG Flatron 17” |
1200 |
|
Поля из вложенных таблиц
Поле в списке выборки может ссылаться на вложенную таблицу источника данных, например, на табличную часть справочника. В этом случае поле результата запроса будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе вложенной таблицы-источника.
По умолчанию во вложенный результат запроса включаются все поля вложенной таблицы-источника данных. Имеется возможность явно определить группу полей, которые должны содержаться во вложенном результате запроса.
Список полей, выбираемых из вложенной таблицы, описывается по следующему образцу:
//требуются все поля из вложенной таблицы ВЫБРАТЬ Документ . РасходнаяНакладная. Состав ВЫБРАТЬ Документ.РасходнаяНакладная.Состав.*
//требуется только одно поле из табличной части ВЫБРАТЬ Документ.РасходнаяНакладная.Состав.Сумма
//требуется несколько полей из табличной части
ВЫБРАТЬ Документ.РасходнаяНакладная.Состав.(Количество,Сумма)
//для полей вложенной таблицы можно указать псевдонимы ВЫБРАТЬ Документ.РасходнаяНакладная.Состав.(Количество КАК Кол,
Сумма КАК Сум)
Предложение ИЗ / FROM
Предложение ИЗ позволяет указать таблицы-источники для запроса и задать порядок их соединения, если таблиц несколько. Вот простые примеры запросов с предложением ИЗ:
ВЫБРАТЬ * ИЗ Справочник.Товары
ВЫБРАТЬ * ИЗ Документ.РасходнаяНакладная
Напомним, что конструкция ИЗ необязательна, если в списке выбираемых полей указаны полные имена таблиц, например,
ВЫБРАТВ Справочник.Товары.*
ВЫБРАТЬ Документ.РасходнаяНакладная.Дата, Документ.РасходнаяНакладная.Номер
Таблицы-источники данных
Каждая таблица-источник предоставляет свой набор полей. С полным их перечнем вы можете ознакомиться в документации или Синтакс-помощнике.
В ^Предприятии 8.0 существуют следующие таблицы-
источники данных для запросов:
• Таблица констант,
• Таблица справочника,
• Таблица документов,
• Таблица журнала документов,
• Таблицы последовательностей,
• Таблица плана видов характеристик,
• Таблица критерия отбора,
• Таблица плана видов расчета,
• Таблицы регистров расчета,
• Таблицы регистров сведений,
• Таблицы регистров накопления,
• Таблицы регистров бухгалтерии.
В данной главе подробно описаны только таблицы для обращения к справочникам и документам.
Таблица справочника
Таблица справочника позволяет организовать запрос к любому справочнику и предоставляет следующие поля:
Ссылка
Ссылка на элемент справочника. Через ссылку можно будет обратиться к любому полю справочника, даже если оно не включено в запрос.
ПометкаУдаления
Признак пометки на удаление элемента справочника. Если равно значению Истина, то элемент помечен на удаление.
Родитель
Указывает на элемента-родителя (или группу), в которой содержится данный элемент. Это поле будет включено в результат запроса только для иерархических справочников.
ЭтоГруппа
Признак того, что элемент справочника является группой. Это поле включается в результат запроса только для иерархических справочников.
Владелец
Ссылка на элемент справочника-владельца, которому принадлежит данный элемент, т.е. которому он подчинен. Это поле будет включено в результат запроса только для подчиненных справочников.
Представление
Виртуальное поле* (см.ниже). Содержит представление элемента справочника, например, его наименование или код.
Код
Код элемента. Встроенное поле для всех справочников.
Наименование
Наименование элемента. Встроенное поле для всех справочников.
<имя реквизита>
Далее идут реквизиты справочника, как они определены в Конфигураторе, например, Цена, ЕдИзм и т.д.
<имя табличной части>
Если у справочника есть табличные части, то к ним можно обращаться по имени. При этом в результате запроса появляется вложенная таблица.
Приведем примеры простых запросов к справочнику:
ВЫБРАТЬ Код, Наименование, Цена, Родитель ИЗ Справочник.Номенклатура
ВЫБРАТЬ
.Представление ИЗ Справочник.Номенклатура
ВЫБРАТЬ Наименование, ЭтоГруппа, ПометкаУдаления ИЗ Справочник.Номенклатура
ГДЕ ЭтоГруппа = ИСТИНА И ПометкаУдаления = ЛОЖЬ
Разработка в системе 1 С: Предприятие 8.0
Таблица документа
Таблица документа предназначена для выборки данных из документов. Она предоставляет следующие поля:
Ссылка
Через ссылку на документ можно будет обратиться к любому полю документа, даже если оно не включено в запрос.
ПометкаУдаления
Признак пометки на удаление документа.
Номер
Номер документа. Встроенное поле для всех документов.
Дата
Дата и время документа. Встроенное поле для всех документов.
Проведен
Содержит признак проведенности документа. Данное поле всегда включается в результат, даже если для документа запрещено проведение.
<имя реквизита>
Далее идут реквизиты шапки документа, как они определены в Конфигураторе, например, Контрагент, Склад и т.д.
<имя табличной части>
Если у документа есть табличные части, то к ним можно обращаться по имени. При этом в результате запроса появляется вложенная таблица.
МоментВремени
Виртуальное поле. Содержит момент времени документа, который включает дату и ссылку на документ. Напомним, что тип «дата» включает также и время с точностью до секунды.
Представление
Виртуальное поле. Содержит строку-представление документа, например, «Расходная накладная 0035 от 25.07.2003 12:05:01».
Итак, мы рассмотрели две основные таблицы-источники данных для справочников и документов. Таблицы-источники для регист-
ров будут представлены в соответствующих главах. Таблицы-источники для других объектов (констант, журналов документов и т.д.) имеют достаточно простую структуру и в данной книге не рассматриваются.
Псевдонимы источников КАК/AS
В языке запросов есть возможность указать псевдоним для таблицы-источника с помощью ключевого слова КАК. При этом можно обращаться к источнику через псевдоним, например, в списке полей конструкции ВЫБРАТЬ или при соединении таблиц, которое будет описано ниже.
Ниже приведен пример использования псевдонима таблицы-источника:
ВЫБРАТЬ Спр.Наименование,
Спр.Цена,
Спр.Страна
ИЗ Справочник.Номенклатура КАК Спр |
Наименование |
Цена |
Страна |
1C: Бухгалтерия 7.7 |
35 |
Россия |
1C:Аспект 7.7 |
45 |
Россия |
Программы |
|
|
1C Торгов ля и Склад 7.7 |
140 |
Россия |
Windows ХР |
140 |
США |
|
Запросы к табличным частям
В качестве таблиц источников можно указывать табличные части объектов, например, справочников и документов. Это не то же самое, что получать табличную часть как поле запроса, содержащее вложенную таблицу, о чем было рассказано выше.
Например, в следующем запросе производится обращение к табличной части Состав документа РасходнаяНакладная:
•«ВРАТЬ Товар, Цена, Количество, Сумма *3 Документ.РасходнаяНакладная.Состав
Разработка в системе 1 С:Предприятие 8.0
Товар |
Цена |
Количество |
Сумма |
1 С:Бухгалтерия 7.7 |
70 |
2 |
140 |
Клавиатура Keyboard PS/2 |
4,5 |
5 |
22,5 |
Монитор 15’ LG |
150 |
1 |
150 |
Мышь 2-кноп A4Tech PS/2 |
1,6 |
10 |
16 |
Если запрос делается к табличной части справочника или документа, то обращение к реквизитам шапки документа или обычным реквизитам справочника производится через поле Ссылка, например:
ВЫБРАТЬ Ссылка.Дата, Ссылка.Номер,
Номенклатура, Цена, Количество, Сумма ИЗ Документ.РасходнаяНакладная.Состав |
Дата |
Но
мер |
Номенклатура |
Цена |
Коли
чество |
Сум
ма |
10.01.2002
12:00:01 |
00016 |
1 С:Бухгалтерия 7.7 |
70 |
2 |
140 |
11.01.2002
12:00:00 |
00001 |
Клавиатура Keyboard PS/2 |
4,5 |
5 |
22,5 |
11.01.2002
12:00:00 |
00001 |
Монитор 15' LG |
150 |
1 |
150 |
11.01.2002
12:00:00 |
00001 |
Мышь 2-кноп
A4Tech PS/2 |
1,6 |
10 |
16 |
|
Вложенные запросы в списке источников
В системе 1 ^Предприятие 8.0 можно указать в качестве источника другой запрос, т.е. запрос может выбирать данные из вложенного запроса.
Для вложенного запроса, как для обычной таблицы-источника, можно указать псевдоним, что сделано в следующем примере:
ВЫБРАТЬ Товары.Номенклатура КАК Товар,
Товары.Номенклатура.ЗакупочнаяЦена КАК Цена
ИЗ {
ВЫБРАТЬ Номенклатура ИЗ Документ.РасходнаяВакладная.Состав ОБЪЕДИНИТЬ
ВЫБРАТЬ Номенклатура ИЗ Документ.ПриходнаяНакладная.Состав ) КАК Товары
СГРУППИРОВАТЬ ПО Товары.Номенклатура |
Товар |
Цена |
1 С:Бухгалтерия 7.7 Базовая версия |
70 |
ЮБухгалтерия 7.7 Стандартная версия |
140 |
Клавиатура Keyboard PS/2 |
4,5 |
Монитор 15” LG Studioworks 575N |
150 |
Мышь 2-кноп A4Tech PS/2 |
1,6 |
1C: Бухгалтерия 7.7 Базовая версия |
70 |
|
Конструкция СОЕДИНЕНИЕ... ПО/JOIN... ON
Важной возможностью языка запросов системы 1С:Предприя-тие 8.0 является обращение сразу к нескольким таблицам. При этом их можно соединять определенным образом.
Например, необходимо выбрать все проданные товары и вывести их в отчет с указанием группы, к которой они относятся. Это делает представленный ниже запрос:
ВЫБРАТЬ Док.Номенклатура,
Спр.ЗакупочнаяЦена КАК Цена,
Спр.Родитель КАК Группа ИЗ Документ.РасходнаяНакладная.Состав КАК Док СОЕДИНЕНИЕ Справочник. Номенклатура КАК Спр ПО Док.Номенклатура = Спр.Ссылка
Результат этого запроса показан ниже:
Номенклатура |
Цена |
Группа |
1C: Бухгалтерия 7.7 |
35 |
Программы |
Клавиатура Keyboard PS/2 |
3 |
Клавиатуры |
Монитор 15” LG |
134,5 |
Мониторы |
Мышь 2-кноп A4Tech PS/2 |
1,2 |
Мыши |
Мышь LOGITECH M-S48 |
0,8 |
Мыши |
Разработка в системе 1 ^Предприятие 8.0
В данном примере того же эффекта можно добиться, если просто обращаться к имени поля через точку, что называется разыменованием ссылочных полей. При этом соединение таблиц производится неявно.
Следующий запрос эквивалентен предыдущему и использует разыменование полей:
ВЫБРАТЬ Номенклатура,
Номенклатура.ЗакупочнаяЦена КАК Цена,
Номенклатура.Родитель КАК Группа ИЗ Документ.РасходнаяНакладная.Состав
Возможность разыменования полей в 1С:Предприятии 8.0 допускает обращение к свойствам объектов через несколько точек, например, «Номенклатура. Поставщик. Страна». Это позволяет значительно упростить написание запросов.
Рассмотренное соединение относится к классу внутренних. В языке запросов системы 1С:Предприятие 8.0 существует возможность внешних соединений, которые могут быть левыми (LEFT OUTER), правыми (RIGHT OUTER) и полными (FULL OUTER).
Левое внешнее соединение
Конструкция ЛЕВОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Но, в отличие от внутреннего соединения, в результат запроса надо включить еще и записи из первого источника (указанного слева от слова СОЕДИНЕНИЕ), для которых не найдено соответствующих условию записей из второго источника.
Таким образом, в результат запроса будут включены все записи из первого источника', они будут соединены с записями из второго источника при выполнении указанного условия. Строки результата запроса, для которых не найдено соответствующих условию записей из второго источника, будут содержать значение NULL в полях, формируемых на основании записей из этого источника.
Обратите внимание, что NULL-значения не являются нулем или пустой строкой. Это специальные маркеры, обозначающие неука-
занные (отсутствующие) значения или значения, не имеющие смысла.
Например, нужно показать курсы всех валют, которые хранятся в регистре сведений КурсыВалют. Возможно, что для некоторой валюты не будет найдено соответствующей записи в регистре сведений, но она также должна попасть в отчет (запросы к регистрам сведений и таблица СрезПоследних описаны в главе «Регистры сведений»):
Результат запроса показан в следующей таблице:
ВЫБРАТЬ Спр.Наименование, Per.Курс ИЗ Справочник.Валюты КАК Спр ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
РегистрСведений.КурсыВалют.СрезПоследних КАК Per ПО Спр.Ссылка = Per.Валюта |
Наименование |
Курс |
EUR |
30,8717 |
GBR |
|
USD |
31,4568 |
Рубль |
1 |
|
Правое внешнее соединение
Конструкция ПРАВОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Кроме того, в результат запроса надо включить еще и записи из второго источника (указанного справа от слова СОЕДИНЕНИЕ), для которых не найдено соответствующих условию записей из первого источника.
Таким образом, в результат запроса будут включены все записи из второго источника] они будут соединены с записями из первого источника при выполнении указанного условия. Строки результата запроса, для которых не найдено соответствующих условию записей из первого источника, будут содержать значение NULL в полях, формируемых на основании записей из этого источника.
Разработка в системе 1С:Предприятие 8.0
Правое внешнее соединение полностью аналогично левому, за исключением того, что таблицы поменялись местами. Например, представленный ниже запрос эквивалентен предыдущему, но вместо левого, используется правое внешнее соединение:
ВЫБРАТЬ Спр.Наименование, Per.Курс
ИЗ РегистрСведений.КурсыВалют.СрезПоследних() КАК Per ПРАВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ Справочник.Валюты КАК Спр ПО Спр.Ссылка = Per.Валюта
Полное внешнее соединение
Конструкция ПОЛНОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ означает, что в результат запроса надо включить комбинации записей из обеих исходных таблиц, которые соответствуют указанному условию. Кроме того, в результат запроса надо включить также еще и те записи из обоих источников, для которых не найдено соответствий.
Таким образом, в результат запроса будут включены все записи из обоих источников; они будут соединены друг с другом при выполнении указанного условия. Строки результата запроса, для которых не найдено соответствующих условию записей из какого-либо источника, будут содержать NULL в полях, формируемых на основании записей из этого источника.
Предложение ГДЕ / WHERE
Предложение ГДЕ позволяет задать условие отбора данных из исходных таблиц-источников запроса. В запросе будут выбраны только те записи, для которых выполняется заданное условие.
Например, выберем товары с ценой, большей или равной определенному значению:
ВЫБРАТЬ Наименование, ЗакупочнаяЦена КАК Цена ИЗ Справочник.Номенклатура ГДЕ ЗакупочнаяЦена >= 1300
Результат запроса будет следующий: |
Наименование |
Цена |
Монитор LCD 22" M8537ZM/A |
1 540 |
|
Наименование |
Цена |
Ноутбук Rover Computers Explorer |
1 326 |
Сист. блок Hewlett-Packard Brio ВА410 |
1 633 |
Сист. блок Hewlett-Packard Vectra VL420 |
1 699 |
Логические операторы И, ИЛИ, НЕ
В условиях можно использовать логические операторы И, ИЛИ, НЕ, с помощью которых можно строить достаточно сложные логические выражения.
Например, выберем товары, произведенные в России по цене, меньшей определенного значения:
ВЫБРАТЬ Наименование,
ЗакупочнаяЦена КАК Цена,
СтранаПроисхождения КАК Страна ИЗ Справочник.Номенклатура
ГДЕ СтранаПроисхождения = "Россия" И ЗакупочнаяЦена < 1000 |
Наименование |
Цена |
Страна |
1 С:Бухгалтерия 7.7 |
35 |
Россия |
1C:Аспект 7.7 |
45 |
Россия |
1С:Торговля и Склад 7.7 |
140 |
Россия |
1С:Бухгалтерия 7.7 |
35 |
Россия |
|
В реальных задачах крайне рекомендуется уточнять у пользователей условия на такого рода неравенства, потому что пользователь часто имеет в виду «меньше или равно», а не «строго меньше». Возможно, в данном запросе товары с ценой 1000 тоже подойдут, тогда знак «<» надо заменить на «<=».
При указании нескольких логических сомножителей И, ИЛИ, НЕ целесообразно расставлять скобки, чтобы правильно определить порядок выполнения логических операций и повысить наглядность запроса.
Например, следующие два запроса могут привести к неожиданным для программиста результатам, потому что оператор И имеет
Разработка в системе 1 С:Предприятие 8.0
больший приоритет, чем ИЛИ (а оператор НЕ имеет еще больший приоритет, чем И):
ВЫБРАТЬ Наименование,
ЗакупочнаяЦена КАК Цена,
СтранаПроисхождения КАК Страна ИЗ Справочник.Номенклатура
ГДЕ СтранаПроисхождения = "Россия" ИЛИ СтранаПроисхождения = "США"
И ЗакупочнаяЦена < 1000
В результате мы получим следующие записи:
Наименование |
Цена |
Страна |
Клавиатура Apple Pro Keyboards |
50 |
США |
Лазерный принтер Minolta-QMS |
361 |
США |
Лазерный принтер HP LaserJet 2200 |
720 |
США |
Монитор 19" Hitachi CM715ET |
300 |
Россия |
Ноутбук Rover Computers Explorer |
1326 |
Россия |
Этот запрос будет интерпретирован системой как «Выбрать все товары из страны Россия, независимо от цены, а также товары из страны США, которые дешевле 1000». Т.е. условие по цене будет проверяться только для товаров из США, а товары из России будут включены в запрос при любой цене.
Вероятно, программист имел в виду совсем другое: «Выбрать товары из России и США, которые дешевле 1000», что реализовано вторым запросом. Условие по цене будет проверяться для всех товаров, независимо от страны-производителя:
ВЫБРАТЬ Наименование,
ЗакупочнаяЦена КАК Цена,
СтранаПроисхождения КАК Страна
ИЗ Справочник.Номенклатура
ГДЕ (СтранаПроисхождения = "Россия" ИЛИ СтранаПроисхождения = "США")
И ЗакупочнаяЦена < 1000
Наименование |
Цена |
Страна |
Клавиатура Apple Pro Keyboards |
50 |
США |
Лазерный принтер Minolta-QMS |
361 |
США |
Лазерный принтер HP LaserJet 2200 |
720 |
США |
Наименование |
Цена |
Страна |
Монитор 19" Hitachi CM715ET |
300 |
Россия |
Параметры в языке запросов
Обычно требуется, чтобы параметры условий пользователь мог указать самостоятельно в каком-либо диалоге. Для этого запрос конструируется с использованием параметров.
Обратите внимание, что в следующем запросе параметр МинЦена предваряется знаком «&».
ВЫБРАТЬ Наименование, ЗакупочнаяЦена ИЗ Справочник.Номенклатура ГДЕ ЗакупочнаяЦена >= &МинЦена
Общая схема выполнения запроса с параметрами выглядит следующим образом:
//создание объекта Запрос с текстом запроса Запрос = Новый Запрос("Выбрать Наименование, Цена ]ИЗ Справочник.Номенклатура I ГДЕ Цена >= ШинЦена") ;
//передача параметров в запрос
Запрос.УстановитьПараметр("МинЦена",1000);
//выполнение запроса с установленными параметрами Результат = Запрос.Выполнить();
Стоит заметить, что для многих типов данных в языке запросов нет литералов, поэтому их значения можно задать только через параметры, даже если пользователь не должен их изменять.
Ключевое слово МЕЖДУ/ BETWEEN
В языке запросов есть вспомогательное ключевое слово МЕЖДУ для задания интервалов. Например, если параметр МинЦена равен 1000, а МаксЦена — 1500, тогда следующий запрос выберет товары с ценой из указанного интервала:
ВЫБРАТЬ Наименование,
ЗакупочнаяЦена КАК Цена
ИЗ Справочник.Номенклатура
ГДЕ ЗакупочнаяЦена МЕЖДУ &МинЦена И ШаксЦена
Разработка в системе 1С Предприятие 8.0
Наименование |
Цена |
Ноутбук Rover Computers Explorer |
1 326 |
Ноутбук Rover Computers Navigator KT7 |
1 118 |
Сист. блок IBM NetVista A22p |
1 111 |
Сист. блок IBM NetVista M41 |
1 222 |
Ключевое слово МЕЖДУ введено для повышения наглядности при задании интервалов и всегда может быть заменено неравенствами. Следующий запрос полностью эквивалентен предыдущему:
ВЫБРАТЬ Наименование, ЗакупочнаяЦена ИЗ Справочник.Номенклатура
ГДЕ ЗакупочнаяЦена >= МинЦена И ЗакупочнаяЦена <= МаксЦена
Проверка вхождения значения в список (В / IN)
В условии можно проверять значения на вхождение в некоторый список или на принадлежность группе справочника (или элементу, если иерархический справочник состоит из одних элементов). В случае иерархического справочника можно применять конструкцию В ИЕРАРХИИ для проверки вхождения в группу независимо от уровня иерархии.
Следующие запросы демонстрируют варианты использования ключевого слова В:
//выбираем товары из заданного списка ВЫБРАТЬ Наименование, ЗакупочнаяЦена ИЗ Справочник.Номенклатура ГДЕ Ссылка В (&СписокВыбранныхТоваров)
//выбираем товары, принадлежащие определенной группе
//независимо от уровня, на котором они находятся
ВЫБРАТЬ Наименование, ЗакупочнаяЦена
ИЗ Справочник.Номенклатура
ГДЕ Ссылка В ИЕРАРХИИ (ЬВыбраннаяГруппа)
В первом запросе параметр СписокВыбранныхТоваров является списком значений. В запросе будут выбраны только те товары, которые представлены в данном списке.
Во втором запросе параметр ВыбраннаяГруппа является группой иерархического справочника Номенклатура. В результат запроса
будут включены товары, принадлежащие к заданной группе, независимо от того, на каком уровне иерархии они находятся.
В качестве списка значений, можно указывать и другой запрос, тогда сначала будет выполнен вложенный запрос, а затем основной. Например, следующий составной запрос выбирает товары, по которым есть хотя бы одна расходная накладная:
ВЫБРАТЬ Спр.Наименование, Спр.ЗакупочнаяЦена
ИЗ Справочник.Номенклатура КАК Спр
ГДЕ Спр.Ссылка В (ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура
ИЗ Документ.РасходнаяНакладная.Состав)
Заметим, что в данном случае это было искусственное усложнение запроса. Того же результата можно добиться проще, используя разыменование полей:
ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура, Номенклатура.ЗакупочнаяЦена ИЗ Документ.РасходнаяНакладная.Состав
Это стало возможно, потому что разыменование полей заставляет систему 1С:Предприятие 8.0 производить неявное соединение таблиц. Рекомендуется всегда пользоваться разыменованием полей там, где это возможно, и не усложнять запросы лишними конструкциями.
Проверка ссылочного значения (ССЫЛКА /REF)
Оператор ССЫЛКА позволяет проверить, является ли значение выражения ссылкой на таблицу, указанную справа от него. Этот оператор полезен для полей, имеющих составной тип данных.
Следующий запрос выбирает товары, для которых единица измерения ссылается на справочник ЕдиницыИзмерения, а не является, например, строкой.
ВЫБРАТЬ Наименование, ЕдиницаИзмерения ИЗ Справочник.Номенклатура
ГДЕ ЕдиницаИзмерения ССЫЛКА Справочник.ЕдиницыИэмерения
Проверка пустых значений (ЕСТЬ NULL/ IS NULL)
Оператор ЕСТЬ NULL позволяет проверить значение заданного выражения на NULL.
Разработка в системе 1С:Предприятие 8.0
Замечание. NULL-значения не являются нулем (0), пустой строкой («») или пробелом (« »). NULL-значения - это неуказанные, отсутствующие или неизвестные значения.
Если проверяемое значение равно NULL, то результатом оператора будет Истина, иначе — Ложь. Применение логического оператора НЕ изменяет действие оператора на обратное. Любая операция обычного сравнения (=, >, <= и т.д.) значения NULL с чем-либо еще дает результат, аналогичный Ложь.
Следующий запрос выбирает из справочника Номенклатура все товары, для которых строковое поле СтранаПроисхождения имеет NULL-значение:
ВЫБРАТЬ Наименование, СтранаПроисхождения КАК Страна
ИЗ Справочник.Номенклатура
ГДЕ СтранаПроисхождения ЕСТЬ NULL |
Наименование |
Страна |
Программное обеспечение |
|
Услуги |
|
Клавиатуры |
|
Принтеры |
|
Мониторы |
|
|
Обратите внимание, что в результате запроса присутствуют только группы справочника, так как для них поле Страна имеет NULL-значение (вообще не указывается). В результат запроса не попали товары, у которых строковое поле СтранаПроисхождения имеет значение «» (пустая строка). Как уже было сказано выше, ни ноль, ни пустая строка, ни пробел не являются NULL-значением.
Чтобы выбрать товары, у которых не указана страна (строковое поле), нужно применить обычное сравнение на пустую строку:
ВЫБРАТЬ Наименование, СтранаПроисхождения КАК Страна ИЗ Справочник.Номенклатура ГДЕ СтранаПроисхождения = ""
Наименование |
Страна |
Доставка |
|
Инсталляция ПО |
|
Консультации по настройке ОС Windows |
|
Монитор 15" LG Studioworks 575N |
|
Если стоит задача выбрать элементы с неуказанным реквизитом, имеющим ссылочный тип, тогда следует поступать по-другому. Например, требуется выбрать все товары с незаполненным полем ОсновнойПоставщик, которое является ссылкой на справочник Контрагенты.
Предлагается следующая схема для решения этой задачи:
Запрос = Новый Запрос(”
I ВЫБРАТЬ Наименование, ОсновнойПоставщик I ИЗ Справочник.Номенклатура
I ГДЕ ОсновнойПоставщик = йПустойКонтрагент ’’);
Запрос.УстановитьПараметр(’’ПустойКонтрагент’’ ,
Справочники.Контрагенты.ПустаяСсылка());
Результат = Запрос.Выполнить();
В условии запроса используется параметр ПустойКонтрагент. Этот параметр до выполнения запроса получает значение пустой ссылки на справочник Контрагенты. Для этого используется метод ПустаяСсылка объекта СправочникМенеджер.
Результат приведенного выше запроса будет следующий:
Наименование |
ОсновнойПоставщик |
Монитор 19" Hitachi CM715ET |
|
Монитор LCD 22" M8537ZM/A |
|
Мышь GENIUS «EASY» (3 кнопки), |
|
Мышь Ice Mouse MUS-2 |
|
Мышь LOGITECH M-S48 PS/2 |
|
Сравнение строк (ПОДОБНО / LIKE)
Ключевое слово ПОДОБНО позволяет сравнить значение строкового выражения, указанного слева от него, со строкой шаблона, указанной справа. Если значение выражения удовлетворяет шаблону, то результатом оператора будет Истина, иначе — Ложь.
Например, следующий запрос выберет всех контрагентов, начинающихся на определенную букву:
ВЫБРАТЬ Наименование ИЗ Справочник.Контрагенты Г?,Е Наименование ПОДОБНО ”М%”
Наименование
Магазин на ул. Алексеева Максимус
В выражении шаблона был использован служебный символ «%», обозначающий любую последовательность символов. Кроме этого, есть и другие служебные символы для задания выражения шаблона.
Следующие символы в строке шаблона являются служебными и имеют особый смысл:
Служебный символ |
Описание |
% (процент) |
Последовательность, содержащая любое количество произвольных символов (как и было использовано в последнем примере). Например, шаблон «%ый» обозначает любую строку, заканчивающуюся на «ый». |
_ (подчеркивание) |
Один произвольный символ. Например, под шаблон « аша» подходят Маша,
Даша, Саша, Паша и т.д. |
[...] (в квадратных скобках один или несколько символов): |
Любой одиночный символ из перечисленных внутри квадратных скобок. Например, под шаблон <<[МД]аша» подходят Маша или Даша. В перечислении могут |
Служебный символ |
Описание |
|
встречаться диапазоны, например, А-Я, означающие произвольный символ, входящий в диапазон, включая концы диапазона. |
[Л...] (в квадратных скобках значок отрицания (крышечка), за которым следует один
или несколько символов |
Любой одиночный символ, кроме тех, которые перечислены следом за значком отрицания. Например, под шаблон «[АМД]аша» Маша и Даша уже не подходят, а подходят Паша и Саша. |
Если необходимо записать один из перечисленных символов в качестве самого себя, а не в качестве служебного символа, то ему должен предшествовать спецсимвол, который определяется в этом же операторе после ключевого слова СПЕЦСИМВОЛ.
Например, следующая строка обозначает любую строку, начинающуюся со знака подчеркивания «_». Так как знак подчеркива
ния является служебным, то для его использования в качестве именно знака подчеркивания, необходимо его экранировать другим спецсимволом, например «\»:
ВЫБРАТЬ Наименование ИЗ Справочник.СистемныеФайлы ГДЕ Наименование ПОДОБНО "\_%" СПЕЦСИМВОЛ "\"
Предложение УПОРЯДОЧИТЬ ПО / ORDER BY
Часто результат запроса требуется отсортировать по алфавиту или по числовому полю. В общем случае в качестве значения упорядочивания может быть выражение.
Например, представим список товаров, упорядоченный по алфавиту. При сортировке сначала идут товары, начинающиеся на цифры, затем на английские буквы, а затем на русские буквы:
ВЫБРАТЬ Код, Наименование ИЗ Справочник.Номенклатура УПОРЯДОЧИТЬ ПО Наименование ВОЗР
Код |
Наименование |
00014 |
1С:Бухгалтерия ПРОФ версия 7.7 |
00016 |
1С:Торговля и Склад 7.7 Проф |
00009 |
Windows XP Home Edition Russian CD |
00010 |
Windows XP Home Edition Russian UPG CD |
00011 |
Windows XP Professional Russian CD |
00041 |
' Доставка |
00042 |
Инсталляция ПО |
00018 |
Клавиатура Apple Pro Keyboards |
Сортировка часто применяется с ключевым словом ПЕРВЫЕ. Например, следующий запрос сортирует товары по убыванию цены и показывает 5 самых дорогих товаров:
Результат запроса показан в таблице:
ВЫБРАТЬ ПЕРВЫЕ 5 Код, Наименование, ЗакупочнаяЦена КАК Цена ИЗ Справочник.Номенклатура УПОРЯДОЧИТЬ ПО Цена УБЫВ |
Код |
Наименование |
Цена |
00035 |
Ноутбук Rover Computers Explorer |
1326 |
00039 |
Сист. блок IBM Net Vista M41 |
1 222 |
00034 |
Ноутбук Rover Computers Navigator KT7 |
1 118 |
00038 |
Сист. блок IBM NetVista A22p |
1 111 |
00032 |
Лазерный принтер HP LaserJet 2200 |
720 |
|
Упорядочивание по иерархии
Для иерархических справочников можно упорядочить элементы с учетом иерархии. Если мы имеем дело со справочником товаров, то вряд ли будет наглядным отчет, в котором клавиатуры череду-
ются с мониторами. Каждый вид товара должен быть упорядочен в пределах своей группы.
Это достигается с помощью ключевого слова ИЕРАРХИЯ, которое используется в следующем запросе:
ВЫБРАТЬ Ссылка КАК Товар ИЗ Справочник.Номенклатура УПОРЯДОЧИТЬ ПО Наименование ИЕРАРХИЯ
Товар
Клавиатуры
Клавиатура Apple Pro Keyboards Клавиатура Keyboard PS/2 Клавиатура Linkworld LK-601 PS/2 Клавиатура LK-боГ КВЯООО PS/2
Мониторы
Монитор 15” LG Studioworks 575N Монитор 17" Philips 107S20 Монитор 19” Hitachi СМ715ЕТ МониторІСО 22"M8M7ZM/A
Будьте внимательны, когда составляете подобный запрос не к справочнику, а к документу или регистру, в котором есть реквизит, выбираемый из иерархического справочника. В этом случае иерархического упорядочивания не происходит.
Следующий запрос это демонстрирует:
ВЫБРАТЬ Номенклатура КАК Товар ИЗ Документ.РасходнаяНакладная.Состав УПОРЯДОЧИТЬ ПО Номенклатура.Наименование ИЕРАРХИЯ
Для нужного эффекта необходимо организовать левое внешнее соединение со справочником, как сделано в этом запросе:
ВЫБРАТЬ Спр.Ссылка Товар, ДокСостав-Ссылка Документ ИЗ Справочник.Номенклатура КАК Спр
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходнаяНакладная.Состав КАК ДокСостав ПО ДокСостав.Номенклатура = Спр.Ссылка
Разработка в системе 1С:Предприятие 8.0
УПОРЯДОЧИТЬ ПО Спр.Наименование ИЕРАРХИЯ |
Товар |
Документ |
Клавиатуры |
|
Клавиатура LK-601 КВ-2000 PS/2 |
Расходная накладная 00032 от 25.07.2002 12:00:00 |
Клавиатура LK-601 KB-2000 PS/2 |
Расходная накладная 00011 от 10.05.2002 12:00:00 |
Клавиатура LK-601 KB-2000 PS/2 |
Расходная накладная 00020 от 02.08.2002 10:44:45 |
Мониторы |
|
Монитор 15" LG Studio-works 575N |
Расходная накладная 00019 от 06.06.2002 12:00:00 |
Монитор 15" LG Studio-works 575N |
Расходная накладная 00006 от 15.02.2002 12:00:00 |
Монитор 15" LG Studio-works 575N |
Расходная накладная 00018 от 15.06.2002 12:00:00 |
|
Упорядочивание во вложенных таблицах
В предложении УПОРЯДОЧИТЬ ПО можно определять также и условия сортировки записей из вложенных таблиц, причем их можно комбинировать с условиями упорядочивания по таблице верхнего уровня.
Например, необходимо вывести спецификацию товарных накладных, показать сам документ, номенклатуру и количество. Документы требуется упорядочить по номеру, а данные из табличной части Состав — по наименованию товара.
Это делается с помощью следующего запроса:
ВЫБРАТЬ НаклСостав.Ссылка.Номер,
Номенклатура, Количество
ИЗ Документ.РасходнаяНакладная.Состав КАК НаклСостав
УПОРЯДОЧИТЬ ПО НаклСостав.Ссылка.Номер,
НаклСостав.Номенклатура.Наименование
Номер |
Номенклатура |
Количество |
00001 |
Мышь LOGITECH M-S48 PS/2 |
10 |
00001 |
Мышь ОК-720 Mouse A4Tech PS/2 |
2 |
00002 |
1C: Аспект 7.7 |
1 |
00003 |
Windows XP Home Edition |
1 |
00003 |
Доставка |
13 |
00003 |
Инсталляция ПО |
2 |
Автоупорядочивание /AUTOORDER
Ключевое слово АВТОУПОРЯДОЧИВАНИЕ позволяет включить режим автоматического формирования полей для упорядочивания результата запроса. Оно часто используется при построении отчетов.
Автоупорядочивание работает по следующим правилам:
• Если в запросе было указано предложение УПОРЯДОЧИТЬ ПО, то каждая ссылка на таблицу, находящаяся в этом предложении, будет заменена полями, по которым по умолчанию сортируется таблица (для справочников это код или наименование, для документов — дата документа). Если поле для упорядочивания ссылается на иерархический справочник, то будет применена иерархическая сортировка по этому справочнику.
• Если в запросе отсутствует предложение УПОРЯДОЧИТЬ ПО, но есть предложение ИТОГИ, тогда результат запроса будет упорядочен по полям, присутствующим в предложении ИТОГИ после ключевого слова ПО, в той же последовательности и в случае, если итоги рассчитывались по ссылочным полям, то по полям сортировки по умолчанию таблиц, на которые были ссылки.
• Если в запросе отсутствуют предложения УПОРЯДОЧИТЬ ПО и ИТОГИ, но есть предложение СГРУППИРОВАТЬ ПО, тогда результат запроса будет упорядочен по полям, присутствующим в предложении, в той же последовательности и в слу-
Разработка в системе 1С:Предприятие 8.0
чае если группировка велась по ссылочным полям, то по полям сортировки по умолчанию таблиц, на которые были ссылки.
• И наконец, если в запросе отсутствуют предложения УПОРЯДОЧИТЬ ПО, ИТОГИ и СГРУППИРОВАТЬ ПО, результат будет упорядочен по полям сортировки по умолчанию для таблиц, из которых выбираются данные, в порядке их появления в запросе.
Агрегатные функции в запросе
Часто требуется не просто выбрать отдельные записи из базы данных, а получить сводную информацию, например, для ответа на следующие вопросы:
• Каков общий объем продаж за период?
• Какова средняя стоимость заказа в каждом филиале?
• Сколько сотрудников работает в штате?
• Какова наименьшая и наибольшая цена продажи каждого товара?
В системе 1 С:Предприятие 8.0 такие запросы можно создавать с помощью агрегатных функций, группировок и предложения ИМЕЮЩИЕ (HAVING). Ниже будут описаны агрегатные функции языка запросов.
Любая агрегатная функция принимает в качестве аргумента какой-либо столбец, а возвращает единственное значение. Например, агрегатная функция СУММА (SUM) принимает в качестве аргумента столбец чисел и вычисляет его сумму.
В языке запросов 1 С:Предприятия 8.0 существуют следующие агрегатные функции:
СУММА (SUM)
Вычисляет сумму всех значений, содержащихся в столбце.
МАКСИМУМ (МАХ)
Находит наибольшее значение в столбце.
МИНИМУМ (MIN)
Находит наименьшее значение в столбце.
СРЕДНЕЕ (AVG)
Вычисляет среднее арифметическое значение по столбцу.
КОЛИЧЕСТВО (COUNT)
Подсчитывает количество значений, содержащихся в столбце. Если в качестве параметра данной функции передать звездочку («
»), то функция подсчитает количество строк в таблице результата запроса.
Ниже приведен пример запроса с несколькими агрегатными функциями:
ВЫБРАТЬ
СУММА(Оклад) КАК ФондОплатыТруда,
МИНИМУМ(Оклад) КАК МинОклад,
МАКСИМУМ(Оклад) КАК МаксОклад,
СРЕДНЕЕ(Оклад) КАК СреднийОклад,
КОЛИЧЕСТВО)
) КАК Количество ИЗ Справочник.Сотрудники
Результат запроса будет содержать всего одну строку: |
ФондОплаты
Труда |
МинОклад |
Макс
Оклад |
Средний
Оклад |
Коли
чество |
1500000 |
6000 |
17000 |
9000 |
30 |
|
Рассмотрим более подробно функцию КОЛИЧЕСТВО / COUNT. Эта функция подсчитывает количество значений параметра, попавших в выборку.
В отличие от других агрегатных функций она допускает три варианта использования:
Разработка в системе 1 С: Предприятие 8.0
чевое слово РАЗЛИЧНЫЕ / DISTINCT, при этом NULL-значения игнорируются.
Например, с помощью функции КОЛИЧЕСТВО можно ответить
на следующие вопросы:
• Сколько сотрудников, у которых оклад больше заданной величины?
ВЫБРАТЬ КОЛИЧЕСТВО)*) КАК Количество ИЗ Справочник. Сотрудники ГДЕ Оклад > &ВыбОклад
• Сколько различных клиентов купили хоть что-нибудь за заданный период?
ВЫБРАТЬ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Контрагент) КАК Количество ИЗ Документ. РасходнаяНакладная ГДЕ Дата МЕЖДУ ШачДата И &КонДата
Предложение СГРУППИРОВАТЬ ПО / GROUP BY
Очень часто запрос делается с целью не просто выбрать записи из таблицы, но также сгруппировать их определенным образом. Под словом «сгруппировать» имеется в виду не распределить записи по группам, а свернуть по группировочным полям, вычислив агрегатные функции по каждой группе.
Например, если требуется узнать объем продаж каждого товара за период, тогда в запросе понадобится группировка по товару. Ниже приведен запрос с группировкой к документам РасходнаяНакладная:
ВЫБРАТЬ Номенклатура, СУММА(Сумма) КАК ОбъемПродаж ИЗ Документ.РасходнаяНакладная.Состав КАК ДокСостав ГДЕ ДокСостав.Ссылка.Дата МЕЖДУ ЬНачДата И &КонДата СГРУППИРОВАТЬ ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ
В данном примере использована агрегатная функция СУММА для поля Сумма табличной части Состав. Запрос группирует все продажи по товарам и подсчитывает объем продаж по каждому товаРУ:
Номенклатура |
ОбъемПродаж |
1С:Торговля и Склад 7.7 Проф |
1 540 |
Windows XP Home Edition Russian CD |
1 360 |
Windows XP Home Edition Russian UPG CD |
1 105 |
Windows XP Professional Russian CD |
2480 |
Доставка |
40 |
Инсталляция ПО |
60 |
Клавиатура Apple Pro Keyboards |
5890 |
Клавиатура Keyboard PS/2 |
384 |
Таким образом, в большинстве случаев группировки используются совместно с агрегатными функциями. Если взять пример из предыдущего параграфа и добавить группировку по подразделению, то можно легко детализировать информацию до подразделений и получить ценную информацию для анализа:
ВЫБРАТЬ
Подразделение,
СУММА(Оклад) КАК ФондОплатыТруда МИНИМУМ(Оклад) КАК МинОклад,
МАКСИМУМ(Оклад) КАК МаксОклад,
СРЕДНЕЕ(Оклад) КАК СреднийОклад,
КОЛИЧЕСТВО(*) КАК КоличествоЧеловек ИЗ Справочник.Сотрудники СГРУППИРОВАТЬ ПО Подразделение
Подразделение |
Фонд
Оплаты
Труда |
Мин
Оклад |
Макс
Оклад |
Средний
Оклад |
Коли
чество
Человек |
Бухгалтерия |
30000 |
6000 |
16000 |
10000 |
9 |
Маркетинг |
40000 |
6500 |
15000 |
11000 |
7 |
Разработка в системе 1 С: Предприятие 8.0
Подразделение |
Фонд
Оплаты
Труда |
Мин
Оклад |
Макс
Оклад |
Средний
Оклад |
Коли
чество
Человек |
Снабжение |
30000 |
7000 |
12000 |
9000 |
8 |
Руководство |
50000 |
9000 |
17000 |
14000 |
6 |
В языке запросов можно группировать данные по нескольким полям, при этом будут подсчитаны агрегатные функции для каждой комбинации группировок:
ВЫБРАТЬ Номенклатура,
ДокСостав.Ссылка.Контрагент КАК Контрагент, СУММА(Сумма) КАК Продажи
ИЗ Документ.РасходнаяНакладная.Состав КАК ДокСостав ГДЕ ДокСостав.Ссылка.Дата МЕЖДУ ШачДата И &КонДата СГРУППИРОВАТЬ ПО Номенклатура, Контрагент АВТОУПОРЯДОЧИВАНИЕ
Номенклатура |
Контрагент |
Продажи |
1С:Аспект 7.7 |
Алекс-2002 |
270 |
1C: Аспект 7.7 |
Магазин на ул. Алексеева |
270 |
1C: Аспект 7.7 |
Эльбрус |
180 |
1С:Бухгалтерия 7.7 |
Магазин на ул. Алексеева |
210 |
1С:Бухгалтерия 7.7 |
Эльбрус |
140 |
Предложение ИМЕЮЩИЕ / HAVING
Предложение ИМЕЮЩИЕ позволяет накладывать условия на значения агрегатных функций. В других конструкциях языка запросов, например, в предложении ГДЕ, использовать агрегатные функции в условиях нельзя. В условии отбора ИМЕЮЩИЕ можно использовать только агрегатные функции и поля, по которым осуществляется группировка.
Например, необходимо выбрать товары, которых продали не менее 70 штук. Тогда нужно сначала подсчитать объем продаж по
каждому товару, а затем применить условие отбора уже к получившимся группам, а не к исходным записям.
Эта задача решается с помощью приведенного ниже запроса:
Результат запроса будет следующий:
ВЫБРАТЬ Номенклатура, Сумма (Количество) КАК Продано ИЗ Документ.РасходнаяНакладная.Состав СГРУППИРОВАТЬ ПО Номенклатура ИМЕЮЩИЕ Сумма (Количество) >= 7 0 |
Номенклатура |
Продано |
Клавиатура Apple Pro Keyboards |
79 |
Клавиатура Keyboard PS/2 |
79 |
Клавиатура LK-601 KB-2000 PS/2 |
76 |
Мышь 2-кноп A4Tech PS/2 |
102 |
Мышь Ice Mouse MUS-2 |
89 |
Мышь LOGITECH M-S48 PS/2 |
98 |
|
Приведем другой пример, когда отбор групп необходим. Выберем клиентов, купивших за заданный период товаров на сумму 10000 и выше:
ВЫБРАТЬ Контрагент, СУММА(Сумма) КАК Куплено
ИЗ РегистрНакопления.Продажи
ГДЕ Период МЕЖДУ &НачДата И ЬКонДата
СГРУППИРОВАТЬ ПО Контрагент
ИМЕЮЩИЕ СУММА (Сумма) >= 10000 |
Контрагент |
Куплено |
Автохозяйство №34 |
10 698,6 |
Алекс-2002 |
76 519,2 |
Завод РТИ |
15 007,9 |
Магазин на ул. Алексеева |
63 525,1 |
Эльбрус |
31 084,7 |
|
Разработка в системе 1 С:Предприятие 8.0
Обратите внимание, что ключевое слово ГДЕ применяется здесь только для отбора записей за нужный период. Затем данные группируются по контрагенту с подсчетом суммы проданных товаров, и к получившимся строкам применяется условие
ИМЕЮЩИЕ.
Предложение ИТОГИ / TOTALS
Язык запросов системы 1С:Предприятие 8.0 имеет очень мощную возможность расчета итогов, чего нет в стандартном языке SQL. Данный механизм дает возможность включить в результат запроса дополнительные строки, содержащие общие и промежуточные итоги по заданным полям и группировкам.
Общие итоги
Рассмотрим сначала общие итоги, как более простые для понимания. Следующий запрос выбирает из регистра накопления Продажи все записи за заданный период и рассчитывает общий объем продаж:
ВЫБРАТЬ Номенклатура, Сумма ИЗ РегистрНакопления.Продажи ИТОГИ СУММА (Сумма) ПО Общие
В результате запроса появляется дополнительная итоговая строка: |
Номенклатура |
Сумма |
|
445 |
1С:Бухгалтерия 7.7 Базовая версия |
140 |
1С:Бухгалтерия 7.7 Стандартная версия |
280 |
Мышь ОК-720 Mouse A4Tech PS/2 |
3 |
Клавиатура Keyboard PS/2 |
22 |
|
При обходе результата запроса итоговые строки можно отличить от обычных с помощью метода ТипЗаписи().
Например, выведем результат данного запроса в окно сообщений, а итоговую строку выделим заглавными буквами:
Запрос = Новый Запрос!”
[ВЫБРАТЬ Номенклатура, Сумма ІИЗ РегистрНакопления.Продажи 1ИТОГИ СУММА (Сумма) ПО Общие”) ;
Выборка = Запрос.Выполнить () .Выбрать () ;
Пока Выборка.Следующий() Цикл
Если Выборка.ТипЗаписи() = ТипЗаписиЗапроса.ОбщийИтог Тогда
Сообщить(”ОБЩИЙ ИТОГ: ” + Выборка.СуммаПродажи);
Иначе
Сообщить(”Товар/услуга: ” + Выборка.Номенклатура +
” Сумма: ” + Выборка . СуммаПродажи) ;
КонецЕсли;
КонецЦикла;
Итоги по группировкам
При расчете итогов по группировкам вычисляются значения агрегатных функций по выборкам с одинаковыми значениями полей, по которым производится группировка.
Например, в следующей таблице значения группировок выделены жирным шрифтом:
Номенклатура
Вилы
Грабли
Грабли
Грабли
Лопата
Лопата
Простой запрос с итогами по группировкам выглядит следующим образом:
ВЫБРАТЬ Номенклатура, Период, Сумма ИЗ РегистрНакопления.Продажи ИТОГИ СУММА( Сумма) ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ
Результат запроса включает в себя обычные записи из регистра и итоги по каждому товару:
Товар |
Период |
Сумма |
1С:Аспект 7.7 |
|
720 |
ЮАспект 7.7 |
11.01.200221:56:07 |
90 |
ЮАспект 7.7 |
24.02.2002 12:00:00 |
180 |
ЮАспект 7.7 |
26.02.2002 12:00:00 |
180 |
1C: Аспект 7.7 |
04.08.2002 12:00:00 |
270 |
1С:Бухгалтерия 7.7 |
|
350 |
1С:Бухгалтерия 7.7 |
10.01.2002 12:00:01 |
140 |
1С:Бухгалтерия 7.7 |
04.08.2002 12:00:00 |
210 |
Обратите внимание, что запрос с итогами по группировкам отличается от обычной группировки (свертки) с помощью предложения СГРУППИРОВАТЬ ПО с агрегатными функциями. В последнем случае в результат запроса не включаются исходные записи, а остаются только итоговые строки.
Например, следующий запрос выводит объем продаж, сгруппированный по каждой номенклатуре, и не выводит детальные записи регистра накопления:
ВЫБРАТЬ Номенклатура, СУММА(Сумма) КАК Сумма ИЗ РегистрНакопления.Продажи СГРУППИРОВАТЬ ПО Номенклатура АВТОУПОРЯДОЧИВАНИЕ |
Номенклатура |
Сумма |
ЮАспект 7.7 |
720 |
1С:Бухгалтерия 7.7 Базовая версия |
350 |
1C: Бухгалтерия 7.7 Стандартная версия |
280 |
1С:Бухгалтерия ПРОФ версия 7.7 |
1 320 |
1С:Торговля и Склад 7.7 Проф |
1 540 |
|
Можно рассчитать итоги по комбинации группировок, перечислив их через запятую:
ВЫБРАТЬ Контрагент, Номенклатура, Сумма ИЗ РегистрНакопления.Продажи ИТОГИ СУММА(Сумма)
ПО Контрагент, Номенклатура АВТОУПОРЯДОЧИВАНИЕ
В данном запросе будет рассчитан объем продаж по каждой комбинации подразделения и номенклатуры. Кроме того, в запрос будут включены исходные записи из регистра накоплений:
Контрагент |
Номенклатура |
Сумма |
Алекс-2002 |
|
780 |
Алекс-2002 |
1С:Аспект 7.7 |
270 |
Алекс-2002 |
1C: Аспект 7.7 |
90 |
Алекс-2002 |
1C: Аспект 7.7 |
180 |
Алекс-2002 |
Windows XP Ноте |
510 |
Алекс-2002 |
Windows XP Ноте |
170 |
Алекс-2002 |
Windows XP Home |
340 |
Эльбрус |
|
85 |
Эльбрус |
1С:Аспект 7.7 |
85 |
Эльбрус |
1С:Аспект 7.7 |
20 |
Эльбрус |
1С:Аспект 7.7 |
25 |
Эльбрус |
Ю:Аспект 7.7 |
40 |
Порядок группировок в тексте запроса имеет довольно важное значение, поскольку сначала рассчитываются итоги по первому группировочному полю, затем по второму и т.д.
Если в предыдущем примере поменять местами контрагента и номенклатуру, то получим следующий результат:
ВЫБРАТЬ Контрагент, Номенклатура, Сумма ИЗ РегистрНакопления.Продажи ИТОГИ СУММА(Сумма)
ПО Номенклатура, Контрагент
АВТОУПОРЯДОЧИВАНИЕ
Результат запроса показан ниже:
Номенклатура |
Контрагент |
Сумма |
1С:Аспект 7.7 |
|
355 |
1С:Аспект 7.7 |
Алекс-2002 |
270 |
1C: Аспект 7.7 |
Алекс-2002 |
90 |
1C: Аспект 7.7 |
Алекс-2002 |
180 |
1С:Аспект 7.7 |
Эльбрус |
85 |
Ю:Аспект 7.7 |
Эльбрус |
20 |
Ю:Аспект 7.7 |
Эльбрус |
25 |
Ю:Аспект 7.7 |
Эльбрус |
40 |
Windows XP Home Edition |
|
510 |
Windows XP Home Edition |
Алекс-2002 |
510 |
Windows XP Home Edition |
Алекс-2002 |
170 |
Windows XP Home Edition |
Алекс-2002 |
340 |
В 1С:Предприятии 8.0 реализована возможность обхода группировок в произвольном порядке. То есть из одного результата запроса возможно получать отчеты с различной последовательностью группировок. Например, в отчете на основе одного результата запроса могут выводиться сначала группировки по товарам, а затем по поставщикам.
Итоги по иерархии
Если группировочное поле является ссылкой на справочник, то для расчета итогов по группам справочника (или родительским элементам, если справочник состоит из одних элементов) необходимо указать ключевое слово ИЕРАРХИЯ. В этом случае в результат будут добавлены записи с итогами для уровней иерархии справочника.
Например, выберем записи справочника Номенклатура, рассчитаем объем продаж по каждой позиции и по группам справочника:
ВЫБРАТЬ Номенклатура, Сумма ИЗ РегистрНакопления.Продажи
ИТОГИ СУММА (Сумма) ПО Номенклатура ИЕРАРХИЯ АВТОУПОРЯДОЧИВАНИЕ
Заметьте, что в результат запроса включены группы справочника, и по ним подсчитаны итоги:
Номенклатура |
Сумма |
Клавиатуры |
675 |
Клавиатура Apple Pro Keyboards |
600 |
Клавиатура Apple Pro Keyboards |
225 |
Клавиатура Apple Pro Keyboards |
375 |
Клавиатура Keyboard PS/2 |
75 |
Клавиатура Keyboard PS/2 |
25 |
Клавиатура Keyboard PS/2 |
50 |
Мониторы |
1460 |
Монитор 15' LG Studioworks 575N |
620 |
Монитор 15' LG Studioworks 575N |
465 |
Монитор 15' LG Studioworks 575N |
155 |
Монитор 17' Philips 107S20 |
840 |
Монитор 17' Philips 107S20 |
840 |
Несколько итогов в запросе
В языке запросов допускается совместное использование различных итогов в одном запросе, например, общих, иерархических и итогов по группировкам.
Ниже представлен запрос, который выбирает данные из расходных накладных и дополнительно подсчитывает общие итоги, итоги по контрагентам, по каждому товару и группе товаров.
ВЫБРАТЬ
НаклСостав.Ссылка.Контрагент КАК Контрагент, НаклСостав.Номенклатура КАК Номенклатура,
НаклСостав.Ссылка.Номер,
НаклСостав.Сумма КАК Продажи ИЗ Документ.РасходнаяНакладная.Состав КАК НаклСостав ИТОГИ СУММА(Продажи) ПО ОБЩИЕ,
Контрагент,
Номенклатура ИЕРАРХИЯ
Контрагент |
Номенклатура |
Номер |
Продажи |
|
|
|
4520 |
Автохозяйство |
|
|
1 280 |
Автохозяйство |
Клавиатуры |
|
20 |
Автохозяйство |
Клавиатура LK-601 |
|
20 |
Автохозяйство |
Клавиатура LK-601 |
00023 |
20 |
Автохозяйство |
Мониторы |
|
1260 |
Автохозяйство |
Монитор 17' Philips |
|
210 |
Автохозяйство |
Монитор 17' Philips |
00023 |
210 |
Автохозяйство |
Монитор 19' Hitachi |
|
1 050 |
Автохозяйство |
Монитор 19' Hitachi |
00023 |
1 050 |
Алекс-2002 |
|
|
3240 |
Алекс-2002 |
Клавиатуры |
|
3240 |
Алекс-2002 |
Клавиатура Apple Pro |
|
3225 |
Алекс-2002 |
Клавиатура Apple Pro |
00012 |
3000 |
Алекс-2002 |
Клавиатура Apple Pro |
00013 |
225 |
Алекс-2002 |
Клавиатура PS/2 |
|
15 |
Алекс-2002 |
Клавиатура PS/2 |
00008 |
15 |
Предложение ОБЪЕДИНИТЬ / UNION
В языке запросов имеется возможность объединять результаты несколько запросов, при этом записи, полученные с помощью каждого из объединяемых запросов, будут собраны в один результат запроса. При объединении каждый запрос собирает данные независимо, а такие операции, как упорядочивание результатов и расчет итогов, выполняются уже над результатом объединения запросов.
Поля результата запроса будут называться так, как описано в списке полей выборки первого из объединяемых запросов. Поля выборки остальных запросов сопоставляются с полями результата в соответствии с порядком их следования в списке полей выборки.
Объединяемые запросы должны иметь одинаковое количество полей в списке полей выборки. Если поля выборки объединяемых запросов имеют разный тип, то поля результата запроса будут иметь составной тип данных.
Пример, выберем проданные или купленные товары за определенный период:
ВЫБРАТЬ
НаклСостав.Номенклатура,
НаклСостав.Цена КАК Цена
ИЗ Документ.РасходнаяНакладная.Состав КАК НаклСостав ГДЕ НаклСостав.Ссылка.Дата МЕЖДУ &НачДата И &КонДата
ОБЪЕДИНИТЬ
ВЫБРАТЬ
НаклСостав.Номенклатура,
НаклСостав.Цена
ИЗ Документ.ПриходнаяНакладная.Состав КАК НаклСостав ГДЕ НаклСостав.Ссылка.Дата МЕЖДУ &НачДата И ЬКонДата
Дата |
Номенклатура |
Цена |
10.01.2002 |
Клавиатура Apple Pro Keyboards |
14 |
11.01.2002 |
Монитор 17" Philips 107S20 |
540 |
12.01.2002 |
Клавиатура Keyboard PS/2 |
12 |
Разработка в системе 1 С: Предприятие 8.0
Обратите внимание, что по умолчанию при объединении запросов полностью одинаковые строки, сформированные разными запросами, заменяются одной. Если требуется, чтобы были оставлены все одинаковые строки, необходимо указать ключевое слово ВСЕ.
Например, выберем проданные или купленные нами товары с указанием даты, цены покупки или цены продажи. Даже если для какого-то товара в определенный день совпадет цена покупки и цена продажи, то в запросе это все-таки будут две разные строки:
ВЫБРАТЬ
НаклСостав.Ссылка.Дата,
НаклСостав.Номенклатура,
НаклСостав.Цена КАК Цена
ИЗ Документ.РасходнаяНакладная.Состав КАК НаклСостав
ГДЕ НаклСостав.Ссылка.Дата МЕЖДУ ЬНачДата И &КонДата
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
НаклСостав.Ссылка.Дата,
НаклСостав.Номенклатура,
НаклСостав.Цена
ИЗ Документ. ПриходнаяНакладная.Состав КАК НаклСостав
ГДЕ НаклСостав.Ссылка.Дата МЕЖДУ ШачДата И ЬКонДата
Дата |
Номенклатура |
Цена |
10.01.2002 |
Клавиатура Apple Pro Keyboards |
14 |
10.01.2002 |
Клавиатура Apple Pro Keyboards |
14 |
11.01.2002 |
Монитор 17" Philips 107S20 |
540 |
12.01.2002 |
Клавиатура Keyboard PS/2 |
12 |
Встроенные функции языка запросов
В языке запросов есть встроенные функции, которые могут быть использованы в списке полей выборки предложения ВЫБРАТЬ и в условии отбора предложения ГДЕ.
Если параметр функции является значением NULL, то возвращается тоже NULL. Для функций работы с датой следует учитывать, что тип «дата» включает в себя дату и время с точностью до секунды.
В языке запросов существуют следующие функции:
ПОДСТРОКА (<Строка>, <Позиция>, <ЧислоСимволов>)
Данная функция предназначена для выделения подстроки из строки.
ГОД (<дата>)
Выделяет год из даты. Возвращает число от 1 до 9999.
МЕСЯЦ (<дата>)
Выделяет месяц из даты (от 1 до 12).
ДЕНЬ (<дата>)
Выделяет число из даты (от 1 до 31).
ЧАС (<дата>)
Выделяет часы из даты (от 0 до 23). ' ,
г . ,' .
МИНУТА (<дата>)
Выделяет минуты из даты (0 до 59).
СЕКУНДА (<дата>)
Выделяет секунды из даты (0 до 59).
КВАРТАЛ (<дата>)
Определяет номер квартала по дате (от 1 до 4).
НЕДЕЛЯ (<дата>)
Определяет номер недели в году по дате (от 1 до 53).
ДеньГода (<дата>)
Определяет номер дня в году по дате (от 1 до 366).
ДеньНедели (<дата>)
Определяет номер дня недели по дате (от 1 до 7).
НачалоПериода ( <дата>, <ТипПериода> )
Возвращает начало периода по заданной дате. В качестве параметра ТипПериода передается Год, Месяц, Неделя, День, Час и т.д.
КонецПериода (<дата>,<ТипПериода>)
Возвращает конец периода по заданной дате.
Например, следующий запрос разбирает дату приема сотрудника на составляющие без учета времени и выводит первые 2 буквы от его ФИО, используя функцию ПОДСТРОКА:
ВЫБРАТЬ Наименование, ДатаПриема
ПОДСТРОКА(Наименование,1,2) КАК Сокращение, ДЕНЫДатаПриема) КАК Число, МЕСЯЦ(ДатаПриема) КАК Месяц,
ГОД(ДатаПриема) КАК Год ИЗ Справочник.Сотрудники
Наименова
ние |
ДатаПриема |
Сокра
щение |
Чис
ло |
Месяц |
Год |
Иванов Иван Иванович |
25.12.2003 |
Ив |
25 |
12 |
2003 |
Петров Петр Петрович |
05.07.2000 |
Пе |
5 |
7 |
2000 |
Сидоров Иван Николаевич |
15.12.1995 |
Си |
15 |
12 |
1995 |
Операции выбора в языке запросов (ВЫБОР / CASE)
В выражениях языка запросов могут применяться операции выбора, которые позволяют получить одно из возможных значений в соответствии с указанными условиями.
Следующий запрос использует операцию выбора для заполнения поля Диапазон:
ВЫБРАТЬ
Наименование,
ЗакупочнаяЦена КАК Цена,
ВЫБОР
Когда ЭтоГруппа = Истина Тогда "Это группа"
Когда ЗакупочнаяЦена >= 1000 Тогда "1000 и выше"
Когда ЗакупочнаяЦена >= 100 Тогда "100 - 1000"
Когда ЗакупочнаяЦена >= 10 Тогда "10 - 100"
Когда ЗакупочнаяЦена > 0 Тогда "О - 10"
Иначе "Не задана"
КОНЕЦ КАК Диапазон
ИЗ Справочник.Номенклатура
Наименование |
Цена |
Диапазон |
Брюки детские |
100 |
100 - 1000 |
Рубашка «Ковбойка» |
1050 |
1000 и выше |
Наименование |
Цена |
Диапазон |
Одежда |
|
Это группа |
Джинсы женские |
1100 |
1000 и выше |
Свитер детский |
0 |
Не задана |
Сантехника |
|
Это группа |
Бытовая техника |
|
Это группа |
Раковина «Лилия» |
0 |
Не задана |
Мойдодыр «Аквариум» |
0 |
Не задана |
Смеситель «Ультра» |
750 |
100 - 1000 |
Приведение типов в языке запросов
Поля исходных таблиц могут иметь составной тип данных. Для таких полей может возникнуть необходимость привести значения поля к какому-либо определенному типу. В языке запросов предусмотрена конструкция ВЫРАЗИТЬ, которая выполняет приведение типа. Ею можно пользоваться в списке полей выборки (предложение ВЫБРАТЬ) и в условии отбора (предложение ГДЕ).
Синтаксическая диаграмма конструкции ВЫРАЗИТЬ такова:
ВЫРАЗИТЬ (<Выражение> КАК <Тип значения>)
Выражение приводится к одному из примитивных типов или к ссылочному типу данных.
Если выражение является составного типа данных и требуемый тип данных входит в список допустимых, то приведение типа считается осуществимым, и для каждого значения указанного типа результатом будет это самое значение. Для значений других типов результатом приведения типа будет значение NULL.
Если выражение не содержит в составном типе требуемый тип значения, то выполнение данного запроса завершится ошибкой из-за принципиальной невозможности совершить приведение типов.
Разработка в системе 1 С: Предприятие 8.0
Литералы и параметры в языке запросов
В выражениях языка запросов могут напрямую указываться значения типа «булево», «число», «строка» или «дата». Также могут использоваться значения параметров запроса.
В следующей таблице приведены все возможные типы литералов и примеры их значений:
Тип литерала |
Примеры значений |
Булево |
ИСТИНА; ЛОЖЬ (других значений не существует) |
Строка |
«Иванов»; «Петров» |
Число |
15; 15.2; -10.20 |
Дата |
ДАТАВРЕМЯ(2003,12,23,16,56,00)
ДАТАВРЕМЯ(2003,12,23) |
Обратите внимание, что значения типа «дата» задаются с помощью ключевого слова ДАТАВРЕМЯ, после которого в скобках последовательно указываются год, месяц, день, час, минута и секунда.
В запрос также могут передаваться параметры. Эта возможность уже использовалась нами при рассмотрении предложения ГДЕ. Значения параметров могут использоваться в выражениях языка запросов, для этого необходимо указать символ «&» и после него имя параметра.
Например, выберем все приходные накладные за определенный период. Период будет задаваться параметрами НачДата и КонДата:
Запрос = Новый Запрос("ВЫБРАТЬ * ИЗ Документ.ПриходнаяНакладная ГДЕ Дата МЕЖДУ ШачДата и ЬКонДата");
Запрос.УстановитьПараметр("НачДата"
/ВыбЫачалоПериода); Запрос.УстановитьПараметр("КонДата",ВыбКонецПериода);
Результат = Запрос.Выполнить() ;
В качестве параметра может быть передано любое значение, например, значение одного из примитивных типов (число, строка, дата, булево), ДокументСсылка, СправочникСсылка, список значений и т.д.
Группы справочника и список значений часто применяются с ключевым словом В. Если передается группа справочника (или родительский элемент для справочников из одних элементов), то можно применить конструкцию В ИЕРАРХИИ:
Например, покажем цены на товары из указанного списка:
//1-й пример: отбор по списку товаров Запрос = Новый Запрос("
!ВЫБРАТЬ * ИЗ Справочник.Номенклатура | ГДЕ Ссылка В &СписокТоваров");
Запрос.УстановитьПараметр("СписокТоваров",СписокВыбранныхТоваров);
//2-й пример: отбор по группе товаров Запрос = Новый Запрос("
I ВЫБРАТЬ * ИЗ Справочник.Номенклатура 1 ГДЕ Ссылка В ИЕРАРХИИ ЬГруппаТоваров") ;
Запрос.УстановитьПараметр("ГруппаТоваров",ВыбГруппа);
Предложение ДЛЯ ИЗМЕНЕНИЯ
Данное ключевое слово позволяет заблокировать определенные данные от изменения другими сеансами работы с информационной базой 1C:Предприятия 8.0. Это необходимо, чтобы в процессе обработки результата запроса была уверенность в актуальности сведений, полученных из запроса. Такая возможность абсолютно необходима при проведении документов, для которых движения документа зависят от данных, содержащихся в регистре на момент проведения документа.
Стоит заметить, что если данные были считаны в транзакции, то они и так не могут быть изменены другими пользователями. Предложение же ДЛЯ ИЗМЕНЕНИЯ позволяет выполнить принудительную блокировку данных, чтобы потом не возникало взаимной блокировки при попытке записи.
Допустим, расходная накладная списывает материалы по средней себестоимости. Сумма списания зависит от текущих данных в регистре учетНоменклатуры, поэтому при оперативном проведе-
нии расходной накладной нужно заблокировать данные от изменения другими процессами. После завершения проведения документа заблокированные данные будут разблокированы.
Следующий пример демонстрирует применение запроса с ключевым словом ДЛЯ ИЗМЕНЕНИЯ:
ВЫБРАТЬ
Док.Номенклатура, Док.Номенклатура.Услуга КАК Услуга, Док.Номенклатура.ЗакупочнаяЦена КАК ЗакупочнаяЦена,
Док.Количество, Док.Сумма,
ОстаткиСкл.КоличествоОстаток КАК КоличествоСкл,
Остатки.КоличествоОстаток, Остатки.СуммаОстаток ИЗ
Документ.РасходнаяНакладная.Состав КАК Док ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
РегистрНакопления.УчетНоменклатуры.Остатки(,
Номенклатура В (ЬПарНоменклатура) И Склад = ЬПарСклад) КАК ОстаткиСкл ПО
Док.Номенклатура = ОстаткиСкл.Номенклатура ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
РегистрНакопления.СтоимостнойУчетНоменклатуры.Остатки(ЬМомент, Номенклатура В (ЬПарНоменклатура)) КАК Остатки ПО Док.Номенклатура = Остатки.Номенклатура ГДЕ Док.Ссылка = йСсылка
ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.УчетНоменклатуры.Остатки
Необходимо понимать, что в транзакции любые данные защищены от изменения другими пользователями. Опция же ДЛЯ ИЗМЕНЕНИЯ нужна для блокировки от транзакционного чтения. Ее используют, чтобы как можно раньше сказать системе, что данная таблица должна быть заблокирована от чтения.
При работе в клиент-серверном варианте блокировка накладывается только на записи, которые задействованы в запросе. Использование данного ключевого слова позволяет в момент обращения к запросу поставить одного из двух конкурирующих пользователей в состояние ожидания, пока другой проведет свой документ.
Проще говоря, если не использовать данное ключевое слово, то два пользователя прочитают, что товар есть на складе, и как минимум один из них не сможет провести документ. А если применить ДЛЯ ИЗМЕНЕНИЯ, то в момент чтения данных (выполнения запроса) тот, кто позже начал, будет ждать, пока данные освободятся. Поэтому запрос с этим ключевым словом обычно ставят как можно раньше в процедуре проведения документа, чтобы уменьшить количество бесполезных действий.
Обработка результата запроса
Напомним общую схему выполнения запроса:
1. Создание объекта Запрос и передача ему текста запроса.
2. Установка параметров запроса с помощью метода УСТЭНОВИТЬ-Параметр.
3. Выполнение запроса, получение результата запроса.
4. Получение выборки из результата запроса или выгрузка результата запроса в таблицу значений / дерево значений. Также есть возможность использовать результат запроса в качестве источника данных для сводной таблицы.
5. Обход выборки из результата запроса или обработка таблицы значений/дерева значений.
Ниже приведен пример выполнения простого запроса и получения выборки из результата запроса:
Запрос = Новый Запрос;
ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Сотрудники";
Запрос.Текст = ТекстЗапроса;
РезультатЗапроса = Запрос.Выполнить();
ВыборкаИзРезультатаЗапроса = РезультатЗапроса.Выбрать();
Тот же самый фрагмент можно записать короче. В приведенном ниже примере используется конструктор объекта Запрос с параметром, через который передается текст запроса. Далее запрос выполняется, и сразу же производится выборка из результата запроса:
Запрос = Новый Запрос("ВЫБРАТЬ * ИЗ Справочник.Сотрудники"); ВыборкаИзРезультатаЗапроса = Запрос.Выполнить().Выбрать();
Перед получением выборки можно проверить результат запроса на наличие хотя бы одной записи. Для этого предназначен метод Пустой:
Запрос = Новый Запрос(”ВЫБРАТЬ * ИЗ Справочник.Сотрудники”);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
ВыборкаИзРезультатаЗапроса = Результат. Выбрать();
КонецЕсли;
В некоторых случаях до получения выборки необходимо определить, какие сведения содержатся в результате. Для решения этой задачи у объекта РезультатЗапроса есть свойство Колонки, через
которое можно обратиться к коллекции колонок результата запроса.
Например, выведем имена всех колонок результата запроса с указанием их типа и ширины:
Запрос = Новый Запрос(”ВЫБРАТЬ * ИЗ Справочник.Сотрудники”);
Результат = Запрос.Выполнить();
Для каждого Колонка ИЗ Результат.Колонки Цикл Сообщить(”Колонка: ” + Колонка.Имя +
” типа ” + Колонка.Тип +
” имеет ширину ” + Колонка.Ширина);
КонецЦикла;
Выборка из результата запроса
Выборка из результата запроса предназначена для обхода его записей. Можно представить себе выборку как некоторый объект, который содержит указатель на текущую запись в результате запроса и предоставляет программе доступ ко всем полям текущей записи. Обход выборки может быть линейный, иерархический или по группировкам.
Возьмем результат простого запроса и продемонстрируем на его примере все варианты обхода выборки:
Результат запроса показан в следующей таблице:
ВЫБРАТЬ Номенклатура, Количество ИЗ Документ.РасходнаяНакладная.Состав УПОРЯДОЧИТЬ ПО Номенклатура
ИТОГИ СУММА(Количество) ПО Номенклатура, Номенклатура Иерархия |
№ |
Номенклатура |
Количество |
1 |
Сантехника |
104 |
2 |
Кран |
84 |
3 |
Кран |
10 |
4 |
Кран |
8 |
5 |
Кран |
44 |
6 |
Кран |
22 |
7 |
Смеситель |
20 |
|
266
№ |
Номенклатура |
Количество |
8 |
Смеситель |
5 |
9 |
Смеситель |
1 |
10 |
Смеситель |
14 |
11 |
Мебель |
134 |
12 |
Стол |
26 |
13 |
Стол |
1 |
14 |
Стол |
15 |
15 |
Стол |
10 |
16 |
Стул |
108 |
17 |
Стул |
55 |
18 |
Стул |
5 |
19 |
Стул |
32 |
20 |
Стул |
16 |
В этой таблице добавлен столбец №1, которого нет в результате запроса, но который будет использоваться нами в дальнейшем для идентификации записи в результате. Итоговые записи в таблице выделены курсивом, а итоговые записи для уровней иерархии справочника выделены жирным шрифтом.
Линейный обход
Первый и самый простой способ обхода — линейный. При линейном обходе выборка будет выдавать записи в той последовательности, в которой они располагаются в результате запроса. В нашем примере это будут записи с номерами 1, 2, 3, 4, 5 и так далее до записи с номером 20.
Для получения линейной выборки необходимо вызвать метод Выбрать объекта РезультатЗапроса без параметров, либо с параметром ОбходРезультатаЗапроса. Прямой.
СпособВыборки = ОбходРезультатаЗапроса.Прямой;
Выборка = РезультатЗапроса.Выбрать(СпособВыборки);
//или эквивалентная запись
Выборка = РезультатЗапроса.Выбрать();
Для навигации по записям запроса используются три метода:
Следующий
Позволяет перейти к следующей записи результата в соответствии с порядком обхода выборки. При первом вызове этот метод позиционирует выборку на первую запись. Когда будут выбраны все записи, данный метод просигнализирует об этом, вернув значение Ложь.
СледующийПоЗначениюПоля
Позволяет получить следующую запись со значением в заданном поле, отличающимся от значения в этом же поле текущей записи.
НайтиСледующий
Позволяет найти запись с заданными значениями некоторых полей.
Ниже приведен простейший пример обхода выборки с помощью метода Следующий:
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл .. <действия с записьк»
КонецЦикла;
Для получения данных текущей записи нужно обращаться к реквизитам объекта Выборка, имена которых совпадают с именами колонок результата запроса:
Запрос = Новый Запрос!”
I ВЫБРАТЬ Код, Наименование КАК ФИО I ИЗ Справочник.Сотрудники”);
Выборка = Запрос.Выполнить{).Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(”Код: ” + Выборка.Код);
Сообщить(”ФИО: ” + Выборка.ФИО);
КонецЦикла;
Метод СледующийПоЗначениюПоля позволяет сгруппировать записи результата по значениям полей, например:
ВЫБРАТЬ Док.Товар. Док.Получатель, Док.Количество ИЗ Документ.РасходнаяНакладная.Состав Док
УПОРЯДОЧИТЬ ПО Док.Товар.Наименование, Док.Получатель.Наименование
Допустим, в результате запроса мы получили следующие записи:
№ |
Товар |
Получатель |
Количество |
1 |
Смеситель |
Маг. «Гигант» |
14 |
2 |
Смеситель |
Маг. «Хозяйка» |
1 |
3 |
Смеситель |
Мосгорторг |
5 |
4 |
Кран |
Маг. «Гигант» |
44 |
5 |
Кран |
Маг. «Хозяйка» |
8 |
6 |
Кран |
Мосгорторг |
10 |
7 |
Кран |
Мосгорторг |
22 |
8 |
Стол |
Маг. «Гигант» |
10 |
9 |
Стол |
Маг. «Мебель» |
15 |
10 |
Стол |
Мосгорторг |
1 |
11 |
Стул |
Маг. «Гигант» |
32 |
12 |
Стул |
Маг. «Мебель» |
55 |
13 |
Стул |
Маг. «Хозяйка» |
5 |
14 |
Стул |
Мосгорторг |
16 |
Организуем линейную выборку из результата запроса и обойдем ее при помощи метода СледующийПоЗначениюПоля:
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.СледующийПоЗначениюПоля(’Получатель”) Цикл
КонецЦикла;
КоиецЦикла;
Следует обратить внимание на то, что во внутреннем цикле не была выбрана запись с номером 7, так как в ней такое же значение поля Получатель, как и в предыдущей записи.
Заметим, что если во вложенном цикле получать записи с помощью метода Следующий, то будут выбраны все записи со значением поля, заданным в последнем вызове метода СледующийПо-ЗначениюПоля:
Выборка = РезультатЗапроса.Выбрать() ;
Пока Выборка.Следующий() Цикп
КонецЦикла;
КонецЦикла;
Метод НайтиСледующий позволяет позиционироваться на запись с нужными значениями полей, при этом текущая запись не рассматривается. В качестве условия поиска можно указать структуру или значение с именем колонки. Если запись найдена, то возвращается Истина, если таких записей больше не найдено, возвращается Ложь.
Метод НайтиСледующий имеет два вариант вызова:
НайтиСледующий(<Структура поиска>)
НайтиСледующий(<Значение>,<Имя колонки>)
Этот метод используется в следующем примере:
Запрос = Новый Запрос("
[Выбрать Наименование,
! ГОД (ДатаПриема) КАК Год,
I МЕСЯЦ(ДатаПриема) КАК Месяц
|Из Справочник.Сотрудники");
Выборка = Запрос.Выполнить().Выбрать();
//1-й вариант применения: поиск по структуре //выберем всех сотрудников, принятых в июне 2 003 года СтруктураПоиска = Новый Структура!"Год,Месяц",2003,5);
Пока Выборка.НайтиСледующий(СтруктураПоиска) Цикл Сообщить("Сотрудник" + Выборка.Наименование);
КонецЦикла;
//2-й вариант: поиск значения по заданной колонке //выберем всех сотрудников, принятых в 2003 году Пока Выборка.НайтиСледующий(2003, "Год") Цикл
Сообщить("Сотрудник" + Выборка.Наименование);
КонецЦикла;
Иерархический обход
Рассмотрим другой способ обхода результата запроса — иерархический. При данном варианте обходятся только записи, находящиеся на одном уровне. Для получения иерархической выборки из результата необходимо вызвать метод Выбрать объекта Резуль-татЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппи-ровкамСИерархией:
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией; Выборка = РезультатЗапроса.Выбрать(СпособВыборки);
Выборка из результата запроса с иерархическим обходом в нашем примере обойдет только записи с номерами 1 и 11, так как только эти две записи находятся на самом верхнем уровне.
Проиллюстрируем это, представив наш результат в виде дерева, где узлами будут итоговые записи, а листьями дерева будут детальные записи. Вот что у нас получится:
Из этого рисунка видно, что именно записи с номерами 1 и 11 находятся на первом уровне дерева, и поэтому только они попадают в первый проход иерархической выборки.
Возникает вопрос, как получить остальные записи результата запроса. Для этого у объекта ВыборкаИзРезультатаЗапроса можно получить еще одну выборку, которая будет обходить подчиненные записи текущей записи выборки. В нашем примере в момент, когда объект Выборка будет позиционирован на запись с номером 1, мы запросим у него иерархическую выборку. Таким образом, мы получим выборку, которая вернет записи с номерами 2, 7. А когда Выборка будет спозиционирована на запись с номером 11, то полученная у нее иерархическая выборка вернет записи с номерами 12, 16. Так реализуется иерархический обход результатов запроса
Заметим, что у выборки можно получать вложенные выборки любого типа. Так, если бы мы запросили у Выборки, спозиционированной на записи 1, линейную выборку, то с ее помощью мы бы получили записи с номерами со 2-го по 10-й.
Проиллюстрируем описанную методику на примере:
Процедура ВыдатьРекурсивно(Выборка) Далее;
Процедура ВыполнитьЗапрос()
Запрос = Новый Запрос(”
ВЫБРАТЬ Товар, Количество ИЗ Документ.РасходнаяНакладная.Состав УПОРЯДОЧИТЬ ПО Товар
1ИТОГИ СУММА(Количество) ПО Товар, Товар ИЕРАРХИЯ”);
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировхамСИерархией; Выборка = Запрос.Выполнить().Выбрать(СпособВыборки);
ВыдатьРекурсивно (Выборка)
КонецПроцедуры
Процедура ВыдатьРекурсивно(Выборка)
Пока Выборка.Следующий() Цикл
//выведем в окно сообщений поля из результата Товар = Выборка.Наименование;
Количество = Выборка.Количество;
Сообщить(”Товар: ” + СокрЛП(Товар) +
"Количество: ” + СокрЛП(Количество));
//продолжим выборку подчиненных записей
СпособВыборки = ОбходРезультатаЗапроса. ПоГрушшровкамСИерархией; ВыдатьРекурсивно (Выборка.Выбрать (СпособВыборки) ) ;
КонецЦикла;
КонецПроцедуры
Обход по группировкам
Третий, и последний способ обхода результата — по группировкам. Он сходен с иерархическим обходом, но с одним различием: записи с иерархическими итогами при обходе в нем рассматриваются как детальные записи, а не как узловые. Для получения выборки по группировкам из результата запроса необходимо вызвать метод Выбрать объекта РезультатЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппировкам:
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкам;
Выборка = РезультатЗапроса.Выбрать(СпособВыборки);
Перебрав такую выборку для нашего примера, мы получим записи с номерами 1, 2, 7, 11, 12, 16, например:
Запрос = Новый Запрос(”
!ВЫБРАТЬ Товар, Количество 1 ИЗ Документ.РасходнаяНакладная.Состав [УПОРЯДОЧИТЬ ПО Товар
(ИТОГИ СУММА(Количество) ПО Товар, Товар ИЕРАРХИЯ”);
РезультатЗапроса = Запрос .Выполнить О;
СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкам;
Выборка = Результатаапроса.Выбрать(СпособВыборки);
Пока Выборка.Следующий() Цикл
//выведем в окно сообщений поля из результата
Сообщить(”Группа товаров: ” + СокрЛП(Выборка.Наименование) + "Количество: ” + СокрЛП(Выборка.Количество));
//выберем дочерние записи линейным способом ВыборкаДочерних = Выборка.Выбрать() ;
Пока ВыборкаДочерних.Следующий() Цикл
Сообщить!” Товар: ” + СокрЛП(Выборка.Наименование) +
” Количество: ” + СокрЛП(Выборка.Количество));
КонецЦикла;
КонецЦикла;
Другие полезные методы
При работе с выборкой из результата запроса будут полезны следующие методы:
Группировка
Возвращает в виде строки имя группировки текущей записи. Если группировки нет, возвращается пустая строка.
Количество
Возвращает количество записей в выборке.
Сбросить
Отменяет позиционирование. После вызова метода Следующий выборка позиционируется на первую запись.
Уровень
Возвращает уровень текущей записи в иерархии и группировках. Уровень считается от начальной выборки из результата запроса.
ТипЗаписи
Этот метод возвращает тип текущей записи запроса, который является одним из значений системного перечисления ТипЗаписиЗапроса: ДетальнаяЗапись, ИтогПоГруппиров-ке, ИтогПоИерархии, ОбщийИтог.
Выгрузка результата запроса
Результат запроса может быть выгружен в таблицу значений или дерево значений с помощью метода Выгрузить. Затем над ними могут быть произведены другие операции: сортировка, свертка, перебор строк и другие действия (см. главу «Коллекции значений»).
Следующий пример выгружает результат запроса в таблицу значений с прямым порядком обхода строк:
Результат = Запрос.Выполнить();
СпособОбхода = ОбходРезультатаЗапроса.Прямой;
ТабЗнач = Результат.Выгрузить(СпособОбхода);
Если используется иерархический обход результата запроса или обход по группировкам, тогда удобнее выгрузить не в таблицу значений, а в дерево значений, как делается в следующем примере:
Результат = Запрос.Выполнить();
СпособОбхода = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
Дерево = Результат.Выгрузить(СпособОбхода);
Результат запроса может быть представлен в виде сводной таблицы, для чего необходимо установить свойство ИсточникДанных объекта СводнаяТаблица. Подробнее про сводные таблицы рассказывается в главе «Отчеты».
Важные отличия от версии 7.7
• В 1 ^Предприятии 8.0 значительно переработан механизм запросов. Язык запросов стал похож на стандартный SQL, в некоторых аспектах даже превосходя его.
• Поддерживаются вложенные запросы.
• Поддерживается объединение нескольких запросов (UNION).
• Поддерживается соединение таблиц (JOIN), включая внутреннее (INNER), левое внешнее (LEFT OUTER) и правое внешнее (RIGHT OUTER) соединения.
• Есть возможность подсчета общих итогов и итогов по группировкам, для чего предназначено предложение ИТОГИ...ПО (TOTALS...BY).
• Параметры запроса нужно устанавливать явно с помощью метода УстановитьПараметр. При выполнении запроса не учитывается контекст модуля.
• Значительно изменился конструктор запросов. Теперь он может быть вызван и в режиме «Предприятие».
• Введено ключевое слово ИМЕЮЩИЕ (HAVING), предназначенное для фильтрации групп.
• Добавлено новое ключевое слово ПОДОБНО (LIKE) для проверки соответствия строки шаблону.
• Введены ключевые слова ПЕРВЫЕ (ТОР) и РАЗЛИЧНЫЕ (DISCTINCT).
• Есть возможность автоупорядочивания результата запроса.
• Добавлено ключевое слово ДЛЯ ИЗМЕНЕНИЯ, предназначенное для блокировки данных, используемых в запросе.
• Полям и источникам данных можно назначать псевдонимы с помощью ключевого слова КАК (AS).
• В результате запроса могут быть поля, являющиеся вложенными результатами запроса. Такие поля образуются при обращении к табличным частям объектов.
• Результат запроса может являться источником данных для сводной таблицы.
Разработка в системе 1С:Предприятие 8.0
Содержание раздела