Основные приемы работы
Основные приемы работы с запросами во встроенном языке 1С:Предприятия удобнее всего рассматривать на примерах. Приведем типичный пример использования запроса:
Запрос = Новый Запрос ( «ВЫБРАТЬ Товар.Наименование Наименование, |Товар.Родитель.Наименование НаименованиеРодителя |ИЗ Справочник.Товары Товар» ); // Выполним запрос и запишем результат в переменную РезультатЗапроса. // Получим выборку из результата запроса. // Пока в выборке есть записи . |
Как видно из этого примера, работа с запросом ведется при помощи трех основных объектов:
- Запрос – объект, выполняющий сам запрос. Представлен в примере переменной с именем Запрос.
- РезультатЗапроса – объект, содержащий полученные при выполнении запроса данные. Представлен в примере переменной с именем РезультатЗапроса.
- ВыборкаИзРезультатаЗапроса – объект, позволяющий обходить (т.е. перебрать) записи из результата. Представлен в примере переменной с именем Выборка.
Рассмотрим подробнее объект ВыборкаИзРезультатаЗапроса. Для этого нам понадобится следующий текст запроса:
ВЫБРАТЬ
Товар, Количество
ИЗ
Документ.РасхНакл.Состав
УПОРЯДОЧИТЬ ПО Товар
ИТОГИ Сумма(Количество) ПО Товар Иерархия
Его результат представлен в таблице:
N
Товар
Количество
1
Сантехника
104
11
Мебель
134
В эту таблицу добавлена колонка «N», которой нет в результате запроса, но которая будет использоваться нами в дальнейшем для идентификации записи в результате. Итоговые записи в таблице выделены курсивом, итоговые записи для иерархических уровней справочника выделены жирным шрифтом.
Способы обхода результата запроса
Линейный обход результата
Первый, и самый простой способ обхода – линейный. При линейном обходе выборка будет выдавать записи в той последовательности, в которой они располагаются в результате запроса. В нашем примере это будут записи с номерами 1, 2, 3, 4, 5 и так далее до записи с номером 20.
Для получения линейной выборки из результата необходимо вызвать метод Выбрать объекта РезультатЗапроса без параметров, либо с параметром ОбходРезультатаЗапроса.Прямой.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . Прямой ; Выборка1 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; // что равнозначно записи Выборка1 = РезультатЗапроса . Выбрать ( ) ; |
Иерархический обход результата
Следующий способ обхода результата – иерархический. При данном обходе обходятся только записи, находящиеся на одном уровне. Для получения иерархической выборки из результата необходимо вызвать метод Выбрать() объекта РезультатЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппировкамСИерархией.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . ПоГруппировкамСИерархией ; Выборка2 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; |
Выборка из результата с иерархическим обходом в нашем примере обойдет только записи с номерами 1 и 11, так как только эти две записи находятся на самом верхнем уровне. Проиллюстрируем это, представив наш результат в виде дерева, где узлами будут итоговые записи, а листьями дерева будут детальные записи. Вот что у нас получится:
Из этого рисунка видно, что именно записи с номерами 1 и 11, и только они находятся на первом уровне дерева, в результате чего только они и попадают в первый проход иерархической выборки.
Возникает вопрос, как получать остальные записи результата запроса. Для этого у объекта ВыборкаИзРезультатаЗапроса можно получить еще одну выборку, которая будет обходить подчиненные записи текущей записи выборки. В нашем примере в момент, когда объект Выборка2 будет позиционирован на запись с номером 1, мы запросим у него иерархическую выборку. Таким образом, мы получим выборку, которая нам вернет записи с номерами 2, 7. А когда Выборка2 будет спозиционирована на записи с номером 11, то полученная у нее иерархическая выборка вернет записи с номерами 12, 16. Так реализуется иерархический обход результатов запроса. Заметим, что у выборки можно получать вложенные выборки любого типа. Так, если бы мы запросили у Выборки2, спозиционированной на записи 1, линейную выборку, то с ее помощью мы бы получили записи с номерами записей со 2-го по 10-й. Проиллюстрируем описанную методику на примере.
Пример:
Процедура ВыполнитьЗапрос ( ) // Создадим запрос. Запрос = Новый Запрос ; // Установим текст запроса // Выполним запрос и запишем результат в переменную // Получим выборку из результата запроса. Процедура ВыдатьРекурсивно ( Выборка ) // Продолжим выборку подчиненных записей КонецЦикла ; |
Обход результата по группам
Третий, и последний способ обхода результата – по группам. Он сходен с иерархическим обходом, но с одним различием: записи с иерархическими итогами при обходе в нем рассматриваются как детальные записи, а не как узловые. Для получения выборки по группам из результата запроса необходимо вызвать метод Выбрать объекта РезультатЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппировкам.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . ПоГруппировкам ; Выборка2 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; |
Перебрав в ней всё, мы получим записи с номерами 1, 2, 7, 11, 12, 16.
Пример:
Процедура ВыполнитьЗапрос ( ) // Создадим запрос. Запрос = Новый Запрос ; // Установим текст запроса // Выполним запрос и запишем результат в переменную // Получим выборку из результата запроса // Пока в выборке есть записи . ВыдатьДочерниеЗаписи ( Выборка . Выбрать ( ) ) ; Процедура ВыдатьДочерниеЗаписи ( Выборка ) |
Работа с выборкой
Объект ВыборкаИзРезультатаЗапроса предназначен для обхода записей результата запроса. Можно представить себе выборку как некоторый объект, который содержит указатель на текущую запись в результате и предоставляет программе доступ ко всем полям текущей записи. Для навигации по записям запроса используются три метода:
- Следующий() – перейти к следующей записи результата в соответствии с порядком обхода выборки. При первом вызове позиционирует выборку на первую запись. Когда будут выбраны все записи, данный метод просигнализирует об этом, вернув значение Ложь.
- СледующийПоЗначениюПоля() – получить следующую запись со значением в заданном поле, отличающимся от значения в этом поле текущей записи.
- НайтиСледующий () – найти запись, с заданными значениями некоторых полей.
Использование метода СледующийПоЗначениюПоля
Метод позволяет сгруппировать записи результата по значениям полей.
Пример запроса:
ВЫБРАТЬ
Док.Товар, Док.Получатель, Док.Количество
ИЗ
Документ.РасхНакл.Состав Док
УПОРЯДОЧИТЬ ПО Док.Товар.Наименование, Док.Получатель.Наименование
Источник
Выборка из результата запроса всех вошедших в него значений группировок
При обходе результата запроса нередко возникает необходимость получения всех значений группировок внутри какой-либо другой группировки. Такая возможность может понадобиться, например, при выводе кросс отчета. Для обеспечения такой возможности в объекте ВыборкаИзРезультатаЗапроса предусмотрен третий параметр функции Выбрать().
Рассмотрим пример. Пусть нам необходимо получить кросс-отчет по остаткам номенклатуры на различных складах. Номенклатуру необходимо вывести в строках, склады — в колонках. Запрос для получения остатков будет выглядеть так:
ВЫБРАТЬ
УчетНоменклатурыОстатки.Номенклатура КАК Номенклатура,
УчетНоменклатурыОстатки.Номенклатура.Представление,
УчетНоменклатурыОстатки.Склад КАК Склад,
УчетНоменклатурыОстатки.Склад.Представление,
УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
РегистрНакопления.УчетНоменклатуры.Остатки КАК УчетНоменклатурыОстатки
ИТОГИ СУММА(КоличествоОстаток) ПО
ОБЩИЕ,
Номенклатура,
Склад
Для обхода номенклатуры воспользуемся выборкой из результата запроса:
ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Номенклатура»);
Пока ВыборкаНоменклатура.Следующий() Цикл
ОбластьНоменклатура.Параметры.Заполнить(ВыборкаНоменклатура);
ТабДок.Вывести(ОбластьНоменклатура);
Для обхода внутри номенклатуры всех складов, присутствующих в результате запроса, получим вложенную выборку от выборки номенклатуры, с указанием третьего параметра «ВСЕ»:
ВыборкаСклад = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Склад», «ВСЕ»);
Пока ВыборкаСклад.Следующий() Цикл
ОбластьСклад.Параметры.Заполнить(ВыборкаСклад);
ТабДок.Присоединить(ОбластьСклад);
КонецЦикла;
В случае если необходимо построить несколько отдельных кросс-таблиц для каждого значения некой группировки, необходимо в качестве третьего параметра выборки указать имя группировки, внутри которой необходимо получить все значения, вошедшие в запрос. Пример:
ВыборкаСклад = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Склад», «Организация»);
В данном примере будут получены все значения складов, присутствующие в ранее выбранной организации.
Пример вывода кросс-отчета с использованием выборок из результата запроса показан в демонстрационной конфигурации «Примеры ИТС», в отчете «ОстаткиНаСкладах».
Источник
Запрос с ТЧ. Как обойти результат такого запроса?
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
|ЗаказПокупателя.Ссылка КАК Документ,
|ЗаказПокупателя.Номер,
|ЗаказПокупателя.Дата КАК Дата,
|ЗаказПокупателя.Проведен,
|ЗаказПокупателя.АдресДоставки,
|ЗаказПокупателя.ВидОперации.Ссылка КАК ВидОперации,
|ЗаказПокупателя.ДатаОплаты,
|ЗаказПокупателя.Контрагент.Ссылка КАК Контрагент,
|КонтактнаяИнформация.Представление КАК Телефон,
|ЗаказПокупателя.Организация.Ссылка КАК Организация,
|ЗаказПокупателя.СкладГруппа.Ссылка КАК Склад,
|ЗаказПокупателя.Грузоотправитель,
|ЗаказПокупателя.Доставка,
|ЗаказПокупателя.Оплата,
|ЗаказПокупателя.ВидыОплат.Ссылка КАК ВидОплаты,
|ЗаказПокупателя.Товары.(
| Номенклатура.Наименование,
| ХарактеристикаНоменклатуры.Ссылка,
| Количество,
| Цена,
| Сумма
| )
|
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя КАК ЗаказПокупателя
| ПО (ЗаказПокупателя.Контрагент.Ссылка = КонтактнаяИнформация.Объект.Ссылка)
|ГДЕ
| ЗаказПокупателя.Проведен
| И ЗаказПокупателя.ВидОперации = &ВидОперации
| И ЗаказПокупателя.Доставка = Истина
| И ЗаказПокупателя.Грузоотправитель = &Грузоотправитель
| И ЗаказПокупателя.СкладГруппа.Ссылка = &СкладГруппа
| И КонтактнаяИнформация.Тип = &Тип
|
|УПОРЯДОЧИТЬ ПО
|Дата»;
то, что выделено зелёным это вложенная таблица ТЧ документа, но есди сделать обход результата запроса
Пока Выборка.Следующий() Цикл
.
КонецЦикла;
то до этой ТЧ не добраться.
Как обойти в цикле эту ТЧ вместе с остальным результатом запроса?
Источник
Работа с запросами во встроенном языке 1С 8.3
Схема выполнения запроса
Для работы с запросами во встроенном языке 1С есть следующие объекты:
- Запрос
- РезультатЗапроса
- ВыборкаИзРезультатаЗапроса
Общая схема выполнения запроса выглядит следующим образом:
- Создается объект Запрос, через свойство Текст устанавливается текст запроса.
- Если в запросе есть параметры, то методом УстановитьПараметр заполняются значения параметров запроса.
- С помощью метода Выполнить получается объект РезультатЗапроса.
- Из результата запроса методом Выбрать получается объект ВыборкаИзРезультатаЗапроса. Также результат запроса можно выгрузить в таблицу значений или в дерево значений с помощью метода Выгрузить.
- На последнем шаге выполняется обработка выборки, таблицы значений или дерева значений.
Непосредственное получение данных из базы выполняется в момент вызова метода Выполнить у объекта Запрос. Для того, чтобы спозиционироваться на первой записи выборки результата запроса нужно вызвать метод Следующий. Если в выборке еще остались записи, то данный метод вернет Истина, в противном случае Ложь. На каждой итерации цикла будет получена очередная запись результата запроса.
Параметры запроса
Для того чтобы передать значения параметров в запрос используется метод УстановитьПараметр. При этом если задать значение параметра, которого нет в тексте запроса, то запрос все равно выполнится. А если не задать значение какого-либо параметра, то будет выброшено исключение «Не задано значение параметра Имя параметра».
После заполнения значений параметров они будут доступны через свойство Параметры объекта Запрос:
Источник