Смекни!
smekni.com

Запросы. Терминология и обозначения (стр. 2 из 3)

запросе объединяются по "И", то есть запросы

Условие(ВыходнойДень(Дата) = 0);

Условие(Товар в ВыбранныйТовар);

и

Условие((ВыходнойДень(Дата) = 0) И (Товар в ВыбранныйТовар)

= 1));

будут выполняться одинаково.

Если условие не подходит под определение элементарного, то оно выполняется механизмом внутреннего языка системы 1С:Предприятие.

Если существует возможность разбить сложное условие на элементарные, то так и следует поступить. Допустим, что нам необходимо применить условие вида:

"//{{Запрос(ПреобразованиеУсловия_Было)

|//...

|Условие(Флаг = Перечисление.Булево.Да);

|//...

"//}}

;

, то для оптимизации времени исполнения запроса следует, объявить глобальную переменную:

Перем True;

а в конце модуля определить её как

True = Перечисление.Булево.Да;

и применить эту переменную для формирования элементарного условия:

"//{{Запрос(ПреобразованиеУсловия_Стало)

|//...

|Условие(Флаг = True);

|//...

"//}}

;

Следует обратить особое внимание на то, что оператор принадлежности (в/in), не поддерживается внутренним языком 1С:Предприятия, поэтому оператор принадлежности должен использоваться только в элементарных условиях вычисляемых самим Запросом. И поэтому следующий пример будет выдавать ошибки при выполнении запроса:

"//{{ЗАПРОС(ОшибкаОператораПринадлежности)

|//...

|Условие(Товар.Код в ВыбТовар.Код);

|//...

"//}}

;

Оператор Группировка

в 1С:Предприятии версии 7.5 обогатился следующими реквизитами Все и Все ВошедшиеВЗапрос . Эти реквизиты созданы для того, чтобы давать возможность создавать табличные отчёты, разворачиваемые по горизонтали и вертикали. Для иллюстрации вышесказанного, обратимся к классике - отчёту "Остатки товаров на складах".

Далее приведен текст процедуры программного модуля, реализующего формирование отчёта:

//*******************************************

// Процедура формирования отчета//

Процедура ПоСкладам()

Перем Запрос, ТекстЗапроса, Таблица;

//Создание объекта типа Запрос

Запрос = СоздатьОбъект("Запрос");

ТекстЗапроса =

"//{{ЗАПРОС(ПоСкладам)

|Скл = Регистр.ОстаткиТоваров.Склад;

|Товар = Регистр.ОстаткиТоваров.Товар;

|КолВо = Регистр.ОстаткиТоваров.ОстатокТовара;

|Группировка Товар Упорядочить По Товар.Код;

|Группировка Скл Упорядочить По Скл.Код Все;

|Функция КО = КонОст(КолВо);

|"//}}ЗАПРОС

;

// Если ошибка в запросе, то выход из процедуры

Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда

Возврат;

КонецЕсли;

// Подготовка к заполнению отчета данными запроса

Таблица=СоздатьОбъект("Таблица");

Таблица.ИсходнаяТаблица("ПоСкладам");

Таблица.ВывестиСекцию("Заголовок");

// Формирование шапки отчета

Таблица.ВывестиСекцию("Шапка|Боковик");

Счётчик = 0;

Пока Запрос.Группировка("Товар") = 1 Цикл

Пока Запрос.Группировка("Скл") = 1 Цикл

Таблица.ПрисоединитьСекцию("Шапка|Склад");

Счётчик = Счётчик + 1;

КонецЦикла;

Если Счётчик>0 Тогда

прервать;

КонецЕсли;

КонецЦикла;

Запрос.ВНачалоВыборки();

// Процесс формирования строки отчета

Пока Запрос.Группировка("Товар") = 1 Цикл

Если Запрос.ЭтоГруппа(1) = 1 Тогда

Таблица.ВывестиСекцию("Группа|Боковик");

Для i = 1 по Счётчик Цикл

КоличествоДляТаблицы = 0;

Таблица.ПрисоединитьСекцию("Группа|Склад");

КонецЦикла;

Иначе

Таблица.ВывестиСекцию("Товар|Боковик");

Пока Запрос.Группировка("Скл") = 1 Цикл

КоличествоДляТаблицы = Запрос.КО;

Таблица.ПрисоединитьСекцию("Товар|Склад");

КонецЦикла;

КонецЕсли;

КонецЦикла;

// Вывод заполненной формы отчета

Таблица.ТолькоПросмотр(1);

Таблица.Опции(0, 0, 5, 0);

Таблица.Показать("Остатки товаров на складах", "");

КонецПроцедуры

Выходная таблица отчёта имеет следующий вид:

Остатки товаров на складах

Следует упомянуть тот факт, что "Запрос" дает возможность доступа к переменным, группировкам и функциям по их именам. Значения упорядочивания хоть и находятся в выборке, но у их нет имени и следовательно, доступ к их значениям по имени невозможен. Для доступа к их значениям применяется метод ЗначениеУпорядочивания. Использование этого метода, может существенно ускорить время обхода выборки, по сравнению с использованием конструкций типа:

Запрос.ИмяГруппировки.ИмяПоля

из-за того, что значение ИмяПоля, система будет повторно выбирать из ИБ.

В 1С:Предприятии версии 7.7 появились новоые возможности по упорядочиванию группировок. Первая, это возможность упорядочивать значение группировки по функции. вторая, возможность новый реквизит предложения Группировка – без упорядочивания . Реквизит без упорядочивания удобен для пакетного режима выполнения запроса, когда не важно расположение элементов группировки, а необходимы только результаты. В этом случае сбор данных упорядочивания отключается полностью, в том числе и по умолчанию, что положительно сказывается на производительности.

Оператор Функция

В этом разделе хочется обратить внимание на то, что значения функций, объявленных в запросе, определены, накапливаются и сворачиваются по всем уровням группировок, начиная с самой старшей группировки - "Итого" и кончая самой младшей. Как иллюстрацию, приведем следующий пример:

Процедура ОстаткиТоваров()

Перем Запрос, ТекстЗапроса, Таб;

//Создание объекта типа Запрос

Запрос = СоздатьОбъект("Запрос");

ТекстЗапроса =

"//{{ЗАПРОС(ОстаткиТоваров)

|Период с ДатаС по ДатаПо;

|Товар = Регистр.ОстаткиТоваров.Товар;

|Склад = Регистр.ОстаткиТоваров.Склад;

|КолВо = Регистр.ОстаткиТоваров.ОстатокТовара;

|Группировка Товар упорядочить по

| Товар.Наименование;

|Группировка Склад упорядочить по

| Склад.Наименование;

|Функция Количество = КонОст(КолВо);

|"//}}ЗАПРОС

;

// Если ошибка в запросе, то выход из процедуры

Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда

Возврат;

КонецЕсли;

// Подготовка к заполнению выходных форм данными

Таб = СоздатьОбъект("Таблица");

Таб.ИсходнаяТаблица("ОстаткиТоваров");

// Заполнение полей "Заголовок"

Таб.ВывестиСекцию("Заголовок");

Состояние("Заполнение выходной таблицы...");

Пока Запрос.Группировка("Товар") = 1 Цикл

// Заполнение полей Товар

Таб.ВывестиСекцию("Товар");

Пока Запрос.Группировка("Склад") = 1 Цикл

// Заполнение полей Склад

Таб.ВывестиСекцию("Склад");

КонецЦикла;

КонецЦикла;

// Заполнение полей "Итого"

Таб.ВывестиСекцию("Итого");

// Вывод заполненной формы

Таб.Опции(1, 0, 1, 0);

Таб.Показать("ОстаткиТоваров", "");

КонецПроцедуры

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

Создание таблицы выборки

Формат хранения временных файлов

Запрос создает временные файлы для накопления и хранения выборки на компьютере, с которого этот запрос запустили. Формат хранения временных файлов .DBF - .CDX.

Структура записи таблицы выборки

Структура записи таблицы выборки следующая:

- Поля группировок . Поля группировок идут последовательно в порядке их объявления в тексте запроса, и этот порядок крайне важен. Поле группировки состоит из полей упорядочивания и поля значения. По полям упорядочивания и полям значения строятся индексы, и следует иметь в виду, что максимальная длина ключа .CDX .файла равна 240 байтам. Если вы заводите большое количество группировок или большое число полей упорядочивания – достичь этой величины не составляет труда. При превышении максимально допустимого значения механизм запросов пропорционально уменьшает длину строковых полей упорядочивания, входящих в ключ. Если же длина ключа превышает 240 байт, а возможность сократить её за счёт строковых полей отсутствует, то обработка запроса прекратится с ошибкой "Длина индекса превышает максимальную длину и не может быть уменьшена".

- Поля функций накопления . Это самые обыкновенные числовые поля с максимальной длиной. Эти поля не входят в индексы.

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

Накопление данных

После того, как мы узнали, что представляет собой запись таблицы выборки, мы наконец-то можем поговорить о том, как накапливаются данные, подчёркиваю, именно, накапливаются . Как говорилось выше, обход ИБ запросом зависит от определения путей переменных. Если переменная Товар в тексте запроса определена следующим образом:

Период с ДатаС по ДатаПо;

Товар = Документ.РасходнаяНал.Товар,

Документ.РасходнаяКредит.Товар;

Склад = Документ.РасходнаяНал.Склад,

Документ.РасходнаяКредит. Склад;

КолВо = Документ.РасходнаяНал.Количество,

Документ.РасходнаяКредит. Количество

Группировка Товар;

Группировка Склад;

Сумма = Функция Сумма(КолВо);

то запрос сначала обойдет все документы вида РасходнаяНал за указанный период, а затем - все документы вида РасходнаяКредит . И каждый раз запрос будет формировать запись, заполняя поля группировок, функций и внутренних переменных. После формирования записи, запрос будет добавлять её в таблицу выборки. Если полученного сочетания значений группировок нет, запрос добавляет запись в таблицу выборки: