Язык запросов в 1С 8 — это упрощенный аналог широко известного «структурированного языка программирования» (как чаще его называют, SQL). Но в 1С он используется только для чтения данных, для изменения данных применяется объектная модель данных.
Еще одно интересное отличие – русский синтаксис. Хотя на самом деле Вы можете использовать и англоязычные конструкции.
Пример запроса:
ВЫБРАТЬ
Банки.Наименование,
Банки.КоррСчет
ИЗ
Справочник.Банки КАК Банки
Данный запрос позволит увидеть нам информацию о наименовании и корреспондентском счете всех существующих в базе данных банков.
Язык запросов – самой простой и эффективный способ получения информации. Как видно из примера выше, в языке запросов нужно апеллировать именами метаданных ( – это список объектов системы, из которых состоит конфигурация, т.е справочники, документы, регистры и т.д.).
Описание конструкций языка запросов
Структура запросов
Для получения данных достаточно использовать конструкции «ВЫБРАТЬ» (select) и «ИЗ» (from). Простейший запрос выглядит следующим образом:
ВЫБРАТЬ * ИЗ Справочники.Номенклатура
Где «*» означает выбор всех полей таблицы, а Справочники.Номенклатура – имя таблицы в базе данных.
Рассмотрим более сложный и общий пример:
ВЫБРАТЬ
<ИмяПоля1> КАК <ПредставлениеПоля1>,
Сумма(<ИмяПоля2>) КАК <ПредставлениеПоля2>
ИЗ
<ИмяТаблицы1> КАК <ПредставлениеТаблицы1>
<ТипСоединения> СОЕДИНЕНИЕ <ИмяТаблицы2> КАК <ПредставлениеТаблицы2>
ПО <УсловиеСоединениеТаблиц>ГДЕ
<УсловиеОтбораДанных>СГРУППИРОВАТЬ ПО
<ИмяПоля1>УПОРЯДОЧИТЬ ПО
<ИмяПоля1>ИТОГИ
<ИмяПоля2>
ПО
<ИмяПоля1>
В данном запросе мы выбираем данные полей «ИмяПоля1» и «ИмяПоля1» из таблиц «ИмяТаблицы1» и «ИмяТаблицы», присваиваем полям синонимы с помощью оператора «КАК», соединяем их по некому условию «УсловиеСоединениеТаблиц».
Из полученных данных мы отбираем только данные, соответствующие условию из «ГДЕ» «УсловиеОтбораДанных».Далее мы группируем запрос по полю «ИмяПоля1», при этом суммируя «ИмяПоля2».Создаём итоги по полю «ИмяПоля1» и итоговым полем «ИмяПоля2».
Последним действием мы сортируем запрос с помощью конструкции «УПОРЯДОЧИТЬ ПО».
Общие конструкции
Рассмотрим общие конструкции языка запросов 1С 8.2.
ПЕРВЫЕ n
С помощью данного оператора можно получить n количество первых записей. Порядок записей определяется порядком в запросе.
ВЫБРАТЬ ПЕРВЫЕ 100
Банки.Наименование,
Банки.Код КАК БИК
ИЗ
Справочник.Банки КАК Банки
УПОРЯДОЧИТЬ ПО
Банки.Наименование
Запросом будет получено первых 100 записей справочника «Банки», упорядоченных по алфавиту.
РАЗРЕШЕННЫЕ
Эта конструкция актуальна для работы с механизмом . Суть механизма в ограничении чтения (и других действий) пользователям для конкретных записей в таблице базы данных, а не таблицы в целом.
Если пользователь пытается с помощью запроса прочитать записи недоступные ему, он получит сообщение об ошибке. Чтобы этого избежать, следует использовать конструкцию «РАЗРЕШЕННЫЕ», т.е запрос будет читать только разрешенные ему записи.
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ХранилищеДополнительнойИнформации.Ссылка
ИЗ
Справочник.ХранилищеДополнительнойИнформации
РАЗЛИЧНЫЕ
Использование «РАЗЛИЧНЫЕ» позволит исключить попадание строк-дублей в результат запроса 1С. Дублирование означает совпадение всех полей запроса.
ВЫБРАТЬ ПЕРВЫЕ 100
Банки.Наименование,
Банки.Код КАК БИК
ИЗ
Справочник.Банки КАК Банки
ПустаяТаблица
Данная конструкция используется очень редко для объединения запросов. При объединении может возникнуть необходимость указать в одной из таблиц пустую вложенную таблицу. Для этого как раз подойдет оператор «ПустаяТаблица»
Пример из справки 1С 8:
ВЫБРАТЬ Ссылка.Номер, ПУСТАЯТАБЛИЦА.(Ном, Тов, Кол) КАК Состав
ИЗ Документ.РасхНакл
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ Ссылка.Номер, Состав.(НомерСтроки, Товар, Количество)
ИЗ Документ.РасхНакл Документ.РасходнаяНакладная.Состав.*
ЕСТЬNULL
Очень полезная функция, которая позволяет избежать многих ошибок. ЕстьNULL() позволяет заменить значение NULL на нужное. Очень часто используется в проверках на наличие значения в присоединенных таблицах, например:
ВЫБРАТЬ
НоменклатураСпр.Ссылка,
ЕстьNULL(ОстаткиТовара.КоличествоОстаток,0) КАК КоличествоОстаток
ИЗ
Можно использовать и по-другому. Например, если для каждой строки не известно, в какой таблице существует значение:
ЕСТЬNULL(СчетФактураПолученный.Дата, СчетФактураВыданный.Дата)
КАК – оператор, который позволяет нам присвоить имя (синоним) таблицы или полю. Пример использования мы видели выше.
Данные конструкции очень похожи – они позволяют получить строковое представление нужного значения. Единственное отличие в том, что ПРЕДСТАВЛЕНИЕ преобразует любые значения в строковый тип, а ПРЕДСТАВЛЕНИЕССЫЛКИ — только ссылочные. ПРЕДСТАВЛЕНИЕССЫЛКИ рекомендуется применять в запросах системы компоновки данных для оптимизации, если, конечно, поле ссылочных данных не планируется использовать в отборах .
ВЫБРАТЬ
Представление(Ссылка), //строка, например «Авансовый отчет №123 от 10.10.2015
Представление(ПометкаУдаления) КАК ПометкаУдаленияТекст, //строка, «Да» или «Нет»
ПредставлениеСсылки(ПометкаУдаления) КАК ПометкаУдаленияБулево //булево, Истина или Ложь
ИЗ
Документ.АвансовыйОтчет
ВЫРАЗИТЬ
Выразить позволяет преобразовать значения поля к нужному типу данных. Можно преобразовать значение как к примитивному типу, так и к ссылочному типу.
Выразить для ссылочного типа используется для ограничения запрашиваемых типов данных в полях составного типа, часто используется для оптимизации работы системы. Пример:
ВЫРАЗИТЬ(ТаблицаЗатрат.Субконто1 КАК Справочник.СтатьиЗатрат).ВидДеятельностиДляНалоговогоУчетаЗатрат
Для примитивных типов эта функция часто используется для ограничения количества символов в полях неограниченной длины (с такими полями нельзя сравнивать). Чтобы избежать ошибки «Неверные параметры в операции сравнения. Нельзя сравнивать поля
неограниченной длины и поля несовместимых типов
», необходимо выразить такие поля следующим образом:
ВЫРАЗИТЬ(Комментарий КАК Строка(150))
РАЗНОСТЬДАТ
Получите 267 видеоуроков по 1С бесплатно:
Пример использования ЕСТЬ NULL в запросе 1С:
ВЫБРАТЬ * ИЗ
Спр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ОстаткиТовара
ПО НоменклатураСпр.Ссылка = РеализованныеТоварыКомитентовОстатки.Номенклатура
ГДЕ НЕ ОстаткиТовара.КоличествоОстаток ЕСТЬ NULL
Тип данных в запросе можно определить следующим образом: с помощью функций ТИП() и ТИПЗНАЧЕНИЯ() или с помощью логического оператора ССЫЛКА. Эти две функции аналогичны.
Предопределенные значения
Помимо использования в запросах переданных параметров в языке запросов 1С можно использовать предопределенные значения или . Например, перечисления, предопределенные справочники, планы счетов и так далее.Для этого используется конструкция «Значение()».
Пример использования:
ГДЕ Номенклатура.ВидНоменклатуры = Значение(Справочник.ВидыНоменклатуры.Товар)
ГДЕ Контрагенты.ВидКонтактнойИнформации = Значение(Перечисление.ВидыКонтактнойИнформации.Телефон)
ГДЕ ОстаткиПоСчетам.СчетУчета = Значение(ПланСчетов.Хозрасчетный.ПрибылиУбытки)
Соединения
Соединения бывают 4 типов: ЛЕВОЕ , ПРАВОЕ , ПОЛНОЕ, ВНУТРЕННЕЕ .
ЛЕВОЕ и ПРАВОЕ СОЕДИНЕНИЕ
Соединения используются для связи двух таблиц по определенному условию. Особенность при ЛЕВОМ СОЕДИНЕНИИ в том, что мы берём первую указанную таблицу полностью и привязываем по условию вторую таблицу. Поля второй таблицы, которые не удалось привязать по условию, заполняются значением NULL .
Например:
Вернет всю таблицу Контрагентов и заполнит поле “Банк” лишь в тех местах, где будет соблюдаться условие “Контрагенты.Наименование = Банки.Наименование”. Если условие не соблюдается, в поле Банк будет установлено NULL .
ПРАВОЕ СОЕДИНЕНИЕ в языке 1С абсолютно аналогично ЛЕВОМУ соединению , за исключением одного отличия – в ПРАВОМ СОЕДИНЕНИИ “главная” таблица – вторая, а не первая.
ПОЛНОЕ СОЕДИНЕНИЕ
ПОЛНОЕ СОЕДИНЕНИЕ отличается от левого и правого тем, что выводит все записи из двух таблиц, соединяет лишь те, которые может соединить по условию.
Например:
ИЗ
ПОЛНОЕ СОЕДИНЕНИЕ
Справочник.Банки КАК БанкиПО
Язык запросов вернет обе таблицы полностью лишь по выполненному условию соединить записи. В отличие от левого/правого соединения возможно появления NULL в двух полях.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
ВНУТРЕННЕЕ СОЕДИНЕНИЕ отличается от полного тем, что выводит только те записи, которые смогли соединить по заданному условию.
Например:
ИЗ
Справочник.Контрагенты КАК КлиентыВНУТРЕННЕЕ СОЕДИНЕНИЕ
Справочник.Банки КАК БанкиПО
Клиенты.Наименование = Банки.Наименование
Данный запрос вернет только строки, в которых у банка и контрагента будет одинаковое наименование.
Объединения
Конструкция ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ объединяет два результата в один. Т.е. результат выполнения двух будет «слит» в один, общий.
Т.е система работает точно так же, как и обычные , только для временной таблицы.
Как использовать ИНДЕКСИРОВАТЬ ПО
Однако следует учесть один момент. Построение индекса временной таблицы также требует времени на выполнение. Поэтому целесообразно использовать конструкцию ” ”, только если точно известно, что во временной таблице будет не 1-2 записи. В противном случае эффект может быть обратным – быстродействие от индексированных полей не компенсирует времени построения индекса.
ВЫБРАТЬ
КурсыВалютСрезПоследних.Валюта КАК Валюта,
КурсыВалютСрезПоследних.Курс
ПОМЕСТИТЬ КурсыВалют
ИЗ
РегистрСведений.КурсыВалют.СрезПоследних(&Период,) КАК КурсыВалютСрезПоследних
ИНДЕКСИРОВАТЬ ПО
Валюта
;
ВЫБРАТЬ
ЦеныНоменклатуры.Номенклатура,
ЦеныНоменклатуры.Цена,
ЦеныНоменклатуры.Валюта,
КурсыВалют.Курс
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период,
Номенклатура В (&Номенклатура) И ТипЦен = &ТипЦен) КАК ЦеныНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ КурсыВалют КАК КурсыВалют
ПО ЦеныНоменклатуры.Валюта = КурсыВалют.Валюта
Группировка
Язык запросов 1С позволяет использовать специальные агрегатные функции при группировке результатов запросов. Группировку можно также использовать без агрегатных функций, для «устранения» дублей.
Существуют следующие функции:
Сумма, Количество, Количество разных, Максимум, Минимум, Среднее.
Пример №1:
ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура,
СУММА(РеализацияТоваровУслугТовары.Количество) КАК Количество,
СУММА(РеализацияТоваровУслугТовары.Сумма) КАК Сумма
ИЗ
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслугТовары.Номенклатура
Запрос получает все строки с товарами и суммирует их по количеству и суммам в разрезе номенклатуры.
Пример №2
ВЫБРАТЬ
Банки.Код,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Банки.Ссылка) КАК КоличествоДублей
ИЗ
Справочник.Банки КАК Банки
СГРУППИРОВАТЬ ПО
Банки.Код
Данный пример отобразит список БИКов справочника «Банки» и покажет, сколько дублей существует по каждому из них.
Итоги
Итоги – способ получения данных из системы с иерархической структурой. Для итоговых полей могут использоваться агрегатные функции, как для группировок.
Один из самых популярных способов использования итогов в практике – партионное списание товаров.
ВЫБРАТЬ
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО
ИТОГИ
СУММА(Количество),
СУММА(Сумма)
ПО
Номенклатура
В результате запроса получится следующее иерархическое :
Общие итоги
Если необходимо получить итоги по всем «итогам», используйте оператор «ОБЩИЕ».
ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
РеализацияТоваровУслугТовары.Ссылка КАК Документ,
РеализацияТоваровУслугТовары.Количество КАК Количество,
РеализацияТоваровУслугТовары.Сумма КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
УПОРЯДОЧИТЬ ПО
РеализацияТоваровУслугТовары.Ссылка.Дата
ИТОГИ
СУММА(Количество),
СУММА(Сумма)
ПО
ОБЩИЕ,
Номенклатура
В результате выполнения запроса получим следующий результат:
В котором 1 уровень группировки – агрегирование всех нужных полей.
Упорядочивание
Оператор УПОРЯДОЧИТЬ ПО используется для сортировки результата запроса.
Сортировка для примитивных типов (строка, число, булево) происходит по обычным правилам. Для полей ссылочных типов сортировка происходит по внутреннему представлению ссылки (уникальный идентификатор), а не по коду или по представлению ссылки.
ВЫБРАТЬ
ИЗ
Справочник.Номенклатура КАК Номенклатура
УПОРЯДОЧИТЬ ПО
Наименование
Запрос выведет список наименований справочника номенклатуры, отсортированного по алфавиту.
Автоупорядочивание
Результат запроса без сортировки представляет собой хаотично представленный набор строк. Разработчики платформы 1С не гарантируют вывод строк в одинаковой последовательности при выполнении одинаковых запросов.
Если необходимо выводить записи таблицы в постоянном порядке, необходимо использовать конструкцию «Автоупорядочивание».
ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
АВТОУПОРЯДОЧИВАНИЕ
Виртуальные таблицы
Виртуальные таблицы в 1С – это уникальная особенность языка запросов 1С, которой нет в других аналогичных синтаксисах. Виртуальная таблица – быстрый способ получения профильной информации из регистров.
Для каждого из типов регистров свой набор виртуальных таблиц, который может отличаться в зависимости от настроек регистра.
- срез первых;
- срез последних.
- остатки;
- обороты;
- остатки и обороты.
- движения с субконто;
- обороты;
- обороты Дт Кт;
- остатки;
- остатки и обороты
- субконто.
- база;
- данные графика;
- фактический период действия.
Для разработчика решения данные берутся из одной (виртуальной) таблицы, но на самом деле платформа 1С берёт из множества таблиц, преобразуя их в нужных вид.
ВЫБРАТЬ
ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток,
ТоварыНаСкладахОстаткиИОбороты.КоличествоОборот,
ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход,
ТоварыНаСкладахОстаткиИОбороты.КоличествоРасход,
ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты КАК ТоварыНаСкладахОстаткиИОборотыТакой запрос позволяет быстро получить большое количество данных.
Параметры виртуальных таблиц
Очень важный аспект работы с виртуальными таблицами – использование параметров. Параметры виртуальных таблиц – специализированные параметры для отбора и настройки.
Для таких таблиц считается неверным использования отбора в конструкции «ГДЕ». Помимо того, что запрос становится не оптимальным, возможно получение неверных данных.
Пример использования таких параметров:
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Месяц, ДвиженияИГраницыПериода, Номенклатура = &НужнаяНоменклатура)
Алгоритм работы виртуальных таблиц
Например, наиболее используемая виртуальная таблица типа «Остатки» хранит данные двух физических таблиц – остатков и движений.
При использовании виртуальной таблицы система проделывает следующие манипуляции:
- Получаем ближайшее по дате и измерениям рассчитанное значение в таблице итогов.
- «Прибавляем» сумму из таблицы движения к сумме из таблицы итогов.
Такие простые действия могут существенно повысить производительность системы в целом.
Использование конструктора запросов
Конструктор запросов – инструмент, встроенный в систему 1С предприятие, существенно облегчающий разработку запросов к базе данных.
Конструктор запроса имеет достаточно простой, интуитивно понятный интерфейс. Тем не менее рассмотрим применение конструктора запроса подробнее.
Запуск конструктора текста запроса производится контекстным меню (правой кнопкой мыши) в нужном месте программного кода.
Описание конструктора запроса 1С
Рассмотрим каждую вкладку конструктора подробнее. Исключение – вкладка Построитель, это тема для отдельного разговора.
Вкладка Таблицы и поля
На этой вкладке указывается источник данных и поля, которые необходимо выводить в отчет. По сути тут описываются конструкции ВЫБРАТЬ.. ИЗ.
В качестве источника может служить физическая таблица базы данных, виртуальная таблица регистров, временные таблицы, вложенные запросы и т.д.
В контекстном меню виртуальных таблиц можно задать параметры виртуальной таблицы:
Вкладка Связи
Вкладка служит для описания соединений нескольких таблиц, создает конструкции со словом СОЕДИНЕНИЕ.
Вкладка Группировка
На данной вкладке система позволяет группировать и суммировать нужные поля результата таблицы. Описывается использование конструкций СГРУППИРОВАТЬ ПО, СУММА, МИНИМУМ, СРЕДНЕЕ, МАКСИМУМ, КОЛИЧЕСТВО, КОЛИЧЕСТВО РАЗЛИЧНЫХ.
Вкладка Условия
Отвечает за всё, что идёт в тексте запроса после конструкции ГДЕ, т.е за все условия, накладываемые на получаемые данные.
Вкладка Дополнительно
Вкладка Дополнительно изобилует всевозможными параметрами, которые являются очень важными. Рассмотрим каждое из свойств.
Группировка Выборка записей :
- Первые N – параметр, возвращающий в запрос только N записей (оператор ПЕРВЫЕ)
- Без повторяющихся – обеспечивает уникальность полученных записей (оператор РАЗЛИЧНЫЕ)
- Разрешенные – позволяет выбирать только те записи, которые позволяет выбрать система с учетом (конструкция РАЗРЕШЕННЫЕ)
Группировка Тип запроса определяет, какой будет тип запроса: выборка данных, создание временной таблицы или же уничтожение временной таблицы.
Ниже существует флаг Блокировать полученные данные для последующего изменения . Он позволяет включить возможность установки блокировки данных, которая обеспечивает сохранность данных от момента их чтения до изменения (актуально только для Автоматического режима блокировок, конструкция ДЛЯ ИЗМЕНЕНИЯ).
Вкладка Объединения/Псевдонимы
На этой вкладке конструктора запросов устанавливается возможность объединения разных таблиц и псевдонимов(конструкция КАК). В левой части указываются таблицы. Если установить флаги напротив таблицы, будет использоваться конструкция ОБЪЕДИНИТЬ, иначе – ОБЪЕДИНИТЬ ВСЕ (отличия двух способов ). В правой части указываются соответствия полей в разных таблицах, если соответствие не указано, запрос будет возвращать NULL.
Вкладка Порядок
Здесь указывается порядок сортировки значений (УПОРЯДОЧИТЬ ПО) – по убыванию (УБЫВ) или возрастанию(ВОЗР).
Также есть интересный флаг – Автоупорядочивание (в запросе – АВТОУПОРЯДОЧИВАНИЕ). По умолчанию система 1С выводит данные в “хаотичном” порядке. Если установить этот флаг, система будет сортировать данные по внутренним данным.
Вкладка Пакет запросов
На вкладке конструктора запросов можно создавать новые , а также использовать её в роли навигации. В тексте запроса пакеты разделяются символом “;”(точка запятая).
Кнопка “Запрос” в конструкторе запросов
В левом нижнем углу конструктора запроса есть кнопка Запрос, с помощью которого можно в любой момент просмотреть текст запроса:
В данном окне можно внести коррективы в запрос и выполнить его.
Использование консоли запросов
Консоль запросов – простой и удобный способ для отладки сложных запросов и быстрого получения информации. В этой статье я постараюсь описать, как пользоваться консолью запросов, и дам ссылку для скачивания консоли запросов.
Рассмотрим этот инструмент подробнее.
Скачать консоль запросов 1С
Первым делом, чтобы начать работу с консолью запросов, её нужно откуда-то скачать. Обработки обычно делятся на два вида – на управляемых формах и обычных (или, иногда, их называют на 8.1 и на 8.2/8.3).
Я постарался объединить эти два вида в одной обработке – в нужном режиме работы открывается нужная форма (в управляемом режиме консоль работает только в толстом режиме).
Описание консоли запросов 1С
Начнем рассмотрение консоли запросов с описания главной панели обработки:
В шапке консоли запросов можно увидеть время выполнения последнего запроса с точностью до миллисекунды, это позволяет сравнивать разные конструкции по производительности.
Первая группа кнопок в командной панели отвечает за сохранение текущих запросов во внешнем файле. Это очень удобно, Вы всегда сможете вернуться к написанию сложного запроса. Или же, например, хранить список типичных примеров тех или иных конструкций.
Слева, в поле “Запрос”, можно создавать новые запросы и сохранять их в древовидной структуре. Вторая группа кнопок как раз отвечает за управление списком запросов. С помощью неё можно создать, скопировать, удалить, переместить запрос.
- Выполнить запрос – простое выполнение и получение результата
- Выполнить пакет – позволяет просмотреть все промежуточные запросы в пакете запросов
- Просмотр временных таблиц – позволяет увидеть результаты, которые возвращают временные запросы в таблице
Параметры запроса:
Позволяют установить текущие параметры для запроса.
В окне параметров запроса интересно следующее:
- Кнопка Получить из запроса автоматически находит все параметры в запросе для удобства разработчика.
- Флаг Единые параметры для всех запросов – при установке его обработка не очищает параметры при переходе от запроса к запросу в общем списке запросов.
Задать параметр списком значений очень просто, достаточно при выборе значения параметра нажать на кнопку очистки значения (крестик), система предложит выбрать тип данных, где надо выбрать “Список значения”:
Также в верхней панели очень есть кнопка вызова настроек консоли запросов:
Здесь можно указать параметры автосохранения запросов и параметры выполнения запроса.
В поле запроса консоли заносится текст запроса. Сделать это можно простым набором теста запроса или же вызовом специального инструмента – конструктора запросов.
Конструктор запроса 1С 8 вызывается из контекстного меню (правая кнопка мыши) при нажатии на поле ввода:
Также в этом меню есть такие полезные функции, как очистка или добавление в запрос символов переноса строки (“|”) или же получения кода запроса вот в таком удобном виде:
Запрос = Новый Запрос;
Запрос.Текст = ”
|ВЫБРАТЬ
| Валюты.Ссылка
|ИЗ
| Справочник.Валюты КАК Валюты”;
РезультатЗапроса = Запрос.Выполнить();
В нижнем поле консоли запросов отображается поле результата запроса, ради чего и создана эта обработка:
Также консоль запросов кроме списка умеет отображать данные в виде дерева — для запросов, содержащих итоги.
Оптимизация запросов
Одним из важнейших пунктов в повышении производительности работы 1С предприятия 8.3 является оптимизация запросов . Этот пункт также очень важен при сдаче аттестации . Ниже пойдет речь о типичных причинах не оптимальной работы запросов и способах из оптимизации.
Отборы в виртуальной таблице с помощью конструкции ГДЕ
Накладывать фильтры на реквизиты виртуальной таблицы необходимо только через параметры ВТ. Ни в коем случае для отбора в виртуальной таблице нельзя использовать конструкцию ГДЕ, это грубейшая ошибка с точки зрения оптимизации. В случае с отбором с помощью ГДЕ по факту система получит ВСЕ записи и только потом отберет нужные.
ПРАВИЛЬНО :
ВЫБРАТЬ
ИЗ
РегистрНакопления.ВзаиморасчетыСДепонентамиОрганизаций.Остатки(
,
Организация = &Организация
И Физлицо = &Физлицо) КАК ВзаиморасчетыСДепонентамиОрганизацийОстатки
НЕПРАВИЛЬНО :
ВЫБРАТЬ
ВзаиморасчетыСДепонентамиОрганизацийОстатки.СуммаОстаток
ИЗ
РегистрНакопления.ВзаиморасчетыСДепонентамиОрганизаций.Остатки(,) КАК ВзаиморасчетыСДепонентамиОрганизацийОстатки
ГДЕ
ВзаиморасчетыСДепонентамиОрганизацийОстатки.Организация = &Организация
И ВзаиморасчетыСДепонентамиОрганизацийОстатки.Физлицо = &Физлицо
Получение значения поля составного типа через точку
При получении данных составного типа в запросе через точку система соединяет левым соединением ровно столько таблиц, сколько типов возможно в поле составного типа.
Например, крайне нежелательно для оптимизации обращаться к полю записи регистра – регистратор. Регистратор имеет составной тип данных, среди которых все возможные типы документов, которые могут писать данные в регистр.
НЕПРАВИЛЬНО:
ВЫБРАТЬ
НаборЗаписей.Регистратор.Дата,
НаборЗаписей.Количество
ИЗ
РегистрНакопления.ТоварыОрганизации КАК НаборЗаписей
Т.е по факту вот такой запрос будет обращаться не к одной таблице, а к 22 таблицам базы данных (у этого регистра 21 тип регистратора).
ПРАВИЛЬНО:
ВЫБРАТЬ
ВЫБОР
КОГДА ТоварыОрг.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыОрг.Регистратор КАК Документ.РеализацияТоваровУслуг).Дата
КОГДА ТоварыОрг.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг
ТОГДА ВЫРАЗИТЬ(ТоварыОрг.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Дата
КОНЕЦ КАК Дата,
ТоварыОрг.Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрг
Либо второй вариант – добавление такой информации в реквизит, например, в нашем случае – добавление даты.
ПРАВИЛЬНО:
ВЫБРАТЬ
ТоварыОрганизаций.Дата,
ТоварыОрганизаций.Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций
Подзапросы в условии соединения
Для оптимизации недопустимо использовать подзапросы в условиях соединения, это существенно замедляет работу запроса. Желательно в таких случаях использовать ВТ. Для соединения нужно использовать только объекты метаданных и ВТ, предварительно проиндексировав их по полям соединения.
НЕПРАВИЛЬНО:
ВЫБРАТЬ …
ЛЕВОЕ СОЕДИНЕНИЕ (
ВЫБРАТЬ ИЗ РегистрСведений.Лимиты
ГДЕ …
СГРУППИРОВАТЬ ПО …
) ПО …
ПРАВИЛЬНО:
ВЫБРАТЬ …
ПОМЕСТИТЬ Лимиты
ИЗ РегистрСведений.Лимиты
ГДЕ …
СГРУППИРОВАТЬ ПО …
ИНДЕКСИРОВАТЬ ПО …;ВЫБРАТЬ …
ИЗ Документ.РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ Лимиты
ПО …;
Соединение записей с виртуальными таблицами
Бывают ситуации, когда при соединении виртуальной таблицы с другими система работает не оптимально. В таком случае для оптимизации работы запроса можно попробовать поместить виртуальную таблицу во временную, не забыв проиндексировать соединяемые поля в запросе временной таблицы. Связано это с тем, что ВТ часто содержатся в нескольких физических таблицах СУБД, в итоге для их выборки составляется подзапрос, и проблема получается аналогичной предыдущему пункту.
Использование отборов по не индексируемым полям
Одна из самых распространенных ошибок при составления запросов – использование условий по не индексируемым полям, это противоречитправилам оптимизации запросов. СУБД не может выполнить запрос оптимально, если в запросе накладывается отбор по неиндексируемым полям. Если же берется временная таблица – также необходимо индексировать поля соединения.
Обязательно для каждого условия должен существовать подходящий индекс. Подходящим является индекс, удовлетворяющий следующим требованиям:
- Индекс содержит все поля, перечисленные в условии.
- Эти поля находятся в самом начале индекса.
- Эти отборы идут подряд, то есть между ними не «вклиниваются» значения, не участвующие в условии запроса.
Если СУБД не подобрал правильные индексы, то будет просканирована таблица полностью – это очень негативно скажется на производительности и может привести к продолжительной блокировке всего набора записей.
Использование логического ИЛИ в условиях
Вот и всё, в данной статье были освещены основы аспекты оптимизации запросов, которые должен знать каждый эксперт 1С.
Очень полезный бесплатный видеокурс по разработке и оптимизации запросов, категорически рекомендую новичкам и не только!
В языке запросов 1С:Предприятия функция ПОДСТРОКА() в формате ПОДСТРОКА(<Исходная строка>, <Начало>, <Длина>) может применяться к данным строкового типа и позволяет выделить фрагмент <Исходной строки>, начинающийся с символа номер <Начало> (символы в строке нумеруются с 1) и длиной <Длина> символов. Результат вычисления функции ПОДСТРОКА() имеет строковый тип переменной длины, причем длина будет считаться неограниченной, если <Исходная строка> имеет неограниченную длину и параметр <Длина> не является константой или превышает 1024.
Вычисление функции ПОДСТРОКА() на SQL сервере:
В клиент-серверном варианте работы функция ПОДСТРОКА() реализуется при помощи функции SUBSTRING() соответствующего оператора SQL, передаваемого серверу баз данных SQL Server, который вычисляет тип результата функции SUBSTRING() по сложным правилам в зависимости от типа и значений ее параметров, а так же в зависимости от контекста, в котором она используется.
В большинстве случаев эти правила не оказывают влияния на выполнение запроса 1С:Предприятия, однако есть случаи, когда для исполнения запроса существенна максимальная длина строки результата, вычисленная SQL Server. Важно иметь в виду, что в некоторых контекстах использования функции ПОДСТРОКА() максимальная длина ее результата может оказаться равной максимальной длине строки ограниченной длины, которая в SQL Server равна 4000 символам. Это может привести к неожиданному аварийному завершению выполнения запроса.
Например, запрос:
Код 1C v 8.х
ВЫБРАТЬ
ВЫБОР
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
ВЫБОР
КОГДА Вид = &ЮрАдресФизЛица
ТОГДА ПОДСТРОКА(Представление, 0, 200)
ИНАЧЕ NULL
КОНЕЦ КАК Представление1
ИЗ
УПОРЯДОЧИТЬ ПО
Представление,
Представление1
завершается аварийно с сообщением Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Warning: The query processor could not produce a query plan from the optimizer because the total length of all the columns in the GROUP BY or ORDER BY clause exceeds 8000 bytes.
HRESULT=80040E14, SQLSTATE=42000, native=8618
Это происходит потому, что вычисленная Microsoft SQL Server максимальная длина строки, которая является результатом выражения:
Код 1C v 8.х
ВЫБОР
КОГДА Вид = &ЮрАдресФизЛица
ТОГДА ПОДСТРОКА(Представление, 0, 200)
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
равна 4000 символов. Поэтому длина записи, состоящей из двух таких полей превышает 8000 байт, разрешенные для выполнения операции сортировки.
В связи с описанной особенностью исполнения функции SUBSTRING() на SQL Server использование функции ПОДСТРОКА() с целью приведения строк неограниченной длины к строкам ограниченной длины не рекомендуется. Вместо нее лучше использовать операцию приведения типа ВЫРАЗИТЬ(). В частности, приведенный пример можно переписать в виде:
Код 1C v 8.х
ВЫБРАТЬ
ВЫБОР
КОГДА Вид = &ЮрАдресФизЛица
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
ВЫБОР
КОГДА Вид = &ЮрАдресФизЛица
ТОГДА ВЫРАЗИТЬ(Представление КАК Строка(200))
ИНАЧЕ NULL
КОНЕЦ КАК Представление1
ИЗ
РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
УПОРЯДОЧИТЬ ПО
Представление,
Представление1
Тип «Строка» встречается во всех языках программирования. Он является примитивным, и в 1С существует много функций для работы с ним. В данной статье мы подробно рассмотрим различные способы работы со строковыми типами в 1С 8.3 и 8.2 на примерах.
Строка
Для того чтобы преобразовать переменную какого-либо типа в строку, существует одноименная функция «Строка()». Входным параметром будет сама переменная, строковое представление которой необходимо получить.
Строка(Ложь) // возвращает «Нет»
Строка(12345) // возвращает «12 345»
Строка(ТекущаяДата()) //»21.07.2017 11:55:36″
Преобразовывать к строке возможно не только примитивные типы, но и остальные, например элементы справочников, документов.
СокрЛП, СокрЛ, СокрП
В качестве входных параметров данных функций выступает переменная строкового типа. Функции удаляют незначащие символы (пробелы, переносы каретки и прочие): с левой и правой стороны, только с левой стороны, и только с правой соответственно.
СокрЛП(» Будут удалены пробелы с обеих сторон «) // «Будут удалены пробелы с обеих сторон»
СокрЛ(» Будут удалены пробелы с обеих сторон «) // «Будут удалены пробелы слева »
СокрП(» Будут удалены пробелы с обеих сторон «) // « Будут удалены пробелы справа»
Лев, Прав, Сред
Данные функции позволяют обрезать часть строки. Функция «Лев()» вернет часть строки с ее левой стороны указанной длины. Функция «Прав()» аналогично, но обрезка производится справа. Функция «Сред()» позволяет указать номер символа, с которого будет выделена строка и ее длину.
Лев(«Строковая переменная», 4) // возвращает «Стро»
Прав(«Строковая переменная», 7) // возвращает «еременная»
Сред(«Строковая переменная», 2, 5)// возвращает «троко»
СтрДлина
Функция определяет количество символов, которые содержатся в строковой переменной.
СтрДлина(«Слово «) // результатом выполнения будет число 5
Найти
Функция дает возможность искать в какой-либо строковой переменной часть строки. В качестве возвращаемого значения будет выступать число, которое показывает позицию начала найденной строки. Если совпадений не обнаружено, возвращается ноль.
Обратите внимание, что поиск производится с учетом регистра. Если в изначальной строке будет больше одного вхождения подстроки поиска, функция вернет начало первого вхождения.
Найти(«раз, два, раз, два, три», «два») // функция вернет число 6
ПустаяСтрока
Использование данной функции позволяет определить, является ли строка пустой. Незначимые символы, например, пробел, перенос каретки и другие не учитываются.
ПустаяСтрока(«Пупкин Василий Иванович») // функция вернет значение Ложь
ПустаяСтрока(» «) // функция вернет значение Истина
ВРег, НРег, ТРег
Данные функции очень полезны при сравнении и преобразовании строковых переменных. «Врег()» вернет исходную строку в верхнем регистре, «НРег()» в нижнем, а «ТРег()» отформатирует ее так, что первый символ каждого отдельного слова будет с большой буквы, а все последующие с маленькой.
ВРег(«ГеНераЛьныЙ дИРЕктОр») // возвращаемое значение – «ГЕНЕРАЛЬНЫЙ ДИРЕКТОР»
НРег(«ГеНераЛьныЙ дИРЕктОр») // возвращаемое значение – «генеральный директор»
ТРег(«ГеНераЛьныЙ дИРЕктОр») // возвращаемое значение – «Генеральный Директор»
СтрЗаменить
Данная функция является аналогом замены в текстовых редакторах. Она позволяет подменять один символ или набор символов другим в строковых переменных.
СтрЗаменить(«красный, белый, желтый», «,», «;») // вернет «красный; белый; желтый»
СтрЧислоСтрок
Функция позволяет определить количество строк, разделенных переносом каретке в текстовой переменной.
Цикл, в приведенном ниже примере, пройдет три круга, так как функция СтрЧислоСтрок вернет значение 3:
Для инд=1 по СтрЧислоСтрок(«Строка1» + Символы.ПС + «Строка2» + Символы.ПС + «Строка3») Цикл
<тело цикла>
КонецЦикла;
СтрПолучитьСтроку
Данная функция работает с многострочным текстом так же, как и предыдущая. Она позволяет получить определенную строку из текстовой переменной.
СтрПолучитьСтроку(«Строка1» + Символы.ПС + «Строка2» + Символы.ПС + «Строка3», 2) // вернет «Строка2»
СтрЧислоВхождений
Функция подсчитывает количество вхождений символа или подстроки в искомой строке.
СтрЧислоВложений(«а;б;в;г; «, «;») // функция вернет число 4
Символ и КодСимвола
Эти функции позволяют получать символ по его коду в кодировке Unicode, а так же определять этот код по самому символу.
КодСимвола(«А») // функция вернет число 1 040
КодСимвола(1040) // функция вернет «А»
Частые задачи при работе со строками
Объединение строк
Чтобы объединить несколько строк (произвести конкатенацию) достаточно использовать оператор сложения.
«Строка 1″ + » Строка 2″ //результатом сложения двух строк будет «Строка 1 Строка 2»
Преобразование типов
Для того, чтобы преобразовать тип в строку, например, ссылку на элемент справочника, число и прочее, достаточно использовать функцию «Строка()». Функции, подобные «СокрЛП()» так же будут преобразовывать переменные в строку, но уже сразу с отсечением незначащих символов.
Строка(1000) // вернет «1 000»
Обратите внимание, что при преобразовании числа в строку, программа автоматически добавила пробел, отделяющий тысячу. Для того чтобы этого избежать можно воспользоваться следующими конструкциями:
СтрЗаменить(Строка(1000),Символы.НПП,»») // вернет «1000»
Строка(Формат(1000,»ЧГ=»)) // вернет «1000»
Кавычки в строке
Довольно часто вам придется сталкиваться с необходимостью указать в строковой переменной кавычки. Это может быть как текст запроса, написанный в конфигураторе, так и просто переменная. Для решения данной задачи вам достаточно установить два символа кавычек.
Заголовок = Строка(«ООО «»Рога и копыта»» — это мы!») // вернет «ООО «Рога и копыта» — это мы!»
Многострочность, перенос строки
Для того, чтобы создать многострочный текст достаточно добавить в него символы переноса строки (Символы.ПС).
МногострочныйТекст = «Первая строка» + Символы.ПС + «Вторая строка»
Как убрать пробелы
Для того, чтобы убрать пробелы справа или слева можно воспользоваться функцией «СокрЛП()» (а так же «СокрЛ()» и «СокрП()»):
СтрокаБезПробелов = СокрЛП(» Много букв «) // функция вернет значение «Много букв»
Если после преобразования числа в строку вам потребовалось убрать неразрывные пробелы, воспользуйтесь следующей конструкцией:
СтрокаБезПробелов = СтрЗаменить(Строка(99999),Символы.НПП,»») // вернет «99999»
Так же программисты часто пользуются ниже приведенной конструкцией, которая позволяет удалить, либо заменить на другой символ все пробелы текстовой переменной:
СтрокаБезПробелов = СтрЗаменить(« п р и в е т», » » ,»») // вернет «привет»
Сравнение строк между собой
Сравнить сроки можно обычным знаком равенства. При сравнении учитывается регистр.
«Здраствуйте» = «здравствуйте» // вернет Ложь
«Здраствуйте» = «Здравствуйте» // вернет Истина
«Здраствуйте» = «До свидания» // вернет Ложь
Приветсвую вас, уважаемые читатели блога сайт! Сегодня, с помощью примеров, мы рассмотрим, как на практике можно использовать функцию запросов 1С ПОДСТРОКА / SUBSTRING . Использование данной функции пригодится не только в простых запросах, которые мы рассмотрим здесь, но и при и запросов, а также в запросах.
Задача состояла в том, что нужно было из реквизита документа Сответствие выделить две строки и сделать сортировку по ним. Соответствие счета, такого вида: 779000/004599. Как разбить это значение на два?
У функции ПОДСТРОКА три параметра. В качестве первого указывается исходная строка, из которой требуется выделить часть символов — подстроку. Понятно, что тип значения этого параметра — это Строка . Внимание, это очень важное замечание, если использовать тип первого параметра не строку, функция не будет работать, запрос будет выдавать ошибку! Второй параметр определяет позицию символа в исходной строке, с которого начинается выделение части строки, а третий — это длина выделяемой подстроки. Тип значения для второго и третьего параметров — число.
Перейдём к практике:
ВЫБРАТЬ Типовой.Регистратор КАК Название, ПОДСТРОКА (Типовой.Регистратор.Соотв.Наименование, 1, 6) КАК СчетЗатрат, ПОДСТРОКА (Типовой.Регистратор.Соотв.Наименование, 8, 11) КАК Отдел, СУММА(ВЫБОР КОГДА МЕСЯЦ(Типовой.Период) = 3 ТОГДА ВЫРАЗИТЬ(Типовой.Сумма КАК ЧИСЛО(15, 2)) ИНАЧЕ 0 КОНЕЦ) КАК Март ИЗ РегистрБухгалтерии.Типовой КАК Типовой ГДЕ Типовой.СчетКт = &СчетКт И Типовой.Период МЕЖДУ &ПериодНач И &ПериодКон СГРУППИРОВАТЬ ПО ПОДСТРОКА (Типовой.Регистратор.Соотв.Наименование, 1, 6), ПОДСТРОКА (Типовой.Регистратор.Соотв.Наименование, 8, 11), Типовой.Регистратор УПОРЯДОЧИТЬ ПО Отдел, СчетЗатрат
Результат этого запроса следующий:
Название | СчетЗатрат | Отдел | Март |
Платежное поручение исходящее 00000000319 от 01.03.2010 14:42:54 | 779000 | 004599 | 9 000 |
Платежное поручение исходящее 00000000320 от 02.03.2010 12:07:34 | 779000 | 004599 | 4 721,6 |
Платежное поручение исходящее 00000000203 от 01.03.2010 12:28:52 | 786500 | 004599 | 987 614,51 |
Платежное поручение исходящее 00000000227 от 03.03.2010 14:16:00 | 786500 | 004599 | 400 000 |
Платежное поручение исходящее 00000000238 от 05.03.2010 12:37:57 | 732000 | 004600 | 5 400 |
Платежное поручение исходящее 00000000197 от 01.03.2010 11:53:11 | 732500 | 004600 | 12 100 |
Платежное поручение исходящее 00000000198 от 01.03.2010 11:55:39 | 732500 | 004600 | 12 100 |
Платежное поручение исходящее 00000000279 от 26.03.2010 0:00:00 | 734100 | 004600 | 19 609 |
Платежное поручение исходящее 00000000287 от 29.03.2010 14:15:36 | 734100 | 004600 | 55 300 |
Платежное поручение исходящее 00000000291 от 30.03.2010 11:01:10 | 734100 | 004600 | 18 090 |
Платежное поручение исходящее 00000000268 от 18.03.2010 10:34:25 | 738000 | 004600 | 10 050 |
Платежное поручение исходящее 00000000276 от 18.03.2010 12:20:20 | 750400 | 004600 | 13 060,98 |
Платежное поручение исходящее 00000000281 от 29.03.2010 12:33:46 | 750400 | 004600 | 555 645,41 |
Платежное поручение исходящее 00000000234 от 04.03.2010 12:21:55 | 754450 | 004600 | 24 120 |
Платежное поручение исходящее 00000000290 от 30.03.2010 10:44:39 | 754450 | 004600 | 100 000 |
Платежное поручение исходящее 00000000240 от 09.03.2010 10:53:24 | 786300 | 004600 | 20 800 |
Платежное поручение исходящее 00000000269 от 18.03.2010 10:58:04 | 786300 | 004600 | 61 012 |
Платежное поручение исходящее 00000000289 от 30.03.2010 9:27:14 | 786300 | 004600 | 6 000 |
Платежное поручение исходящее 00000000223 от 03.03.2010 12:13:38 | 786500 | 004600 | 36 000 |
Платежное поручение исходящее 00000000228 от 04.03.2010 9:52:35 | 786500 | 004600 | 378 138,85 |
Платежное поручение исходящее 00000000229 от 04.03.2010 9:57:50 | 786503 | 004600 | 126 117,75 |
Платежное поручение исходящее 00000000200 от 01.03.2010 11:58:06 | 754422 | 004762 | 63 000 |
Платежное поручение исходящее 00000000286 от 29.03.2010 14:10:18 | 764422 | 004762 | 10 000 |
Платежное поручение исходящее 00000000267 от 17.03.2010 0:00:00 | 764423 | 004762 | 464 370 |
Платежное поручение исходящее 00000000261 от 15.03.2010 11:16:28 | 764522 | 004762 | 81 357 |
Итак, если мы берём строку 779000/004599, то ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 1, 6) будет выделять строку «779000». А ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 8, 11) будет выводить «004599».
В этом же запросе, используется выражение:
СУММА(ВЫБОР КОГДА МЕСЯЦ(Типовой.Период) = 3 ТОГДА ВЫРАЗИТЬ(Типовой.Сумма КАК ЧИСЛО(15, 2)) ИНАЧЕ 0 КОНЕЦ) КАК Март
В этой же задаче необходимо было добавить новые колонки с названиями месяцев и с суммами по ним. Как раз это выражение решает эту задачу. Если Вам нужно использовать другие месяца, например январь, то заменим выражение:
СУММА(ВЫБОР КОГДА МЕСЯЦ(Типовой.Период) = 1 ТОГДА ВЫРАЗИТЬ(Типовой.Сумма КАК ЧИСЛО(15, 2)) ИНАЧЕ 0 КОНЕЦ) КАК Январь
Приведу пример текста запроса, в котором с помощью цикла формируются поля месяцев (выделено жирным), начиная с марта по февраль.
ТекстЗапроса = " |ВЫБРАТЬ |Типовой.Регистратор КАК Название, |ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 1, 6) КАК СчетЗатрат, |ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 8, 11) КАК Отдел,"; Для Сч = 1 По 12 Цикл Если Сч < 11 Тогда Мес = Сч + 2; Иначе Мес = Сч - 10; КонецЕсли; ТекстЗапроса = ТекстЗапроса + " |СУММА(ВЫБОР | КОГДА МЕСЯЦ(Типовой.Период) = " + Мес + " | ТОГДА ВЫРАЗИТЬ(Типовой.Сумма КАК ЧИСЛО(15, 2)) | ИНАЧЕ 0 |КОНЕЦ) КАК Поле" + Мес + ?(Сч=12,"",","); КонецЦикла; ТекстЗапроса = ТекстЗапроса + " |ИЗ | РегистрБухгалтерии." + ИмяРегистраБухгалтерии + ".ДвиженияССубконто(| &НачПериода, | &КонПериода,"; СтрокаОграниченийПоРеквизитам = " (Активность = ИСТИНА) И (Счет В ИЕРАРХИИ (&СчетАнализа))"; ТекстЗапроса = ТекстЗапроса + СтрокаОграниченийПоРеквизитам + " |) КАК Типовой |"; ТекстЗапроса = ТекстЗапроса + " |ГДЕ | Типовой.СчетКт = &СчетАнализа | И Типовой.Период МЕЖДУ &НачПериода И &КонПериода |СГРУППИРОВАТЬ ПО | ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 1, 6), | ПОДСТРОКА(Типовой.Регистратор.Соотв.Наименование, 8, 11), | Типовой.Регистратор |УПОРЯДОЧИТЬ ПО | Отдел, | СчетЗатрат";
Итак, с помощью кода приведенного выше (выделено жирным), выводятся части запроса с месяцами. Таким образом, происходит добавление новых колонок с названиями месяцев и с суммами по ним.
Раздел содержит описание особенности выполнения функции ПОДСТРОКА() языка запросов в клиент-серверном варианте работы и вытекающие из нее рекомендации по построению запросов.
Функция ПОДСТРОКА()
В языке запросов 1С:Предприятия функция ПОДСТРОКА() в формате ПОДСТРОКА(,) может применяться к данным строкового типа и позволяет выделить фрагмент, начинающийся с символа номер (символы в строке нумеруются с 1) и длиной символов. Результат вычисления функции ПОДСТРОКА() имеет строковый тип переменной длины, причем длина будет считаться неограниченной, если имеет неограниченную длину и параметр не является константой или превышает 1024.
Вычисление функции ПОДСТРОКА() на SQL сервере
В клиент-серверном варианте работы функция ПОДСТРОКА() реализуется при помощи функции SUBSTRING() соответствующего оператора SQL, передаваемого серверу баз данных SQL Server, который вычисляет тип результата функции SUBSTRING() по сложным правилам в зависимости от типа и значений ее параметров, а так же в зависимости от контекста, в котором она используется.
В большинстве случаев эти правила не оказывают влияния на выполнение запроса 1С:Предприятия, однако есть случаи, когда для исполнения запроса существенна максимальная длина строки результата, вычисленная SQL Server. Важно иметь в виду, что в некоторых контекстах использования функции ПОДСТРОКА() максимальная длина ее результата может оказаться равной максимальной длине строки ограниченной длины, которая в SQL Server равна 4000 символам. Это может привести к неожиданному аварийному завершению выполнения запроса.
Например, запрос:
ВЫБРАТЬ
ВЫБОР
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
ВЫБОР
КОГДА Вид =
&
ЮрАдресФизЛица
ТОГДА
ПОДСТРОКА(Представление,
0
,
200
)
ИНАЧЕ NULL
КОНЕЦ КАК Представление1
ИЗ
УПОРЯДОЧИТЬ ПО
Представление,
Представление1
завершается аварийно с сообщением:
Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Warning: The query processor could not produce a query plan from the optimizer because the total length of all the columns in the GROUP BY or ORDER BY clause exceeds 8000 bytes.
HRESULT=80040E14, SQLSTATE=42000, native=8618
Это происходит потому, что вычисленная Microsoft SQL Server максимальная длина строки, которая является результатом выражения:
ВЫБОР
КОГДА Вид =
&
ЮрАдресФизЛица
ТОГДА
ПОДСТРОКА(Представление,
0
,
200
)
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
равна 4000 символов. Поэтому длина записи, состоящей из двух таких полей превышает 8000 байт, разрешенные для выполнения операции сортировки.
В связи с описанной особенностью исполнения функции SUBSTRING() на SQL Server использование функции ПОДСТРОКА() с целью приведения строк неограниченной длины к строкам ограниченной длины не рекомендуется. Вместо нее лучше использовать операцию приведения типа ВЫРАЗИТЬ(). В частности, приведенный пример можно переписать в виде:
ВЫБРАТЬ
ВЫБОР
КОГДА Вид =
&
ЮрАдресФизЛица
ИНАЧЕ NULL
КОНЕЦ КАК Представление,
ВЫБОР
КОГДА Вид =
&
ЮрАдресФизЛица
ТОГДА
ВЫРАЗИТЬ(Представление КАК Строка(200
)
)
ИНАЧЕ NULL
КОНЕЦ КАК Представление1
ИЗ
РегистрСведений.
КонтактнаяИнформация КАК КонтактнаяИнформация
УПОРЯДОЧИТЬ ПО
Представление,
Представление1