Hare.ru @ Коллективный разум / Hare.ru @ Дикое место

Архив hare.ru 
Мысли, конвертированные в текст

Собственные руки TM


Все статьи раздела

Динамические запросы в 1Cv7

Владимир Козлов (где-то в 2001)

Что подразумевается под “динамическими запросами”? Только то, что текст запроса не хранится в явном виде где-то в модуле, а формируется “на лету” (т.е. методами встроенного языка, прямо в процессе работы), на основании выбранных пользователем настроек и условий.

Зачем это нужно? Дело в том, что механизм запросов V7 в ряде случаев намного превосходит методы “тупого перебора” по производительности (не говоря о простоте и изящности кода). Но почему-то многие программисты не идут дальше использования конструктора запросов и хранения текста запроса в явном виде в модуле.

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

В качестве примера, иллюстрирующего вышесказанное, предлагается обработка “Универсальный реестр документов” – лучше один раз увидеть, чем прочитать тонну описаний.

Предистория этого дела такова – в типовых конфигурациях от 1С для компоненты “Оперативный учет” был (и есть) такой универсальный отчет – “Реестр документов”, уж очень он мне в свое время (еще во времена 7.5) понравился, и я вставил его в свою рабочую конфигурацию. Я думаю, что наверняка все, кто так или иначе связан с программированием на 1С, знакомы с этим отчетом, так что описывать его функционал не буду. Идея отчета хороша, но реализация мне кажется весьма ущербной, особенно после появления версии 7.7. Так что пришлось этот отчёт переписать заново. В результате получился UniReestr.ert.

Что он умеет?

  • Во-первых, отбор документов производится не тупым перебором, а через запрос, что даёт лучшее быстродействие отчета как в файл-серверной (DBF), так и в клиент-серверной (SQL) версиях движка 1С.
  • Во-вторых, предусмотрена возможность отбора документов по конкретным значениям любых реквизитов шапки документа и/или общих реквизитов.
  • В-третьих, имеется возможность суммирования итогов по любой колонке табличной части документа с установленным реквизитом “ИтогПоКолонке”.
  • Наконец, в-четвертых, поскольку в отчете активно используется объект метаданные, он максимально “отвязан” от конкретной конфигурации (и даже компоненты) и может быть быстро и легко адаптирован в любую конфигурацию. Единственное предположение, сделанное при написании отчёта – это наличие в конфигурации справочника “Товары”, так что при адаптации следует обратить на это внимание, и, при необходимости, поменять “Товары” или на любой другой справочник, по которому необходимо производить отбор.

Еще один момент, на который хочу обратить внимание – в моей конфигурации в данном отчёте реализована возможность открытия общего журнала документов на конкретном документе, выбранном кликом по “книжечке” в печатной форме отчёта, на мой вкус это очень удобно. Если вы согласны со мной и хотите реализовать такую же фичу и у себя, то следует проделать следующее:

  • заменить в ert содержимое закладки “Таблица” содержимым закладки “Журнал”
  • в модуль формы отчета добавить следующую процедуру:

    //-----------------------------
    Процедура ОбработкаЯчейкиТаблицы(ТекЗн,ФлгСтд,Конт,Адр)
       НомКол=Число(Сред(Адр,Найти(Адр,"C")+1));
       Если НомКол=4 Тогда
         // sic! имя общего журнала документов может быть другим
         ОткрытьФорму("Журнал.Общий.ФормаСписка #Общ",ТекЗн);
       Иначе
         ФлгСтд=1;
       КонецЕсли;
    КонецПроцедуры

  • в модуль формы общего журнала документов, в предопределенные процедуры добавить такой код:

    //-----------------------------
    Процедура ПриПовторномОткрытии()
      Если ПустоеЗначение(Форма.Параметр)=0 Тогда
        Если ВРег(ТипЗначенияСтр(Форма.Параметр))="ДОКУМЕНТ" Тогда
          Док = Форма.Параметр.ТекущийДокумент();
          Если (НачалоИнтервала()>Док.ДатаДок) ИЛИ
          (КонецИнтервала()<Док.ДатаДок) Тогда
            УстановитьИнтервал(НачМесяца(Док.ДатаДок), КонМесяца(Док.ДатаДок));
          КонецЕсли;
        КонецЕсли;
        Попытка
          АктивизироватьОбъект(Док);
        Исключение
        КонецПопытки;
      КонецЕсли;
    // .....
    КонецПроцедуры

    //--------------
    Процедура ПриОткрытии()
    //.....
      ПриПовторномОткрытии();
    //.....
    КонецПроцедуры

В заключение хочу заметить, что данный отчёт может служить неплохой иллюстрацией методов работы с объектами Метаданные, которые в штатном описании языка очень слабо документированы. Текст отчёта в достаточной степени снабжён комментариями, так что разбор особого труда не составит.

Партнеры:


Также может быть интересно:

Канал Россия 1 на http://spbtvonline.ru/
   
 Сайт поддерживается за счет партнеров:
:::... Сайт содержит архив двух версий hare.ru Карта сайта