Каталог решений - Некоторые полезные новичкам платформы 1С8.х приёмы работы с запросами

Некоторые полезные новичкам платформы 1С8.х приёмы работы с запросами

Некоторые полезные новичкам платформы 1С8.х приёмы работы с запросами

В наличии

В статье приведено несколько приёмов работы с запросами повышающие эффективность работы программиста

Категория:

Описание

 

Как известно основой работы по отбору данных на платформе 1С-Предприятие 8.х являются запросы, в этом кратком материале, не претендующем на полноту, приводится несколько простых приёмов работы с запросами на мой взгляд, представляющих интерес для новичков. Все приёмы будут приводиться в тексте запросов, после кода будет даваться краткое пояснение. Большинство приёмов рассчитаны на традиционную парадигму кодирования на 1С8.Х, а именно: вынесение многократно используемого кода в общие модули, стремление к написанию более компактного и более читаемого кода, написание универсальных процедур и функций. Запросы выбраны для примеров самые простые, что-бы лучше был виден сам приём а не терялся в глубине кода.

 

1.       1.Обработка  пустого результата в самом запросе.

Запрос.Текст = "ВЫБРАТЬ
|    Номенклатура.Ссылка,
|      ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток,0)
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(&МоментВремени, )
|    КАК ОстаткиНоменклатурыОстатки
|        ПО ОстаткиНоменклатурыОстатки.Номенклатура = Номенклатура.Ссылка"

 

  Что это даёт: в результате работы запрос может возвращать значение типа «Null». В этом случае работа с результатом запроса выдаст ошибку, т.к. значение типа «Null» не может быть преоблазовано к значению другого вида (число, строка и др.). Функция ЕСТЬNULL() прямо в запросе произведёт проверку возвращаемого результата. Такой приём позволяет несколько разгрузить клиентскую часть, в случае многократного использования запроса вынесенного в общий модуль позволит сократить строки кода.

 

2.Построение многовариантного запроса.

Процедура ОбщийОтбор(Тип, МоментВремени)
Запрос.Текст ="ВЫБРАТЬ
|             ОстаткиНоменклатурыОстатки.КоличествоОстаток
|ИЗ
|             РегистрНакопления.ОстаткиНоменклатуры.Остатки(&МоментВремени, ) КАК |ОстаткиНоменклатурыОстатки"
Если Тип=1 Тогда
 СтрЗаменить(Запрос.Текст," .ОстаткиНоменклатуры.", ".ОстаткиИмущества.");

КонецЕсли;

Результат = Запрос.Выполнить();

 

  Что это даёт: выполнение над текстом запроса операции «СтрЗаменить» до команды «Запрос.Выполнить()» позволяет сделать универсальный  и легко читаемый запрос над разными схожими по структуре регистрами.  Конечно, можно было вынести имя регистра в переменную ну например «ИмяРегистра»  тогда-бы запрос имел вид :

"ВЫБРАТЬ
|             ОстаткиНоменклатурыОстатки.КоличествоОстаток
|ИЗ
|             РегистрНакопления. "+ИмяРегистра+".Остатки(&МоментВремени, ) КАК |ОстаткиНоменклатурыОстатки"
 

Но в этом случае мы теряем возможность правки текста запроса посредством конструктора запросов, что в случае сложных запросов является серьёзным недостатком

3.       Использование функции Значение.

 

"ВЫБРАТЬ
             КонтактСКлиентом.Контрагент,
             КонтактСКлиентом.ВидКонтакта,
             КонтактСКлиентом.Заголовок,
             КонтактСКлиентом.Тема,
             КонтактСКлиентом.МоментВремени
ИЗ
             Документ.КонтактСКлиентом КАК КонтактСКлиентом
ГДЕ
             КонтактСКлиентом.ВидКонтакта = ЗНАЧЕНИЕ(Перечисление.ВидыКонтактов.Звонок)"


Что это даёт: если этот запрос отбирает только один вид контакта, то нет необходимости передавать вид контакта в качестве параметра в запрос.

Примечение: в качестве аргумента функции значение может выступать предопределённое значение, т.е то значение, к которому кожно обратиться из кода напрямую (предопределённые счета плана счетов, все значения перечислений и т.п.).

 

4.       Выгрузка результатов запроса в табличную часть.

 

Запрос.Текст = "ВЫБРАТЬ
|            ПоступлениеТоваров.Номенклатура КАК Номенклатура,
|            СУММА(ПоступлениеТоваров.Количество) КАК Количество,
|            СУММА(ПоступлениеТоваров.Сумма) КАК Сумма,
|            ПоступлениеТоваров.Ссылка.Дата КАК Период,
|            ПоступлениеТоваров.Ссылка.Контрагент КАК Контрагент
|    ИЗ
|           Документ.ПриобретениеТМЦ.РеестрТМЦ КАК ПоступлениеТоваров
|  ГДЕ
|           ПоступлениеТоваров.Ссылка = &Ссылка
|  СГРУППИРОВАТЬ ПО
|           ПоступлениеТоваров.Номенклатура,
|           ПоступлениеТоваров.Ссылка.Контрагент";

ТаблицаЗакупок = Запрос.Выполнить().Выгрузить();
Движения.Закупки.Загрузить(ТаблицаЗакупки);


Что это даёт: такой код позволяет выполнить загрузку результатов запроса в табличную часть документа двумя командами без обхода результатов в цикла. Код более компактный, читабельный, быстрый.

 

5.       Добавление необходимых значений в результат запроса.

 

При использовании результатов запроса, как в предыдущем примере, нередко  для получения значения некоторых колонок в запрос приходится добавлять обращения ещё к одной или нескольким таблицам, чтобы получить значения всех требуемых колонок, в том случае когда эти значения уже известны их можно передать в качестве параметров, подобный запрос может иметь вид:

Запрос.Текст = "ВЫБРАТЬ
|          ПоступлениеТоваров.Номенклатура КАК Номенклатура,
|          СУММА(ПоступлениеТоваров.Количество) КАК Количество,
|          СУММА(ПоступлениеТоваров.Сумма)КАК Сумма,
|          &ДатаПриобретения КАК Период,
|          &Поставщик КАК Контрагент
|ИЗ
|         Документ.ПриобретениеТМЦ.РеестрТМЦ КАК ПоступлениеТоваров
|ГДЕ
|         ПоступлениеТоваров.Ссылка = &Ссылка
|СГРУППИРОВАТЬ ПО
|         ПоступлениеТоваров.Номенклатура;"

                Запрос.УстановитьПараметр("ДатаПриобретения", ДатаОтбора);
               Запрос.УстановитьПараметр("Поставщик",ВыбраныйПоставщик);

ТаблицаЗакупок = Запрос.Выполнить().Выгрузить();
Движения.Закупки.Загрузить(ТаблицаЗакупки);

Что это даёт: читабьельность не теряется, запрос  удобнее читается «с экрана», за счёт ухода от использования в запросе обращения к дополнительным таблицам, время выполнения запроса меньше.

 

6.       Передача массива в качестве параметра.

"ВЫБРАТЬ
|             КонтактСКлиентом.Контрагент,
|             КонтактСКлиентом.ВидКонтакта,
|             КонтактСКлиентом.Заголовок,
|             КонтактСКлиентом.Тема,
|             КонтактСКлиентом.МоментВремени
|ИЗ
|             Документ.КонтактСКлиентом КАК КонтактСКлиентом
|ГДЕ
|             КонтактСКлиентом.ВидКонтакта  В (&ВидыКонтактов)"

               ВидыКонтактов = Новый Массив;
               ВидыКонтактов.Добавить(Перечисления.ВидыКонтактов.Звонок);
               ВидыКонтактов.Добавить(Перечисления.ВидыКонтактов.Письмо);
               ВидыКонтактов.Добавить(Перечисления.ВидыКонтактов.Встреча);
               Запрос.УстановитьПараметр("ВидыКонтактов ", ВидыКонтактов);

Что это даёт: текст запроса остаётся читабельным, количество параметров не зашкаливает, трафик данных между клиентом и сервером минимальный.

 

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

Текст, демонстрирующий сразу несколько приёмов, текст кода находится в модуле объекта документа (естественно в оригинале код немного сложнее и движения выполняются по нескольким регистрам), код написан для платформы 1С8.2 :

 

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

   Движения.ОстаткиНоменклатуры.Записывать = Истина;
          ВыполнитьДвиженияОстаткиНоменклатуры();
КонецПроцедуры

Процедура ВыполнитьДвиженияОстаткиНоменклатуры() Экспорт

    Запрос = Новый Запрос;
    Запрос.Текст =" ВЫБРАТЬ
|            РеализацияТоваровТовары.Номенклатура,
|            РеализацияТоваровТовары.Сумма,
|            РеализацияТоваровТовары.Качество,
|            РеализацияТоваровТовары.Ссылка.Дата КАК Период,
|            ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход) КАК ВидДвижения
|        ИЗ
|            Документ.РеализацияТоваров.Товары КАК РеализацияТоваровТовары
|        ГДЕ
|            РеализацияТоваровТовары.Ссылка =&Ссылка
|            И РеализацияТоваровТовары.Номенклатура.ВидНоменклатуры <> Значение(Перечисления.ВидыНоменкклатуры.Услуга)";

    Запрос.УстановитьПараметр("Ссылка", Ссылка);

    Результат = Запрос.Выполнить();
    Движения.ОстаткиНоменклатуры.Загрузить(Результат.Выгрузить());
    Движения.ОстаткиНоменклатуры.Записать();

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

Что делает этот код:  процедура «ОбработкаПроведения» вызывает процедуру «ВыполнитьДвиженияОстаткиНоменклатуры» (Далее просто процедура).  Процедура выполняет запрос, с единственным параметром «Ссылка» (это ссылка на наш документ — выполняющий функцию регистратора движений регистра). Запрос возвращет весь перечень номенклатуры документа кроме номеклатуры имеющей тип «Услуга», результат запроса выгружается в таблицу и из таблицы загружается в регистр «РегистрыНакопления.ОстаткиНоменклатуры«(вид регистра — регистр остатков).

Справочно, структура регистра:

Измерения:

    Номенклатура — СправочникСсылка.Номенклатура

   Качество — ПеречислениеСсылка.Качество

Ресурсы:

   Количество — Число 15.3

 

Вместо эпилога: Уважаемые читатели, в общем статья была написана на коленке (писал сразу из головы (даже не в конструкторе/консоли запросов) , не спрашивайте почему так получилось — не скажу!) за полчаса…, в начале февраля выйдет переработанная и несколько расширенная статья (извините, но год закончился — пошла отчётностью, нововведения в законодательстве,…. времени не хватает совсем), если у кого-то есть пожелания увидеть что-то конкретное — пишите в коменты, постараюсь всё учесть. Обязательно напишу про простейшие приёмы и принципы оптимизации в запросах. Новая статья будет так-же написана максимально простым языком новичка для новичков, но надеюсь будет более продумана и не вызовет столько нареканий…

Всех с Крещением Господним!

И успехов всем нам в нашем нелёгком труде!

19.01.2011.

has been added to your cart:
Оформление заказа