Выбрать минимум в запросе 1с. Агрегатные функции системы компоновки данных

Подписаться
Вступай в сообщество «passport13.com»!
ВКонтакте:

Предположим, что на наших складах имеется такой товар:

Секция группировки объявляется ключевым словом СГРУППИРОВАТЬ ПО . Для чего нужна группировка в запросе? Совершенно верно, для объединения в группу одинаковых полей таблицы и получения суммарных результатов по остальным. Группировка сворачивает одинаковые поля запроса в одно, уменьшая тем самым количество результирующих записей. Сразу оговорюсь, если в запросе применяется группировка, то все поля должны быть разбиты на две категории: те по которым группируем и те которые группируются. Поясню на примере, допустим мы хотим узнать сколько у нас товара вообще, без учета складов, тогда мы напишем следующий код запроса:

Запрос.Текст = "
|ВЫБРАТЬ
| Товары.Товар,
| СУММА(Товары.Количество) КАК Количество
|ИЗ
|
|СГРУППИРОВАТЬ ПО
| Товары.Товар";

Товар в данном случае - это поле по которому осуществляется группировка, а Количество - группируемое поле. СУММА - это агрегатная функция, она указывает запросу что все данные по количеству одинаковых товаров нужно просуммировать. Результатом выполнения этого запроса будет таблица вида:

Агрегатные функции

К группируемым полям должны быть обязательно применена агрегатная функция, это необязательно СУММА, а также МАКСИМУМ, МИНИМУМ, СРЕДНЕЕ, КОЛИЧЕСТВО, КОЛИЧЕСТВО РАЗЛИЧНЫХ. Рассмотрим более подробно действие каждой из них.

СУММА - применяется только для числовых полей, складывает переданные ей числа. Ее результат приведен на рисунке выше.

СРЕДНЕЕ - применяется только для числовых полей, вычисляет среднее - сумма переданных параметров / количество параметров:

МАКСИМУМ - может использоваться для любых полей, получает максимальный из переданных параметров. Допустим текст запроса имеет вид:

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

Т.е. имеем опять одно группировочное поле Товар и два группируемых поля: Склад и Количество. Результат выполнения этого запроса будет выглядеть следующим образом:

МИНИМУМ - может использоваться для любых полей, получает минимальный из переданных параметров:

КОЛИЧЕСТВО - может использоваться для любых полей, получает количество переданных параметров:

КОЛИЧЕСТВО РАЗЛИЧНЫХ - может использоваться для любых полей, получает количество различных параметров. Т.е. если функции передать параметры (1,1,2,3,3,3,4,4,4,4,4,5), то она вернет 5 . Функция КОЛИЧЕСТВО вернула бы 12. Запрос с использованием функции КОЛИЧЕСТВО РАЗЛИЧНЫХ будет выглядеть так:

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

Результат:

Пусть мы группируем по двум полям: Товар и Склад:

Запрос.Текст = "
|ВЫБРАТЬ
| Товары.Товар,
| Товары.Склад КАК Склад,
| <АГРЕГАТНАЯ ФУНКЦИЯ>(Товары.Количество) КАК Количество
|ИЗ
| Справочник.Товары КАК Товары
|СГРУППИРОВАТЬ ПО
| Товары.Товар,
| Товары.Склад";

для различных агрегатных функций результат будет следующим:

Подведем итоги:

Если в запросе используется группировка, то все поля должны делиться на группируемые (которые будут "свернуты") и группировочные (по которым осуществляется группировка - "сворачивание"). К группируемым полям должна быть применена одна из агрегатных функций, причем такие функции как СУММА и СРЕДНЕЕ могут быть применены только к числовым полям.

<Разыменование поля> |

<Агрегатная функция> |

<Встроенная функция> |

<Операция выбора> |

<Приведение типа>[.<Разыменование поля>] |

<3начение> |

<Выражение> <Бинарная операция> <Выражение> |

<Унарная операция> <Выражение> |

Выражения в списке полей выборки, в предложениях ИМЕЮЩИЕ, ИТОГИ, УПОРЯДОЧИТЬ ПО могут быть агрегатными функциями . Агрегатные функции описаны на .

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

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

Разыменование полей

Выражения языка запросов в простейшем случае представляют собой ссылки на поля таблиц информационной базы. В общем виде ссылки описываются следующими правилами:

[<Таблица>.]<Имя поля>[.<Имя поля>[...]]

<Имя таблицы> | <Псевдоним источника>

Разыменование поля начинается с имени таблицы, содержащей это поле. Если <Имя поля> уникально - существует только у одной из таблиц среди указанных в списке источников, <Таблица> может быть опущена.

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

Если исходной таблице в списке источников присвоен <Псевдоним источника>, он может использоваться вместо имени таблицы в разыменовании полей этой таблицы. В против­ном случае указывается <Имя таблицы> (см. описание источ­ников данных запроса).

Агрегатные функции языка запросов

В языке запросов предусмотрены агрегатные функции, которые используются при группировке результатов запроса и при подсчете итогов. Агрегатные функции предназначены для обобщения значений указанного параметра. Определены следующие агрегат­ные функции:

СУММА (<Выражение >) |

СРЕДНЕЕ (<Выражение>) |

МИНИМУМ (<Выражение>) |

МАКСИМУМ (<Выражение>) |

КОЛИЧЕСТВО ([РАЗЛИЧНЫЕ] <Выражение> | *)

Выбрать
Накладная.Номенклатура.Наименование,
Сумма(Накладная.Сумма) Как Сумма,
Среднее(Накладная.Сумма) Как Среднее,
Максимум(Накладная.Сумма) Как Максимум,
Минимум(Накладная.Сумма) Как Минимум,
Количество(Накладная.Сумма) Как Колич
Из

Сгруппировать По
Накладная.Номенклатура
Итоги Общие

Результат запроса:

Наименование Сумма Среднее Максимум Минимум Колич
265 955,45 12 511,12 40 000,23 555 8
Брюки детские 28 500,22 9 500,07 15000 3000 3
Рубашка «Ков­бойка» 24000 8000 16000 4000 3
Джинсы жен­ские 63555 6 355,5 30000 555 10
Свитер детский 6400 6400 6400 6400 1
Раковина «Ли­лия» 60 000,23 30000,115 40 000,23 20000 2
Мойдодыр «Ак­вариум» 65500 21 833,33 40000 8000 3
Смеситель «Ультра» 15000 15000 15000 15000 1
Кухонный ком­байн Крупс 3000 3000 3000 3000 1

Агрегатные функции могут использоваться в списке полей вы­борки, предложениях ИМЕЮЩИЕ, ИТОГИ, УПОРЯДОЧИТЬ ПО.

Агрегатная функция СУММА

Функция вычисляет арифметическую сумму всех попавших в выборку значений поля.

В качестве параметра функции можно указывать только поля, содержащие числовое значение.

Если поле не может содержать числовых значений, то примене­ние функции СУММА к такому полю вызовет ошибку. Если поле может содержать числовые значения (имеет составной тип дан­ных), то данная функция может быть применена к такому полю. Но если среди значений поля в выборке встретится нечисловое значение (помимо значений NULL), это вызовет ошибку.

Агрегатная функция СРЕДНЕЕ

Функция вычисляет среднее значение всех попавших в выборку значений поля.

В качестве параметра функции можно указывать только ссылки на поля, содержащие числовое значение.

Если поле не может содержать числовых значений, то примене­ние функции СРЕДНЕЕ к такому полю вызовет ошибку. Если поле может содержать числовые значения (имеет составной тип данных), то данная функция может быть применена к такому по­лю. Но если среди значений поля в выборке встретится нечисло­вое значение (помимо значений NULL), это вызовет ошибку.

Агрегатная функция МИНИМУМ

Функция вычисляет минимальное значение из всех попавших в выборку значений поля.

При определении минимального значения применяются правила сравнения значений, описанные на .

Агрегатная функция МАКСИМУМ

Функция вычисляет максимальное значение из всех попавших в выборку значений поля.

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

При определении максимального значения применяются правила сравнения значений, описанные на .

Агрегатная функция КОЛИЧЕСТВО

Функция подсчитывает количество значений параметра, попав­ших в выборку. В отличие от других агрегатных функций функ­ция КОЛИЧЕСТВО допускает три способа использования.

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

ВЫБРАТЬ
Количество(*) Как Всего,
Количество(Различные Накладная.Номенклатура) Как Разные
Из
Документ.РасходнаяНакладная.Состав Как Накладная

Результат запроса:

Всего Разные
24 8

Встроенные функции языка запросов

В языке запросов определены встроенные функции, которые мо­гут использоваться в выражениях в списке полей выборки (см. стр. 300) и в условии отбора в предложении ГДЕ (см. стр. 315). Опре­делены следующие встроенные функции:

ПОДСТРОКА(<Выражение>, <3начение>, <3начение>) |
ГОД(<Выражение>) |
КВАРТАЛ(<Выражение>) |
МЕСЯЦ(<Выражение>) |
ДЕНЬГОДА(<Выражение>) |
ДЕНЬ(<Выражение>) |
НЕДЕЛЯ(<Выражение>) |
ДЕНЬНЕДЕЛИ(<Выражение>) |
ЧАС(<Выражение>) |
МИНУТА(<Выражение>) |
СЕКУНДА(<Выражение>)

Данная функция предназначена для выделения подстроки из строки.

<Выражение>

Строка, из которой необходимо выделить под­строку. Выражение, имеющее тип Строка.

<3начение>

Позиция символа, с которого начинается вы­деляемая из строки подстрока. Значение типа Число.

<3начение>

Длина выделяемой подстроки. Значение типа Число.

Если в качестве первого параметра фигурирует строка, то резуль­татом функции будет строка (возможно нулевой длины). Если в качестве первого параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Выбрать
Справочних.Контрагенты.Наименование,
Подстрока(Справочник.Контрагенты.Наименование, 3, 5) Как Подстрока

Результат запроса:

Данная функция предназначена для вычисления номера года из значения типа Дата.

Данная функция предназначена для вычисления номера квартала из з гачения типа Дата. Номер квартала находится в диапазоне 1-4.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления номера месяца из значения типа Дата. Номер месяца находится в диапазоне 1 -12.

Параметр функции - это выражение, имеющее тип Дата-

Данная функция предназначена для вычисления дня года из зна­чения типа Дата. День года находится в диапазоне 1 - 366.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качестве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления дня месяца из значения типа Дата. День месяца находится в диапазоне 1 - 31.

Параметр функции - это выражение, имеющее тип Дата.

Данная функция предназначена для вычисления номера недели года из значения типа Дата.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления дня недели из значения типа Дата. День недели находится в диапазоне 1 (по­недельник) - 7 (воскресенье).

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления часа суток из значения типа Дата. Час суток находится в диапазоне 0 - 23.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления минуты часа из значения типа Дата. Минута часа находится в диапазоне 0 - 59.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Данная функция предназначена для вычисления секунды минуты из значения типа Дата. Секунда минуты находится в диапазоне 0 - 59.

Параметр функции - это выражение, имеющее тип Дата.

Если в качестве параметра фигурирует значение типа Дата, то результатом функции будет значение типа Число. Если в качест­ве параметра будет использовано значение NULL, то результатом функции также будет значение NULL. Другие значения считаются недопустимыми и вызывают состояние ошибки.

Операции выбора в языке запросов

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

Операция выбора описывается следующим набором правил:

ВЫБОР
<Альтернативы выбора>
[ИНАЧЕ
<Выражение>]
КОНЕЦ

<Одиночный выбор> [<Альтернативы выбора>]

КОГДА
<Логическое выражение>
ТОГДА
<Выражение>

В операции выбора может указываться неограниченное количест­во альтернативных одиночных выборов КОГДА... ТОГДА. Они обрабатываются в запросе последовательно; если <Логическое выражение> имеет значение ИСТИНА, обработка операции вы­бора завершается; результатом операции является значение вы­ражения, указанного после слова ТОГДА. Логические выражения описаны на .

Значение выражения, указанного после слова ИНАЧЕ использует­ся в качестве результата операции выбора в том случае, если во всех ранее указанных альтернативных одиночных выборах преди­кат имел значение ЛОЖЬ.

Выбрать
,
Выбор
Когда Справочник.Номенклатура.ЭтоГруппа = Истина Тогда "Это Группа"
Когда Справочник.Номенклатура.ЗакупочнаяЦена > 1000 Тогда "1000 -"
Когда Справочник.Номенклатура.ЗакупочнаяЦена > 100 Тогда "100 - 1000"
Когда Справочник.Номенклатура.ЗакупочнаяЦена > 10 Тогда "10 - 100"
Когда Справочник.Номенклатура.ЗакупочнаяЦена > 0 Тогда «0 - 10»
Иначе "Не Задана"
Конец Цена

Результат запроса:

Наименование Цена
Брюки детские 100 - 1000
Рубашка «Ковбойка» 1000-
Одежда Это группа
Джинсы женские 1000-
Свитер детский Не задана
Сантехника Это группа
Бытовая техника Это группа
Раковина «Лилия» Не задана
Мойдодыр «Аквариум» Не задана
Смеситель «Ультра» 100 - 1000
Кухонный комбайн Крупе 1000-
Мясорубка Браун Не задана
Электронож Крупе Не задана
Зажигалка для газовой плиты «Огонек» Не задана
Калькулятор бухгалтерский Не задана
Кухонная техника Это группа
Оргтехника Это группа

Приведение типа в языке запросов

Поля исходных таблиц могут иметь составной тип. Для таких по­лей возникает необходимость привести значения поля к какому-либо определенному типу. В языке запросов предусмотрена воз­можность приведения типа, ею можно пользоваться в списке по­лей выборки и в условии отбора в предложении ГДЕ.

ВЫРАЗИТЬ (<Выражение> КАК <Тип значения>)

БУЛЕВО | ЧИСЛО | СТРОКА | ДАТА | <Имя таблицы>

<Выражение> приводится к одному из базовых типов, или к ссылочному типу данных; в последнем случае <Имя таблицы> указывает на соответствующую таблицу информационной базы.

Если <Выражение> содержит в составном типе требуемый <Тип значения>, то приведение типа считается осуществи­мым, и для каждого значения указанного типа результатом будет это самое значение. Для значений других типов результатом при­ведения типа будет значение NULL.

Если <Выражение> не содержит в составном типе требуемый <Тип значения>, то выполнение данного запроса завершится ошибкой из-за принципиальной невозможности совершить при­ведение типов.

Константы и параметры в языке запросов

В выражениях языка запросов могут напрямую указываться зна­чения типа булево, число, строка или дата. Также могут использоваться значения параметров запроса:

ИСТИНА |
ЛОЖЬ |
<Литерал типа ЧИСЛО> |
<Литерал типа СТРОКА> |
<Литерал типа ДАТА> |
<Имя параметра>

<Целое число> [.<Целое число>]

<Последовательность символов>

ДАТАВРЕМЯ (<Целое число>, <Целое число>, <Целое число>[, <Целое число>, <Целое число>, <Целое число>])

Значения типа булево, число, строка в языке запросов зада­ются так же, как и во встроенном языке.

Значения типа дата задаются с помощью ключевого слова ДАТАВРЕМЯ, после которого в скобках последовательно указы­ваются год, месяц, день, час, минута, секунда. Последние три ука­зывать необязательно.

В запрос могут передаваться параметры (см. описание объекта Запрос). Значения параметров могут использоваться в выраже­ниях языка запросов, для этого необходимо указать символ & и после него <Имя параметра>.

Условия в языке запросов

В языке запросов используются условия отбора, в соответствии с которыми осуществляется отбор данных в предложениях ГДЕ, ИМЕЮЩИЕ и СОЕДИНЕНИЕ. Условия описываются по следующим правилам:

<Логическое слагаемое> [ИЛИ <Логическое слагаемое>]

<Логический сомножитель> [И <Логический сомножитель>]

НЕ <Логический сомножитель> | (<Условие отбора>) | <Логическое выражение>

В простейшем случае условие является выражением, результат которого имеет значение логического типа. Логические выраже­ния описаны ниже.

Условия могут определяться и как более сложные логические выражения, где фигурируют простые логические выражения, со­единенные между собой с помощью логических операторов И, ИЛИ, НЕ.

Логические операторы имеют приоритет:

Самый высокий приоритет имеет логический оператор НЕ.

Следующим по приоритету является оператор И.

Самый низкий приоритет у оператора ИЛИ.

В условиях сначала вычисляются простые логические выражения, затем операции НЕ, затем операции И, в последнюю очередь -операции ИЛИ. Для того, чтобы обеспечить другой порядок вы­числений, можно использовать круглые скобки ().

Логические выражения в языке запросов

В языке запросов в операциях выбора и в условиях отборов ис­пользуются логические выражения:

<Выражение> |
<Выражение> <Операция сравнения> <Выражение> |
<Выражение> [НЕ] В [ИЕРАРХИИ] (<Список значений>)

<Выражение> [НЕ] В [ИЕРАРХИИ] <Описание запроса> |
<Выражение> [НЕ] МЕЖДУ <Выражение> И <Выражение> |
<Выражение> ЕСТЬ [НЕ] NULL |
<Выражение> ССЫЛКА <Имя таблицы> |
<Выражение> [НЕ] ПОДОБНО <Литерал типа СТРОКА> [СПЕЦСИМВОЛ <Литерал типа СТРОКА>]

<Выражение> [, <Выражение> [, ...] ]

Логическим выражением может быть:

Обычное <Выражение> языка запросов, если его результат имеет логический тип;

<Операция сравнения> двух выражений языка запросов; выполняются в соответствии с правилами сравнения значений описанными на ;

Оператор проверки совпадения / не совпадения значения выражения с одним из перечисленных или со значениями, со­держащимися в результате другого запроса;

Оператор проверки вхождения значения выражения в диапа­зон;

Оператор проверки значения выражения на NULL;

Оператор проверки ссылочного значения выражения на ссыл­ку на определенную таблицу;

Оператор проверки строкового значения на подобие шаблону.

При сравнении значений используются правила сравнения значе­ний, описанные на .

Оператор В позволяет проверить, совпадает ли значение выраже­ния, указанного справа от него, с одним из значений, описанных слева. Если совпадает хотя бы с одним - результатом оператора будет ИСТИНА, иначе - ЛОЖЬ. Применение НЕ изменяет дейст­вие оператора на обратное. Сравнение значений производится по правилам, описанным на .

Выбрать
Справочник.Номенклатура.Наименование
Где
Справочник.Номенклатура.Родитель.Наименование В ("Бытовая техника", "Оргтехника")

Для справочников проверка может осуществляться и на принад­лежность по иерархии. Результатом оператора В ИЕРАРХИИ бу­дет ИСТИНА, если значение выражения слева является ссылкой на элемент справочника и входит во множество значений справа или иерархически принадлежит какой-нибудь группе, содержа­щейся в этом множестве.

//В качестве параметра Группа в запрос передается ссылка
//на какую-либо группу справочника Номенклатура.
Выбрать
Справочник.Номенклатура.Наименование
Где
Справочник.Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)

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

Выбрать
Справочник.Номенклатура.Наименование
Где
Справочник.Номенклатура.Ссылка В ИЕРАРХИИ
(ВЫБРАТЬ
Справочник.Номенклатура.Ссылка
ГДЕ
Справочник.Номенклатура.Наименование = "Одежда")

Оператор МЕЖДУ позволяет проверить, входит ли значение выра­жения, указанного справа от него, в диапазон, указанный слева. Если входит - результатом оператора будет ИСТИНА, иначе -ЛОЖЬ Применение НЕ изменяет действие оператора на обратное. Сравнение значений производится по правилам, описанным на .

Выбрать

Справочник.Номенклатура.ЗакупочнаяЦена
Где
Справочник.Номенклатура.ЗакупочнаяЦена МЕЖДУ 100 И 1000

Оператор ЕСТЬ NULL позволяет проверить значение выражения слева от него на NULL. Если значение равно NULL результатом оператора будет ИСТИНА, иначе - ЛОЖЬ. Применение НЕ изме­няет действие оператора на обратное.

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

Справочник.Номенклатура.ЗакупочнаяЦена

Справочник.Номенклатура.ЗакупочнаяЦена Есть NULL

Оператор ССЫЛКА позволяет проверить, является ли значение выражения, указанного справа от него, ссылкой на таблицу, ука­занную слева Если да - результатом оператора будет ИСТИНА, иначе - ЛОЖЬ. Разыменование таблиц описано на .

ВЫБРАТЬ
Справочник.Номенклатура.Наименование,
Справочник.Номенклатура.ЕдиницаИзмерения
ГДЕ
Справочник.Номенклатура.ЕдиницаИзмерения ССЫЛКА Справочник.ЕдиницыИзмерения

Оператор ПОДОБНО позволяет сравнить значение выражения, указанного слева от него, со строкой шаблона, указанной справа. Значение выражения должно иметь тип строка. Если значение выражения удовлетворяет шаблону - результатом оператора бу­дет ИСТИНА, иначе - ЛОЖЬ.

Следующие символы в строке шаблона являются служебными и имеют смысл, отличный от символа строки:

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

_ (подчеркивание): один произвольный символ.

[...] (в квадратных скобках один или несколько символов): любой одиночный символ из перечисленных внутри квадрат­ных скобок. В перечислении могут встречаться диапазоны, на­пример a-z, означающие произвольный символ, входящий в диапазон, включая концы диапазона.

[^...] (в квадратных скобках значок отрицания, за которым следует один или несколько символов): любой одиночный символ, кроме тех, которые перечислены следом за значком отрицания.

Любой другой символ означает сам себя и не несет никакой до­полнительной нагрузки.

Если в качестве самого себя необходимо записать один из пере­численных символов, то ему должен предшествовать <Спецсимвол>. Сам <Спецсимвол> (любой подходящий символ) определяется в этом же операторе после ключевого слова СПЕЦСИМВОЛ.

Например, шаблон "%АБВ[абвг]\_абв%" СПЕЦСИМВОЛ "\" означает подстроку, состоящую из последовательности символов:

буквы А, буквы Б; буквы В; одной цифры, одной из букв а, 6, в или г; символа подчеркивания; буквы а; буквы б; буквы в. Причем перед этой последовательностью может располагаться произволь­ный набор символов.

Сравнительно с предыдущей публикацией текста много, но по-другому совсем никак.

1.Полная форма использования оператора В.

Помимо формы, указанной в предыдущей публикации:

Поле В (&СписокЗначений),

Также в запросах языка 1С допустимы следующие формы использования этого оператора:

1.Поле В (&Массив)

2.Поле В (&Значение1,....&ЗначениеN),

3.Поле В (Выбрать …..) или для нескольких полей:

(Поле1, Поле2) В (Выбрать Т.Поле5, Т.Поле6 Из Таблица Т) , где Т - таблица (физическая, виртуальная или временная)

4.Поле В (&ТаблицаЗначений) или для нескольких полей:

(Поле1, Поле2) В (&ТаблицаЗначений)

Вариант записи №3 называют подзапросом.

У варианта №4 есть особенность: количество полей в Таблице значений должно точно совпадать с количеством полей, по которым производится проверка. Кроме того следует учесть что при сравнении по нескольким полям условие будет принимать значение Истина только при совпадении по всем полям одновременно.

2.Оператор В Иерархии.

Этот оператор может быть использован только для иерархических справочников (и других иерархических объектов, например План Счетов, План Видов Характеристик). По сути этот оператор очень схож с оператором В, но имеет совсем другой смысл: оператор производит проверку, что элемент справочника принадлежит указанной группе (или группам вложенным в указанную группу).

Пример использования: отбираем в запросе все элементы справочника номенклатура, которые находятся в группе товаров «Мебель» (для простоты элемент справочника «Номенклатура» Мебель - предопределённый).

Запрос.Текст = "ВЫБРАТЬ Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура

Запрос. УстановитьПараметр(" Группа1", Справочники. Номенклатура. Мебель);

Примечание1: если в качестве аргумента оператора В Иерархии указать пустой элемент - будут отобраны все элементы справочника (т.е. оператор в Иерархии будет возвращать значение Истина для любого элемента справочника, т.к. у элементов и групп самого верхнего уровня значение реквизита Родитель пустое), например: Запрос. УстановитьПараметр(" Группа1", Справочники. Номенклатура. ПустаяСсылка());

Примечание2: оператор В Иерархии очень мощный и позволяет проверить принадлежность группе для элементов справочника неограниченного уровня вложенности в рамках одного запроса (что невозможно сделать другими способами), но скорость работы этого оператора не сильно велика, что особенно заметно на больших справочниках.

3.Использование конструктора запроса.

В среде программистов 1С не редко возникают споры о использовании конструктора запросов или отказе от использования конструктора и написании запроса вручную. Тем не менее, по мнению большинства программистов, пользоваться конструктором нужно, но иногда после этого полученный запрос «допиливают руками». Для вызова конструктора запросов в любом модуле нужно кликнут по правой кнопке манипулятора мышь и из выпавшего меню выбрать или «Конструктор запроса» или «Конструктор запроса с обработкой результата».

Основные преимущества использования конструктора запросов:

1.Видимость всех доступных объектов конфигурации для построения запроса (а также всех временных таблиц запроса и т.п.).

2.Точное указание имён полей и реквизитов (т.к. они не набираются вручную а выбираются из списка).

3.Упрощенное отображение взаимосвязей между объектами запроса и условий.

4.Относительно изолированная работа над каждой частью запроса (каждым запросом в пакетном запросе или отдельном запросе при объединении запросов).

5.Абсолютно достоверные данные по «существующим» в данной конфигурации Виртуальным таблицам.

4.Работа с датами в запросах (дата, момент времени, граница)

В средствах разработки 1С, начиная с версии 8.0, тип данных Дата стал составным из Даты и Времени . И всё-бы было хорошо, но и тут есть свои особенности.

1 Проблемма. Время создания документов можно определить только с точностью до секунды, т.е.если мы дважды с небольшой паузой выполним следующий код:

Док

Док

Док = Документы. Приход. СоздатьДокумент(); Док. Дата = ТекущаяДата(); Док.Записать();

Док = Документы. Расход. СоздатьДокумент(); Док. Дата = ТекущаяДата(); Док.Записать();

А потом выполнить следующий запрос:

ОБЪЕДИНИТЬ ВСЕ

УПОРЯДОЧИТЬ ПО Дата

То получим странный результат:

Документы не упорядочены даже по порядку их создания! Если заменим реквизит документа Дата на реквизит МоментВремени в запросе получим уже более лучший результат:

В пределах 1 секунды идут сначала документы «Приход» этой секунды, а далее документы «Расход» этой секунды, причём номера документов идут строго в порядке возрастания (в нашем случае в виду автонумерации документов это означает что в порядке создания). Осталось решить небольшую проблему - упорядочить внутри секунды документы в реальном порядке их создания а не только для каждого вида документа - если заблаговременно не было задачи решения этой проблемы - она не разрешима в принципе.

Примечание: МоментВремени содержит дату, время и ссылку на объект базы данных. А т.к. ссылка содержит код типа объекта и уникальный номер объекта - то сортировка в пределах секунды по МоментуВремени в качестве результата выдаст группы разнотипных объектов внутри групп упорядоченных, но между собой не «перемешанных».

Как решить эту задачу:

1вариант: если номера самих документов не принципиальны - можно создать нумератор документов и тогда номер документа будет ответствовать его порядковому номеру при создании. Это решение очень плохо в виду отказа от сквозной нумерации документов.

2 вариант: ввести дополнительное идентификационное поле и перед сохранением документа с незаполненным значением этого поля получать значение этого поля для этого документа из любого сеансанезависимого источника, которым может быть и специальная запись непериодического Регистра Сведений и значение записное во внешний текстовый или другой файл или специально для этого написанный Com-сервис и т.п. и писать полученное значение в это поле, а сохраненное значение увеличить на единичку.

2 Проблема . Выбор времени для выполнения запроса получения остатков. При выполнении многих запросов нужно указывать конец периода выборки (т.е. момент на который получаются остатки). Казалось-бы вполне правильным было так:

Запрос . УстановитьПараметр(" КонецПериода " , КонецМесяца(ТекущаяДата()));

Но на самом деле запрос получения остатков будет выполнен по состоянию на начало указанной даты(которая есть дата+время). Если учесть, что КонецМесяца(Дата(2012, 10, 29)) = 31.10.0012 23:59:59

То получается, что у нас выпадают обороты формируемые движениями (документами) за последнюю секунду периода и мы получим остатки за секунду до конца месяца а не по состоянию на конец месяца! Особенно часто эта особенность приводит к ошибке получения остатков при импорте нечальных остатков (когда в последную секунду может поместиться огромное количество документов) и в организациях работающих в режиме 7*24.

Как решить эту проблему:

1 вариант: прибавить к концу периода 1 секунду:

Запрос . УстановитьПараметр(" КонецПериода " , КонецМесяца(ТекущаяДата())+1);

2 вариант: воспользоваться специально созданным для этого объектом Граница:

ГраницаПериода = Новый Граница(КонецМесяца(ТекущаяДата())+ 1, ВидГраницы. Исключая);

Запрос. УстановитьПараметр("КонецПериода" , ГраницаПериода);

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

ГраницаПериода = Новый Граница(Документ. МоментВремени, ВидГраницы. Исключая);

или если движения и этого документа должны попасть:

ГраницаПериода = Новый Граница(Документ. МоментВремени, ВидГраницы. Включая);

Примечание 2: Как справедливо заметили в комментариях ещё 1 плюс работы с типом данных Граница - не надо задумываться что выбираешь остатки или обороты и нет необходимости передавать в сложный запрос в котором выбираются и остатки и обороты 2 параметра описывающих момент на который проиводится выборка (один для оборотов, второй для остатков).

5.Выборка по группировкам, итоги.

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

Инструменты

Напильник

То обычная выборка запроса вида:

Выборка = Запрос. Выполнить(). Выбрать();

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

Запрос = Новый Запрос;

Запрос. Текст = "ВЫБРАТЬ Номенклатура.Ссылка КАК Номенклатура ИЗ Справочник.Номенклатура КАК Номенклатура

ИТОГИ ПО Номенклатура ИЕРАРХИЯ";

Выборка = Запрос.Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Сообщить("Элемент=" + ВыборкаДетали. Номенклатура);

КонецЦикла;

КонецЦикла;

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

Запрос = Новый Запрос;

Запрос. Текст = "ВЫБРАТЬ Номенклатура.Ссылка КАК Номенклатура, Номенклатура.Продано КАК Продано

ИЗ Справочник.Номенклатура КАК Номенклатура

ИТОГИ СУММА(Продано)

ПО Номенклатура ИЕРАРХИЯ";

Выборка = Запрос. Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Пока Выборка. Следующий() Цикл

Сообщить("Группа=" + Выборка. Номенклатура+ " Продано=" + Выборка. Продано);

ВыборкаДетали = Выборка.Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Номенклатура" );

Пока ВыборкаДетали. Следующий() Цикл

Сообщить("Элемент=" + ВыборкаДетали. Номенклатура+ " Продано=" + ВыборкаДетали. Продано);

КонецЦикла;

КонецЦикла;

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

Примечание2: для обхода справочника с более сложной структурой (количеством уровней>2) можно воспользоваться рекурсией, например вот так:

……………………..

Выборка = Запрос.Выполнить(). Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);
ВыбратьРекурсивно(Выборка);

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

Процедура ВыбратьРекурсивно(Выборка)

Пока Выборка.Следующий() Цикл

Сообщить(Выборка. Номенклатура+ " колво=" + Выборка. Продано);

// Попытка получить дочерние записи

ВыбратьРекурсивно(Выборка. Выбрать(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);
КонецЦикла;
КонецПроцедуры

Примечание3: ещё одно применение иерархической выборки - выгрузка результатов запроса в объект типа Дерево Значений, например так:

ЗначениеВРеквизитФормы(Результат. Выгрузить(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией, "Дерево" );

Дерево = Результат. Выгрузить(ОбходРезультатаЗапроса. ПоГруппировкамСИерархией);

6.Временные таблицы, пакетные запросы .

Ещё одной очень мощной возможностью языка запросов 1С является работа с временными таблицами. По сути, мы результат запроса помещаем во временную таблицу, с которой далее можем работать как с обычной таблицей. Сам запрос становится составным из нескольких запросов, которые выполняются строго последовательно, один (последний) запрос пакета выполняет выборку данных - такой составной запрос называют пакетным запросом. Каждая временная таблица имеет своё имя и т.о. в пакетном запросе может создаваться произвольное количество таблиц. Время жизни временной таблицы ограниченно временем выполнения запроса, как только запрос был выполнен - все временные таблицы уничтожаются, а память занятая хранением данных временных таблиц высвобождается.

Для того чтобы выполнить помещение данных во временную таблицу используется оператор ПОМЕСТИТЬ , который пишется в запросе между операторами ВЫБРАТЬ и ИЗ . Запросы внутри пакетного запроса отделяются друг от друга строками:

////////////////////////////////////////////////////////////

Пример небольшого пакетного запроса выбирающего последний документ продажи «Реализация» (у документа есть табличная часть «Товары», в которой перечислены реализованные товары) для каждой номенклатуры.

Схема пакетного запроса:

в 1 запросе получаем полный перечень продаваемой номенклатуры и максимальную дату продажи для каждой из номенклатур,

во 2 запросе отбираем для каждой номенклатуры из первого запроса документ реализации с датой равной для этой номенклатуры максимальной

ВЫБРАТЬ РелизацияТовары.Номенклатура, МАКСИМУМ(РеализацияТоваровТовары.Ссылка.Дата) КАК Дата

ПОМЕСТИТЬ Даты

ИЗ Документ.Реализация.Товары КАК РеализацияТовары

СГРУППИРОВАТЬ ПО РеализацияТовары.Номенклатура

////////////////////////////////////////////////////////////

ВЫБРАТЬ Даты.Номенклатура, Даты.Дата, МАКСИМУМ(Реализация.Ссылка) КАК Ссылка

ИЗ Даты КАК Даты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.Реализация КАК Реализация

ПО Даты.Дата = Реализация.Дата

СГРУППИРОВАТЬ ПО Реализация.Ссылка

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

7.Последовательность чисел, дат.

Задача: генерация числовой последовательности от 0 до 959 в запросе. При использовании пакетного запроса задача решается легко:

ВЫБРАТЬ Цифры.Поле1 КАК Цифра

ПОМЕСТИТЬ Цифры

ИЗ (ВЫБРАТЬ 1 КАК Поле1

ОБЪЕДИНИТЬ ВЫБРАТЬ 2

ОБЪЕДИНИТЬ ВЫБРАТЬ 3

ОБЪЕДИНИТЬ ВЫБРАТЬ 4

ОБЪЕДИНИТЬ ВЫБРАТЬ 5

ОБЪЕДИНИТЬ ВЫБРАТЬ 6

ОБЪЕДИНИТЬ ВЫБРАТЬ 7

ОБЪЕДИНИТЬ ВЫБРАТЬ 8

ОБЪЕДИНИТЬ ВЫБРАТЬ 9

ОБЪЕДИНИТЬ ВЫБРАТЬ 10) КАК Цифры

ВЫБРАТЬ (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100 КАК Число

ГДЕ (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100 <= 959

УПОРЯДОЧИТЬ ПО Число

Задача : генерация последовательности дат от Дата1 до Дата2 . Решается аналогично, можно как выполнить в 3 шага (первый и второй как в приведённом примере, но результат не выбрать а поместить во временную таблицу) или в 2 шага изменив второй запрос пакета на вот такой:

ВЫБРАТЬ ДОБАВИТЬКДАТЕ (&Дата1 , ДЕНЬ , (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100) КАК Дата

ИЗ Цифры КАК Цифры, Цифры КАК Цифры1, Цифры КАК Цифры2

ГДЕ ДОБАВИТЬКДАТЕ (&Дата1 , ДЕНЬ , (Цифры.Цифра- 1) + (Цифры1.Цифра - 1)* 10+ (Цифры2.Цифра - 1)* 100)

УПОРЯДОЧИТЬ ПО Дата

Примечание: естественно этот запрос будет правильно работать только если между датами Дата1 и Дата2 не более 999 дней.

8.Использование данных из таблицы значений в запросе.

Если в первом разделе (оператор В ) мы производим сравнение набора полей с данными из Таблицы значений, то иногда этого мало. Например, из стороннего источника передаются наборы данных, например такие: штрих-код и количество единиц проданной продукции. Можно конечно в запросе обойти переданный набор значений выполняя на каждой итерации цикла запрос, но это наихудший вариант решения этой задачи. Правильнее сделать так:

1.Создать типизированную Таблицу значений (т.е. у которой указан тип для каждого поля).

2.Заполнить Таблицу значений полученными данными о продажах.

3.Произвести поиск номенклатуры в запросе.

Пример кода для 1 и 3 этапа:

Создание типизированной Таблицы значений:

// Создание описателей типов для таблицы значений

КЧК = Новый КвалификаторыЧисла(14, 3);

КЧШК = Новый КвалификаторыЧисла(13, 0);

Массив = Новый Массив;

Массив. Добавить(Тип("Число" ));

ОписаниеТиповЧК = Новый ОписаниеТипов(Массив, КЧК);

Массив. Очистить();

Массив. Добавить(Тип(" Число"));

ОписаниеТиповЧШ = Новый ОписаниеТипов(Массив, КЧШК);

// Создание таблицы значений

ТаблицаЗначений = Новый ТаблицаЗначений;

// добавим в таблицу значений две колонки

ТаблицаЗначений. Колонки.Добавить("ШтрихКод" , ОписаниеТиповЧШ, "ШтрихКод" , 13); ТаблицаЗначений. Колонки. Добавить("Продано" , ОписаниеТиповЧК, "Продано" , 14);

Поиск Номенклатуры в запросе:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ТЗ.ШтрихКод, ТЗ.Количество

ПОМЕСТИТЬ ТЗ

ИЗ &ТЗ КАК ТЗ

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ ТЗ.Количество КАК ОбъемПродаж, Номенклатура.Ссылка КАК Ссылка

ИЗ ТЗ КАК ТЗ

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура

ПО ТЗ.ШтрихКод = Номенклатура.ШтрихКод";

Запрос. УстановитьПараметр("ТЗ" , ТаблицаЗначений);

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

Важно! Если параметр функции имеет тип Строка и в нем указывается имя поля, которое содержит пробелы, то такое имя поля должно быть заключено в квадратные скобки.
Например: "[Количество Оборот]".

1. Сумма (Total) - рассчитывает сумму значений выражений, переданных ей в качестве аргумента для всех детальных записей. В качестве параметра можно передавать Массив. В этом случае функция будет применена к содержимому массива.

Пример :
Сумма(Продажи.СуммаОборот)

2. Количество (Count) - рассчитывает количество значений отличных от значения NULL. В качестве параметра можно передавать Массив. В этом случае функция будет применена к содержимому массива.

Синтаксис :
Количество([Различные] Параметр)

В указания получения различных значений следует перед параметром метода Количество указать Различные (Distinct).

Пример :
Количество(Продажи.Контрагент)
Количество(Различные Продажи.Контрагент)

3. Максимум (Maximum) - получает максимальное значение. В качестве параметра можно передавать Массив. В этом случае функция будет применена к содержимому массива.

Пример :
Максимум(Остатки.Количество)

4. Минимум (Minimum) - получает минимальное значение. В качестве параметра можно передавать Массив. В этом случае функция будет применена к содержимому массива.

Пример :
Минимум(Остатки.Количество)

5. Среднее (Average) - получает среднее значение для значений, отличных от NULL. В качестве параметра можно передавать Массив. В этом случае функция будет применена к содержимому массива.

Пример :
Среднее(Остатки.Количество)

6. Массив (Array) - формирует массив, содержащий для каждой детальной записи значение параметра.

Синтаксис :
Массив([Различные] Выражение)

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

Пример :
Массив(Контрагент)

7. ТаблицаЗначений (ValueTable) - формирует таблицу значений, содержащую столько колонок, сколько параметров у функции. Детальные записи получаются из наборов данных, которые нужны для получения всех полей, участвующих в выражениях параметров функции.

Синтаксис :
ТаблицаЗначений([Различные] Выражение1 [КАК ИмяКолонки1][, Выражение2 [КАК ИмяКолонки2],...])

Если параметрами функции выступают поля–остатки, то в результирующую таблицу значений попадут значения для записей по уникальным комбинациям измерений из других периодов. При этом значения получаются только для полей-остатков, измерений, счетов, полей периодов и их реквизитов. Значениями остальных полей в записях из других периодов считаются равными NULL. Если выражение содержит функцию ТаблицаЗначений, то считается, что данное выражение является агрегатным. Если указано ключевое слово Различные, то в получаемой таблице значений не будет строк, содержащих одинаковые данные. После каждого параметра может располагаться необязательное ключевое слово КАК и имя, которое будет назначено колонке таблицы значений.

Пример :
ТаблицаЗначений(Различные Номенклатура, ХарактеристикаНоменклатуры КАК Характеристика)

8. Свернуть (GroupBy) - предназначена для удаления дубликатов из массива.

Синтаксис :
Свернуть(Выражение, НомераКолонок)

Параметры :

  • Выражение - выражение типа Массив или ТаблицаЗначений, значения элементов которого нужно свернуть;
  • НомераКолонок - (если выражение имеет тип ТаблицаЗначений) тип Строка. Номера или имена (через запятую) колонок таблицы значений, среди которых нужно искать дубликаты. По умолчанию – все колонки.
Пример :
Свернуть(ТаблицаЗначений(НомерТелефона, Адрес) ,"НомерТелефона");

9. ПолучитьЧасть (GetPart) - получает таблицу значений, содержащую определенные колонки из исходной таблицы значений.

Синтаксис :
ПолучитьЧасть(Выражение, НомераКолонок)

Параметры :

  • Выражение - тип ТаблицаЗначений. Таблица значений, из которой нужно получить колонки;
  • НомераКолонок - тип Строка. Номера или имена (через запятую) колонок таблицы значений, которые нужно получить.
Возвращаемое значение: ТаблицаЗначений, в которой имеются только колонки, которые указаные в параметре.

Пример :
ПолучитьЧасть(Свернуть(ТаблицаЗначений(НомерТелефона, Адрес) ,"НомерТелефона"),"НомерТелефона");

10. Упорядочить (Order) - предназначена для упорядочивания элементов массива и таблицы значений.

Синтаксис :
Упорядочить(Выражение, НомераКолонок)

Параметры :

  • Выражение - Массив или ТаблицаЗначений, из которой нужно получить колонки;
  • НомераКолонок - (если выражение имеет тип ТаблицаЗначений) номера или имена (через запятую) колонок таблицы значений, по которым нужно упорядочить. Может содержать направление упорядочивания и необходимость автоупорядочивания: Убыв/Возр + Автоупорядочивание.
Возвращаемое значение: Массив или ТаблицаЗначений, с упорядоченными элементами.

Пример :
Упорядочить(ТаблицаЗначений(НомерТелефона, Адрес, ДатаЗвонка),"ДатаЗвонка Убыв");

11. СоединитьСтроки (JoinStrings) - предназначена для объединения строк в одну строку.

Синтаксис :
СоединитьСтроки (Значение, РазделительЭлементов, РазделителиКолонок)

Параметры :

  • Значение - выражения, которые нужно объединить в одну строку. Если является Массивом, то в строку будут объединяться элементы массива. Если является ТаблицаЗначений, то в строку будут объединяться все колонки и строки таблицы;
  • РазделительЭлементов - строка, содержащая текст, который нужно использовать в качестве разделителя между элементами массива и строками таблицы значений. По умолчанию – символ перевода строк;
  • РазделителиКолонок - строка, содержащая текст, который нужно использовать в качестве разделителя между колонками таблицы значений. По умолчанию "; ".
Пример :
СоединитьСтроки(ТаблицаЗначений(НомерТелефона, Адрес));

12. ГрупповаяОбработка (GroupProcessing) - возвращает объект ДанныеГрупповойОбработкиКомпоновкиДанных. В объект в свойство Данные помещается в виде таблицы значений значения группировок для каждого выражения, указанного в параметре функции Выражения. В случае использования иерархической группировки каждый уровень иерархии обрабатывается отдельно. Значения для иерархических записей также помещаются в данные. В свойство ТекущийЭлемент объекта помещается строка таблицы значений, для которой в настоящий момент вычисляется функция.

Синтаксис :
ГрупповаяОбработка(Выражения, ВыраженияИерархии, ИмяГруппировки)

Параметры :

  • Выражения . Выражения, которые нужно вычислить. Строка, в которой через запятую перечислены выражения, которые нужно вычислить. После каждого выражение возможно наличие необязательного ключевого слова КАК и имени колонки результирующей таблицы значений. Каждое выражение образует колонку таблицы значений свойства Данные объекта ДанныеГрупповойОбработкиКомпоновкиДанных.
  • ВыраженияИерархии . Выражения, которые нужно вычислить для иерархических записей. Аналогично параметру Выражения с тем отличием, что параметр ВыраженияИерархии используется для иерархических записей. Если параметр не указан, то для вычисления значений для иерархических записей используется выражения, указанные в параметре Выражение.
  • ИмяГруппировки . Имя группировки, в которой нужно вычислять группировку обработки. Строка. Если не указано, то вычисление происходит в текущей группировке. Если вычисление идет в таблице и параметр содержит пустую строку, или не указан, то значение вычисляется для группировки – строки. Компоновщик макета при генерации макета компоновки данных заменяет данное имя на имя группировки в результирующем макете. Если группировка не доступна, то функция будет заменена на значение NULL.
13. Каждый (Every) - если хоть одна запись имеет значение Ложь, то результат Ложь, иначе Истина.

Синтаксис :
Каждый(Выражение)

Параметр :

  • Выражение - тип Булево.
Пример :
Каждый()

14. Любой (Any) - если хоть одна запись имеет значение Истина, то результат Истина, иначе Ложь

Синтаксис :
Любой(Выражение)

Параметр :

  • Выражение - тип Булево.
Пример :
Любой()

15. СтандартноеОтклонениеГенеральнойСовокупности (Stddev_Pop) - вычисляет стандартное отклонение совокупности. Вычисляется по формуле: SQRT(ДисперсияГенеральнойСовокупности(X)).

Синтаксис :
СтандартноеОтклонениеГенеральнойСовокупности(Выражение)

Параметр :

  • Выражение - тип Число.

Пример :

X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ СтандартноеОтклонениеГенеральнойСовокупности(Y) ИЗ Таблица
Результат: 805.694444

16. СтандартноеОтклонениеВыборки (Stddev_Samp) - вычисляет совокупное типовое стандартное отклонение. Вычисляется по формуле: SQRT(ДисперсияВыборки(X)).

Синтаксис :
СтандартноеОтклонениеВыборки(Выражение)

Параметр :

  • Выражение - тип Число.
Тип возвращаемого значения Число.

Пример :

X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ СтандартноеОтклонениеВыборки(Y) ИЗ Таблица
Результат: 28.3847573

17. ДисперсияВыборки (Var_Samp) - вычисляет типовое различие ряда чисел без учета значений NULL в этом наборе. Вычисляется по формуле: (Сумма(X^2) - Сумма(X)^2 / Количество(X)) / (Количество(X) - 1). Если Количество(X) = 1, то возвращается значение NULL.

Синтаксис :
ДисперсияВыборки(Выражение)

Параметр :

  • Выражение - тип Число.
Пример :
ВЫБРАТЬ ДисперсияГенеральнойСовокупности(Y) ИЗ Таблица
Результат: 716.17284

19. КовариацияГенеральнойСовокупности (Covar_Pop) - вычисляет ковариацию ряда числовых пар. Вычисляется по формуле: (Сумма(Y * X) - Сумма(X) * Сумма(Y) / n) / n, где n число пар (Y, X) в которых ни Y ни X не являются NULL.

Синтаксис :
КовариацияГенеральнойСовокупности(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ КовариацияГенеральнойСовокупности(Y, X) ИЗ Таблица
Результат: 59.4444444

20. КовариацияВыборки (Covar_Samp) - вычисляет типовое различие ряда чисел без учета значений NULL в этом наборе. Вычисляется по формуле: (Сумма(Y * X) - Сумма(Y) * Сумма(X) / n) / (n-1), где n число пар (Y, X) в которых ни Y ни X не являются NULL.

Синтаксис :
КовариацияВыборки(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ КовариацияВыборки(Y, X) ИЗ Таблица
Результат: 66.875

21. Корреляция (Corr) - вычисляет коэффициент корреляции ряда числовых пар. Вычисляется по формуле: КовариацияГенеральнойСовокупности(Y, X) / (СтандартноеОтклонениеГенеральнойСовокупности(Y) * СтандартноеОтклонениеГенеральнойСовокупности(X)). Не учитываются пары, в которых Y или X равны NULL.

Синтаксис :
Корреляция(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ Корреляция(X, Y) ИЗ Таблица
Результат: 0.860296149

22. РегрессияНаклон (Regr_Slope) - вычисляет наклон линии. Вычисляется по формуле: КовариацияГенеральнойСовокупности(Y, X) / ДисперсияГенеральнойСовокупности(X). Вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияНаклон(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ РегрессияНаклон(Y, X) ИЗ Таблица
Результат: 8.91666667

23. РегрессияОтрезок (Regr_Intercept) - вычисляет Y-точку пересечения линии регресса. Вычисляется по формуле: Среднее(Y) - РегрессияНаклон(Y, X) * Среднее(X). Вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияОтрезок(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
ВЫБРАТЬ РегрессияКоличество(Y, X) ИЗ Таблица
Результат: 9

25. РегрессияR2 (Regr_R2) - вычисляет коэффициент детерминации. Вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияR2(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Возвращаемое значение:
  • Null - если ДисперсияГенеральнойСовокупности(X) = 0;
  • 1 - если ДисперсияГенеральнойСовокупности(Y)=0 И ДисперсияГенеральнойСовокупности(X)<>0;
  • POW(Корреляция(Y,X),2) - если ДисперсияГенеральнойСовокупности(Y)>0 И ДисперсияГенеральнойСовокупности(X)<>0.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ РегрессияR2(Y, X) ИЗ Таблица
Результат: 0.740109464

26. РегрессияСреднееX (Regr_AvgX) - вычисляет среднее число X после исключения X и Y пар, где или X или Y являются пустыми. Среднее(X) вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияСреднееX(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ РегрессияСреднееX(Y, X) ИЗ Таблица
Результат: 5

27. РегрессияСреднееY (Regr_AvgY) - вычисляет среднее число Y после исключения X и Y пар, где или X или Y являются пустыми. Среднее(Y) вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияСреднееY(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ РегрессияСреднееY(Y, X) ИЗ Таблица
Результат: 24.2222222

28. РегрессияSXX (Regr_SXX) - вычисляется по формуле: РегрессияКоличество(Y, X) * ДисперсияГенеральнойСовокупности(X). Вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияSXX(Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Возвращает сумму квадратов независимых выражений, используемых в линейной модели регресса. Функция может использоваться, чтобы оценить статистическую обоснованность модели регресса.

Пример :
ВЫБРАТЬ РегрессияSYY(Y, X) ИЗ Таблица
Результат: 6445.55556

30. РегрессияSXY (Regr_SXY) - вычисляется по формуле: РегрессияКоличество(Y, X) * КовариацияГенеральнойСовокупности(Y, X). Вычисляется без учета пар, содержащих NULL.

Синтаксис :
РегрессияSXY (Y, X)

Параметры :

  • Y - тип Число;
  • X - тип Число.
Пример :
X 1 2 3 4 5 6 7 8 9
Y 7 1 2 5 7 34 32 43 87
ВЫБРАТЬ РегрессияSXY(Y, X) ИЗ Таблица
Результат: 535

31. МестоВПорядке (Rank)

Синтаксис :
МестоВПорядке(Порядок, ПорядокИеррахии, ИмяГруппировки)

Параметры :

  • Порядок – тип Строка. Содержит выражения, в последовательности которых нужно расположить групповые записи, разделенные через запятую. Направление упорядочивания управляется при помощи слов Возр, Убыв. После поля также можно указать строку Автоупорядочивание, что обозначает, что при упорядочивании ссылок нужно использовать поля упорядочивания, определенные для объекта, на который ссылка. Если последовательность не указана, то значение рассчитывается в последовательности группировки;
  • ПорядокИеррахии – тип Строка. Содержит выражения упорядочивания для иерархических записей;
  • ИмяГруппировки – тип Строка. Имя группировки, в которой нужно вычислять группировку обработки. Если не указано, то вычисление происходит в текущей группировке. Если вычисление идет в таблице и параметр содержит пустую строку, или не указан, то значение вычисляется для группировки – строки. Компоновщик макета при генерации макета компоновки данных заменяет данное имя на имя группировки в результирующем макете. Если группировка не доступна, то функция будет заменена на значение NULL.
Если в последовательности имеются две или более записей с одинаковыми значениями полей упорядочивания, то для всех записей функция возвращает одинаковые значения.

Пример :
МестоВПорядке("[Количество Оборот]")

32. КлассификацияABC (ClassificationABC)

Синтаксис :
КлассификацияABC(Значение, КоличествоГрупп, ПроцентыДляГрупп, ИмяГруппировки)

Параметры :

  • Значение – тип Строка. по которому нужно рассчитывать классификацию. Строка, в которой указано выражение;
  • КоличествоГрупп - тип Число. Задает количество групп, на который нужно разбить;
  • ПроцентыДляГрупп - тип Строка. Столько, на сколько групп нужно разбить минус 1. Через запятую. Если не задано, то автоматически;
  • ИмяГруппировки - тип Строка. Имя группировки, в которой нужно вычислять группировку обработки. Если не указано, то вычисление происходит в текущей группировке. Если вычисление идет в таблице и параметр содержит пустую строку, или не указан, то значение вычисляется для группировки – строки. Компоновщик макета при генерации макета компоновки данных заменяет данное имя на имя группировки в результирующем макете. Если группировка не доступна, то функция будет заменена на значение NULL.
Результатом работы функции будет номер класса, начиная с 1, который соответствует классу A.

Пример :
КлассификацияABC("Сумма(ВаловаяПрибыль)", 3, "60, 90")

Решил внести свою лепту и описать те особенности языка, которые не были рассмотрены в приведенных выше статьях. Статья ориентирована на начинающих разработчиков.

1. Конструкция "ИЗ".

Для того, чтобы получить данные из базы совсем необязательно использовать конструкцию "ИЗ".
Пример: Нам необходимо выбрать все сведения о банках из справочника банки.
Запрос:

ВЫБРАТЬ Справочник.Банки.*

Выбирает все поля из справочника Банки. И является аналогичным запросу:

ВЫБРАТЬ Банки.* ИЗ Справочник.Банки КАК Банки

2. Упорядочивание данных по ссылочному полю

Когда нам необходимо упорядочить данные запроса по примитивным типам: "Строка", "Число", "Дата" и т.д., то все решается использованием конструкции "УПОРЯДОЧИТЬ ПО", если вам необходимо упорядочить данные по ссылочному полю? Ссылочное поле представляет из себя ссылку, уникальный идентификатор, т.е. грубо говоря некий произвольный набор символов и обычное упорядочивание может выдать не совсем ожидаемый результат. Для упорядочивания ссылочным полей используется конструкция "АВТОУПОРЯДОЧИВАНИЕ". Для этого необходимо сначала упорядочить данные непосредственно по ссылочному типу конструкцией "УПОРЯДОЧИТЬ ПО", а затем конструкция "АВТОУПОРЯДОЧИВАНИЕ".

В этом случае для документов упорядочивание будет происходить в порядке "Дата->Номер" , для справочников по "Основному представлению". Если упорядочивание происходит не по ссылочным полям, то использовать конструкцию "АВТОУПОРЯДОЧИВАНИЕ" не рекомендуется.

В некоторых случаях конструкция "АВТОУПОРЯДОЧИВАНИЕ" может замедлять процесс выборки. Аналогичным образом можно переписать без автоупорядочивания для документов:

3.Получение текстового представления ссылочного типа. Конструкция "ПРЕДСТАВЛЕНИЕ".

Когда вам необходимо вывести для показа поле ссылочного типа, например поле "Банк", которое является ссылкой на элемент справочника "Банки", то необходимо понимать, что при выводе этого поля автоматически выполнится подзапрос к справочнику "Банки", чтобы получить представление справочника. Это будет замедлять вывод данных. Для Того, чтобы этого избежать необходимо использовать конструкцию "ПРЕДСТАВЛЕНИЕ" в запросе, чтобы сразу получить представление объекта и уже его выводить для просмотра.

В система компоновки данных этот механизм используется по умолчанию, а вот при формировании макетов в ячейках следует указывать представление ссылочного поля, а например в расшифровку помещать саму ссылку.

4. Условие на выборку данных по шаблону.

Например, вам необходимо получить мобильные телефоны сотрудников вида (8 -123- 456-78-912). Для этого необходимо поставить такое условие в запросе:

ВЫБРАТЬ Сорудник.Наименование, Сорудник.Телефон КАК Телефон ИЗ Справочник.Сотрудники КАК Сотрудники ГДЕ Телефон ПОДОБНО "_-___-___-__-__"

Символ "_" является служебным и заменяет любой символ.

5. Одновременное использование итогов и группировок.


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

ВЫБРАТЬ ОказаниеУслуг.Организация КАК Организация, ОказаниеУслуг.Номенклатура КАК Номенклатура, СУММА(ОказаниеУслуг.СуммаДокумента) КАК СуммаДокумента ИЗ Документ.ОказаниеУслуг КАК ОказаниеУслуг СГРУППИРОВАТЬ ПО ОказаниеУслуг.Организация, ОказаниеУслуг.Номенклатура ИТОГИ ПО ОБЩИЕ, Организация, Номенклатура

В этом случае запрос вернет практически тоже самое что и такой запрос:

ВЫБРАТЬ ОказаниеУслуг.Организация КАК Организация, ОказаниеУслуг.Номенклатура КАК Номенклатура, ОказаниеУслуг.СуммаДокумента КАК СуммаДокумента ИЗ Документ.ОказаниеУслуг КАК ОказаниеУслуг ИТОГИ СУММА(СуммаДокумента) ПО ОБЩИЕ, Организация, Номенклатура

Только первый запрос свернет записи с одинаковой номенклатурой.

6. Разыменование полей.

Обращение к полям через точку называется операцией разыменования ссылочного поля. Например Оплата.Организация.АдминистративнаяЕдиница . В этом случае в ссылочном поле "Организация" документа "Оплата", ссылается на другую таблицу "Организации", в которой будет получено значение реквизита "АдминистративнаяЕдиница". Важно понимать, что при обращении к полям через точку платформа неявно создает подзапрос и соединяет эти таблицы.

Запрос:

Можно представить в виде:

ВЫБРАТЬ Оплата.Ссылка, Оплата.Организация, Оплата.Организация, Организации. АдминистративнаяЕдиница ИЗ Документ.Оплата КАК Оплата ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организации КАК Организации ПО Оплата.Организация = Организации.Ссылка

При разыменовании ссылочных полей составного типа платформа пытается создать неявные соединения со всеми таблицами, которые входят в тип этого поля. В этом случае запрос будет неоптимален.Если четко известно, какого типа поле, необходимо ограничивать такие поля по типу конструкцией ВЫРАЗИТЬ() .

Например имеется регистр накопления "Нераспределенные оплаты", где регистратором могут выступать несколько документов. В этом случае неверно получать значения реквизитов регистратора таким образом:

ВЫБРАТЬ НераспределенныеОплаты.Регистратор.Дата, ..... ИЗ РегистрНакопления.НераспределеныеОплаты КАК НераспределенныеОплаты

следует ограничить тип составного поля регистратор:

ВЫБРАТЬ ВЫРАЗИТЬ(НераспределенныеОплаты.Регистратор КАК Документ.Оплата).Дата, ..... ИЗ РегистрНакопления.НераспределеныеОплаты КАК НераспределенныеОплаты

7. Конструкция "ГДЕ"

При левом соединении двух таблиц, когда вы накладываете условие "ГДЕ" на правую таблицу то мы получим результат аналогичный результату при внутреннем соединении таблиц.

Пример. Необходимо выбрать всех Клиентов из Справочника клиенты и для тех клиентов, у которых имеется документ оплата со значением реквизита "Организация" = &Организация вывести документ "Оплата", для тех у кого нет, не выводить.

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

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

Можно обойти это условие и другим способом. необходимо наложить условие "ГДЕ" непосредственно в связи двух таблиц. Пример:

ВЫБРАТЬ Клиенты.Ссылка, Оплата.Ссылка ИЗ Справочник.УС_Абоненты КАК УС_Абоненты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО (Клиенты.Ссылка = Оплата.Клиент И Оплата.Клиент.Наименование ПОДОБНО "Сахарный Пакет") СГРУППИРОВАТЬ ПО Клиенты.Ссылка, Оплата.Ссылка

8. Соединения с Вложенными и Виртуальными таблицами

Вложенные запросы зачастую необходимы для выборки данных по какому-либо условию. Если же потом использовать их в соединении с другими таблицами то это может критически замедлить выполнение запроса.

Для примера нам необходимо для некоторых клиентов получить Сумму остатка на текущую дату.

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

При выполнении такого запроса, вероятны ошибки оптимизатора СУБД при выборе плана, что приведет к неоптимальному выполнению запроса. При соединении двух таблиц оптимизатор СУБД выбирает алгоритм соединения таблиц исходя из количества записей в обеих таблицах. В случае наличия вложенного запроса, определить количество записей, которое вернет вложенный запрос крайне сложно. Поэтому вместо вложенных запросов всегда стоит использовать временные таблицы. Поэтому перепишем запрос.

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

В данном случае оптимизатор сможет определить, какое количество записей использует временная таблица тКлиенты и сможет подобрать оптимальный алгоритм соединения таблиц.

Виртуальные таблицы , позволяют получить практически готовые данные для большинства прикладных задач.(СрезПервых,СрезПоследних,Остатки,Обороты,ОстаткиИОбороты) Ключевое слово здесь виртуальные. Эти таблицы не являются физическими, а компонуются системой налету, т.е. при получении данных из виртуальных таблиц система собирает данные из итоговых таблиц регистров, компонует, группирует и выдает пользователю.

Т.е. при соединении с виртуальной таблицей происходит соединение с подзапросом. В этом случае оптимизатор СУБД может также выбрать неоптимальный план соединения. Если запрос формируется недостаточно быстро и в запросе испольуются соединения в виртуальными таблицами, то реклмендуется вынести обращение к виртуальным таблицам во временную таблицу, а затем в произвести соедининие между двумя временными таблицами. Перепишем предыдущий запрос.

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

9.Проверка результата выполнения запроса.

Результат выполнения запроса может быть пустым, для проверки на пустые значения следует использовать конструкцию:

РезЗапроса = Запрос.Выполнить(); Если резЗапроса.Пустой() Тогда Возврат; КонецЕсли;

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

Ни для кого не является открытием то, что запросы в цикле использовать крайне нежелательно. Это может критически сказаться на времени работы той или иной функции. Очень желательно получать все данные в запросе и уже потом обрабатывать данные в цикле. Но иногда бывают случаи, когда вынести запрос за пределы цикла становится невозможным. В этом случае для оптимизации можно вынести создание запроса за пределы цикла, а в цикле подставлять необходимые параметры и выполнять запрос.

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

Это избавит систему от синтаксической проверки запроса в цикле.

11. Конструкция "ИМЕЮЩИЕ".

Конструкция, довольно редко встречающаяся в запросах. Позволяет накладывать условия на значения агрегатные функций (СУММА, МИНИМУМ, СРЕДНЕЕ и т.д.). Например, вам необходимо выбрать только тех клиентов, у которых сумма оплат в сентябре была больше 13 000 рублей. Если использовать условие "ГДЕ", то придется сначала создавать временную таблицу или вложенный запрос, там группировать записи по сумме оплаты и потом накладывать условие. Конструкция "ИМЕЮЩИЕ" поможет этого избежать.

ВЫБРАТЬ Оплата.Клиент, СУММА(Оплата.Сумма) КАК Сумма ИЗ Документ.Оплата КАК Оплата ГДЕ МЕСЯЦ(Оплата.Дата) = 9 СГРУППИРОВАТЬ ПО Оплата.Клиент ИМЕЮЩИЕ СУММА(Оплата.Сумма) > 13000

В конструкторе для этого достаточно перейти на вкладку "Условия", добавить новое условие и поставить галочку на "Произвольное". Далее просто написать Сумма(Оплата.Сумма) > 13000


12. Значение NULL

Я не буду описывать здесь принципы трехзначной логики в БД, есть множество статей на эту тему. Просто вкратце о том как NULL может повлиять на результат запроса. Значение NULL на самом деле не значение, а факт того, что значение не определено, неизвестно. Поэтому любые операции с NULL возвращают NULL, будь то сложение, вычитание, деление или сравнение. Значение NULL не может быть сравнимо со значением NULL, потому как мы не знаем, что именно сравнивать. Т.е. оба этих сравнения: NULL = NULL, NULL<>NULL - это не Истина или не Ложь, это неизвестно.

Давайте рассмотрим пример.

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

ВЫБРАТЬ "Нет оплат" КАК Признак, NULL КАК Документ ПОМЕСТИТЬ тОплаты; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Клиенты.Ссылка КАК Клиент, Оплата.Ссылка КАК Оплата ПОМЕСТИТЬ тКлиентОплата ИЗ Справочник.Клиенты КАК Клиенты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО Клиенты.Ссылка = Оплата.Пайщик; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиентОплата.Клиент ИЗ тКлиентОплата КАК тКлиентОплата ВНУТРЕННЕЕ СОЕДИНЕНИЕ тОплаты КАК тОплаты ПО тКлиентОплата.Оплата = тОплаты.Документ

Обратите внимание на вторую временную таблицу тКлиентОплата. Левым соединением я выбираю всех клиентов и все оплаты по этим клиентам. Для тех же клиентов у которых нет оплат в поле "Оплата" будет NULL . Следуя логике, в первой временной таблице "тОплаты" я обозначил 2 поля, одно из них NULL, второе строка "Не имеет оплат". В третьей таблице я соединяю внутренним соединением таблицы "тКлиентОплата" и "тОплаты" по полям "Оплата" и "Документ". Мы знаем, что в первой таблице поле "Документ" это NULL, и во второй таблице у тех, у кого нет оплат в поле "Оплата" тоже NULL. Что же вернет нам такое соединение? А ничего не вернет. Потому как сравнение NULL = NULL не принимает значение Истина.

Для того, чтобы запрос вернул нам ожидаемый результат, перепишем его:

ВЫБРАТЬ "Нет оплат" КАК Признак, ЗНАЧЕНИЕ(Документ.Оплата.ПустаяСсылка) КАК Документ ПОМЕСТИТЬ тОплаты; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Клиенты.Ссылка КАК Клиент, ЕСТЬNULL(Оплата.Ссылка, ЗНАЧЕНИЕ(Документ.Оплата.ПустаяСсылка)) КАК Оплата ПОМЕСТИТЬ тКлиентОплата ИЗ Справочник.Клиенты КАК Клиенты ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплата ПО Клиенты.Ссылка = Оплата.Пайщик; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ тКлиентОплата.Клиент ИЗ тКлиентОплата КАК тКлиентОплата ВНУТРЕННЕЕ СОЕДИНЕНИЕ тОплаты КАК тОплаты ПО тКлиентОплата.Оплата = тОплаты.Документ

Теперь, во второй временной таблице, мы указали, что в случае, если поле "Оплата" есть NULL, тогда это поле = пустая ссылка на документ оплата. В Первой таблице мы также заменили NULL на пустую ссылку. Теперь в соединении участвуют не NULL поля и запрос вернет нам ожидаемый результат.

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

13. Недокументированная особенность конструкции "ВЫБОР КОГДА...ТОГДА....КОНЕЦ".

В том случае, когда необходимо описывать в запросе контрукцию "Условия", то мы используем стандартный синтаксис:

ВЫБРАТЬ ВЫБОР КОГДА Пользователи.Наименование = "Вася Пупкин" ТОГДА "Наш любимый сотрудник" ИНАЧЕ "Не знаем такого" КОНЕЦ КАК Поле1 ИЗ Справочник.Пользователи КАК Пользователи

А что делать, если, к примеру, нам надо получить название месяца в запросе? Писать огромную конструкцию в запросе некрасиво и долго, поэтому нас может выручить такая форма записи выше:

ВЫБОР МЕСЯЦ(УС_РасчетПотребления_ГрафикОбороты.ПериодРасчета) КОГДА 1 ТОГДА "Январь" КОГДА 2 ТОГДА "Февраль" КОГДА 3 ТОГДА "Март" КОГДА 4 ТОГДА "Апрель" КОГДА 5 ТОГДА "Май" КОГДА 6 ТОГДА "Июнь" КОГДА 7 ТОГДА "Июль" КОГДА 8 ТОГДА "Август" КОГДА 9 ТОГДА "Сентябрь" КОГДА 10 ТОГДА "Октябрь" КОГДА 11 ТОГДА "Ноябрь" КОГДА 12 ТОГДА "Декабрь" КОНЕЦ КАК Месяц

Теперь конструкция выглядит не такой громоздкой и легко воспринимается.

14. Пакетное выполнение запроса.


Для того, чтобы не плодить запросы, можно создать один большой запрос, разбить его на пакеты и работать уже с ним.
Например, мне нужно получить из справочника "Пользователи" поля: "ДатаРождения" и доступные роли для каждого пользователя. в выгрузить это в разные табличные части на форме. Конечно можно сделать это в одном запросе, тогда придется перебирать записи или сворачивать, а можно так:

ВЫБРАТЬ Пользователи.Ссылка КАК ФИО, Пользователи.ДатаРождения, Пользователи.Роль ПОМЕСТИТЬ втПользователи ИЗ Справочник.Пользователи КАК Пользователи; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втПользователи.ФИО, втПользователи.ДатаРождения ИЗ втПользователи КАК втПользователи СГРУППИРОВАТЬ ПО втПользователи.ФИО, втПользователи.ДатаРождения; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ втПользователи.ФИО, втПользователи.Роль ИЗ втПользователи КАК втПользователи СГРУППИРОВАТЬ ПО втПользователи.ФИО, втПользователи.ДатаРождения

тПакет = Запрос.ВыполнитьПакет();

ТП_ДатыРождения = тПакет.Выгрузить();
ТП_Роли = тПакет.Выгрузить();

Как мы видим, запрос можно выполнить в пакете и работать с результатом как с массивом. В некоторых случаях очень удобно.

15. Условия в пакетном запросе

Например, у нас есть пакетный запрос, где сначало мы получаем поля: "Наименование, ДатаРождения, Код" из справочника "Пользователи" и хотим из справочника "ФизЛица" получить записи с условием по этим полям.

ВЫБРАТЬ Пользователи.ФизЛицо.Наименование КАК Наименование, Пользователи.ФизЛицо.ДатаРождения КАК ДатаРождения, Пользователи.ФизЛицо.Код КАК Код ПОМЕСТИТЬ втПользователи ИЗ Справочник.Пользователи КАК Пользователи; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ФизическиеЛица.Ссылка КАК ФизЛицо ИЗ Справочник.ФизическиеЛица КАК ФизическиеЛица

Можно накложить условия таким образом:

ГДЕ ФизическиеЛица.Код В (ВЫБРАТЬ втПользователи.Код ИЗ втПользователи) И ФизическиеЛица.Наименование В (ВЫБРАТЬ втПользователи.Код ИЗ втПользователи) И ФизическиеЛица.ДатаРождения В (ВЫБРАТЬ втПользователи.ДатаРождения ИЗ втПользователи)

А Можно и так:

ГДЕ (ФизическиеЛица.Код, ФизическиеЛица.Наименование, ФизическиеЛица.ДатаРождения) В (ВЫБРАТЬ втПользователи.Код, втПользователи.Наименование, втПользователи.ДатаРождения ИЗ втПользователи)

Причем обязателено соблюдать порядок.

16. Вызов конструктора запросов для "условия" в пакетном запросе

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

Необходимо после Конструкции "В" поставить скобки и между скобками оставить пустое место(пробел), выделить это место и вызвать контруктор запросов. Контруктору будут доступны все таблицы пакетного запроса. Прием работает как на виртуальных таблицах регистров, так и для вкладки "Условия". В последнем случае необходимо поставить галочку "П(произволное условие)" и войти в режим редактирования "F4".

Запросов зачастую выдумывал на ходу и они служат просто для отображения "приемов", которые я рассматривал.

Хотел рассмотреть использование индексов в запросах, но больно обширная тема. Вынесу в отдельную статью, либо позже добавлю здесь.

upd1. Пункты 11,12
upd2. Пункты 13,14,15,16

Используемая литература:
Язык запросов "1С:Предприятия 8" - Е.Ю. Хрусталева
Профессиональная разработка в системе 1С:Предприятие 8".

← Вернуться

×
Вступай в сообщество «passport13.com»!
ВКонтакте:
Я уже подписан на сообщество «passport13.com»