Описание встроенного языка системы 1С Предприятие

       

Структура запросов и методика их использования


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

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

Работа с запросами предполагает следующий порядок:

  • при помощи функции СоздатьОбъект создается объект типа «Запрос» и ссылка на него присваивается какой-либо переменной. Далее обраще­ние к запросу производится посредством этой ссылки.
  • после создания переменной типа «Запрос» следует обращение к методу Выполнить, которому в качестве параметра передается текст запроса, написанный на специальном языке запросов (см. главу «Язык запро­сов»). Метод Выполнить анализирует текст запроса, выполняет в соот­ветствии с ним выборку данных и формирует временный выходной на­бор данных (выборку).
  • после этого организуется циклическая обработка сформированного вре­менного набора данных (выборки) с целью получения требуемого отчета.
  • В данном разделе мы рассмотрим структуру создаваемого запросом времен­ного набора данных и работу методов запросов по выборке информации из этого временного набора.

    Дальнейшее описание проведем на простом примере: необходимо получить отчет о количестве товаров, хранящихся на складах. Текст процедуры, выпол­няющей эту операцию приведен ниже.

    Пример:

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

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

    "//{{ЗАПРОС(Сформировать)

    |СКЛАД = Регистр.ТоварныйЗапас.Склад;

    |ТОВАР = Регистр.ТоварныйЗапас.Товар;



    |КОЛИЧЕСТВО = Регистр.ТоварныйЗапас.Количество;

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

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




    |Функция КОЛ = КонОст(КОЛИЧЕСТВО);

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

    ;

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

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

       Возврат;

    КонецЕсли;

    Структура временного набора данных, созданная запросом "НашЗапрос" после его выполнения, представлена на следующем рисунке:

    Товар

    Склад

    Кол.

    Итог общий

    X

    X

    62

    Итог по товару Стол

    Стол

    X

    35

    Строка по товару Стол на складе Первый

    Стол

    Первый

    10

    Строка по товару Стол на складе Второй

    Стол

    Второй

    20

    Строка по товару Стол на складе Третий

    Стол

    Третий

    5

    Итог по товару Стул

    Стул

    X

    9

    Строка по товару Стул на складе Второй

    Стул

    Второй

    7

    Строка по товару Стул на складе Третий

    Стул

    Третий

    2

    Итог по товару Шкаф

    Шкаф

    X

    18

    Строка по товару Шкаф на складе Первый

    Шкаф

    Первый

    8

    Строка по товару Шкаф на складе Третий

    Шкаф

    Третий

    10

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

    Далее, допустим, в цикле мы проходим только по самой внешней группи­ровке запроса: "Товар". В теле этого цикла объект "НашЗапрос" позициони­руется во временном наборе данных на записи, содержащие итоги по каждому конкретному товару, поэтому в теле этого цикла мы можем использовать итоги по товарам.

    После завершения цикла по самой внешней группировке, объект "НашЗапрос" снова позиционируется на первой записи временного набора данных, где содержится общий итог по запросу. Поэтому, общие итоги по за­просу можно использовать в двух местах: до и после цикла по самой внешней группировке запроса.

    Продолжение примера:

    //Итог общий

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



       //Итог по товару

    КонецЦикла;

    //Итог общий

    Поскольку после первого просмотра временного набора данных (как мы это сделали выше) объект "НашЗапрос" снова спозиционирован на первой записи, то можно запустить просмотр еще раз.

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

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

    После завершения цикла по вложенной группировке ("Склад"), объект "НашЗапрос" снова позиционируется на записи временного набора данных, где содержится общий итог по конкретному товару. Поэтому, общие итоги по конкретному товару можно использовать в двух местах: до и после цикла по вложенной группировке ("Склад").

    После завершения цикла по самой внешней группировке, объект "НашЗапрос" снова позиционируется на первой записи временного набора данных, где содержится общий итог по запросу. Поэтому, общие итоги по за­просу можно использовать в двух местах: до и после цикла по самой внешней группировке запроса.

    Продолжение примера:

    //Итог общий

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

       //Итог по товару

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

          //Строка по товару — складу

       КонецЦикла;

       //Итог по товару

    КонецЦикла;

    //Итог общий

    После выхода из процедуры, где была определена переменная, содержащая объект типа «Запрос» (в нашем примере "НашЗапрос") или после уничтоже­ния объекта типа «Запрос» (Наш3апрос = 0;), временный набор данных на локальной машине пользователя уничтожается.



    Из приведенного выше примера можно сделать несколько важных заключе­ний:

    • при просмотре временного набора данных, вложенность циклов про­смотра должна точно повторять порядок группировок запроса (нельзя входить во вложенную группировку, не войдя в предыдущую);


    • допускается просматривать временный набор данных, опуская с некото­рого уровня все вложенные (внутренние) группировки;


    • не следует прерывать последовательность просмотра временного набора данных (например, оператором Прервать;), если вы собираетесь ис­пользовать временный набор дальше или еще раз, т. к. в таком случае те­ряется точка позиционирования во временном наборе и продолжать про­смотр невозможно;


    • Пример:

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

         Если (Запрос.Товар = НужныйТовар) Тогда

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

               Если (Запрос.Отдел = НужныйОтдел) Тогда

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

                     Если (Запрос.Сотрудник = НужныйСотрудник) Тогда

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

                           Док = Запрос.Док;

                           Если Запрос.ПрихКол <> 0 Тогда

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

                           ИначеЕсли Запрос.РасхКол <> 0 Тогда

                              Приращение = Запрос.РасхКол;

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

                           КонецЕсли;

                        КонецЦикла;

                     КонецЕсли;

                  КонецЦикла;

               КонецЕсли;

            КонецЦикла;

         КонецЕсли;

      КонецЦикла;


      Содержание раздела