Войти
Windows. Настройка. Интернет. Обслуживание. Компьютеры. Безопасность
  • Как выбрать стол под ноутбук
  • Презентация на тему "направление электрического тока"
  • Экстранет: что это, зачем нужно и как функционирует?
  • Установка Joomla Установка джумлы
  • Как открыть dds файл. Чем открыть файл.DDS? Зачем нужны DDS файлы
  • Почему не отвечает браузер Mozilla Мазила не открывается
  • Работа со строками в запросе 1с 8.2. Особенность выполнения функции подстрока(). Функции представление и представлениессылки

    Работа со строками в запросе 1с 8.2. Особенность выполнения функции подстрока(). Функции представление
и представлениессылки

    В языке запросов 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с делают процесс получения данных гибким и многофункциональным. Данные функции и конструкции применимы к полям запроса, а некоторые также применимы в условиях.

    Функции языка запросов 1с

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

    1. Функция ДАТАВРЕМЯ - данная функция создает константное поле с типом "Дата".

    Синтаксис: ДАТАВРЕМЯ(<Год>,<Месяц>,<День>,<Час>,<Минута>,<Секунда>)

    Пример использования:

    2. Функция РАЗНОСТЬДАТ - возвращает разность двух дат в одном из измерений (год, месяц, день, час, минута, секунда). Измерение передается в параметре.

    Синтаксис: РАЗНОСТЬДАТ(<Дата1>, <Дата2>, <Тип>)

    Пример использования:

    Запрос.Текст = "ВЫБРАТЬ | РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2015, 4, 17), ДАТАВРЕМЯ(2015, 2, 1), ДЕНЬ) | КАК КолвоДней";

    3. Функция ЗНАЧЕНИЕ - задает константное поле с предопределенной записью из базы данных, также можно получить пустую ссылку любого типа.

    Синтаксис: ЗНАЧЕНИЕ(<Имя>)

    Пример использования:

    Запрос.Текст = "ВЫБРАТЬ //предопределенный элемент | ЗНАЧЕНИЕ(Справочник.Валюты.Доллар) КАК Доллар, //пустая ссылка | ЗНАЧЕНИЕ(Документ.ПоступлениеТоваровУслуг.ПустаяСсылка) КАК Поступление, //знач. перечисления | ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ФизЛицо) КАК ФизЛицо, //предопределенный счет | ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Материалы) КАК Счет_10" ;

    4. Функция ВЫБОР - перед нами аналог конструкции ЕСЛИ который используется в коде, только эта используется в запросах 1С.

    Синтаксис: ВЫБОР КОГДА <Выражение> ТОГДА <Выражение> ИНАЧЕ <Выражение> КОНЕЦ

    Пример использования:

    Запрос.Текст = //если сумма больше 7500, тогда должна быть скидка 300 рублей, //поэтому если условие срабатывает то функция //возвращает Сумма - 300 //в противном случае запрос вернет просто Сумма "ВЫБРАТЬ | ВЫБОР | КОГДА ТЧПоступления.Сумма > 7500 | ТОГДА ТЧПоступления.Сумма - 300 | ИНАЧЕ ТЧПоступления.Сумма | КОНЕЦ КАК СуммаСоСкидкой |ИЗ | Документ.ПоступлениеТоваровУслуг.Товары КАК ТЧПоступления";

    5. Функция ВЫРАЗИТЬ - позволяет выразить константное поле определенным типом.

    Синтаксис: ВЫРАЗИТЬ(НазваниеПоля КАК НазваниеТипа)

    Пример использования:

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

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

    Пример использования:

    Запрос.Текст = "ВЫБРАТЬ | ВЫРАЗИТЬ(Номенклатура.Комментарий КАК Строка(300)) КАК Комментарий, | ВЫРАЗИТЬ(Номенклатура.Сумма КАК Число(15,2)) КАК Сумма |ИЗ | Справочник.Номенклатура КАК Номенклатура";

    6. Функция ISNULL (альтернативное написание ЕСТЬNULL) - если поле имеет тип NULL, то оно заменяется на второй параметр функции.

    Синтаксис: ЕСТЬNULL(<Поле>, <ПодставляемоеЗначение>)

    Пример использования:

    Также отметим что тип NULL желательно ВСЕГДА заменять на какое-то значение, т.к. сравнение с типом NULL всегда дает ЛОЖЬ даже если вы сравниваете NULL с NULL. Чаще всего значения NULL образуются в результате соединения таблиц (все виды соединений кроме внутреннего).

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

    7. Функция ПРЕДСТАВЛЕНИЕ - позволяет получить представление поля запроса.

    Синтаксис: ПРЕДСТАВЛЕНИЕ(<НаименованиеПоля>)

    Пример использования:

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

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

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

    1. Конструкция ССЫЛКА - представляет из себя логический оператор проверки ссылочного типа. Наиболее часто встречается при проверки поля составного типа на конкретный тип. Синтаксис: ССЫЛКА <Имя таблицы>

    Пример использования:

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

    2. Конструкция МЕЖДУ - данный оператор проверяет входит ли значение в указанный диапазон.

    Синтаксис: МЕЖДУ <Выражение> И <Выражение>

    Пример использования:

    Запрос.Текст = //получим всю номенклатуру код которой лежит в диапазоне от 1 до 100 "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Код МЕЖДУ 1 И 100" ;

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

    Синтаксис: В(<СписокЗначений>), В ИЕРАРХИИ(<СписокЗначений>)

    Пример использования:

    Запрос.Текст = //выбираем все субсчета счета "ВЫБРАТЬ | Хозрасчетный.Ссылка КАК Счет |ИЗ | ПланСчетов.Хозрасчетный КАК Хозрасчетный |ГДЕ | Хозрасчетный.Ссылка В ИЕРАРХИИ ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары)";

    4. Конструкция ПОДОБНО - эта функция позволяет нам сравнивать строку с шаблоном строки.

    Синтаксис: ПОДОБНО "<ТекстШаблона>"

    Варианты шаблона строки:

    % - последовательность, содержащая любое количество произвольных символов.

    Один произвольный символ.

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

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

    Пример использования:

    Запрос.Текст = //найдем всю номенклатуру которая содержит корень ТАБУР и начинается //либо с маленькой либо с большой буквы т "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Товары.Наименование ПОДОБНО ""[Тт]абур%""" ;

    5. Конструкция РАЗРЕШЕННЫЕ - этот оператор позволяет выбрать только те записи из БД, на которые вызывающий имеет право чтения. Данные права настраиваются на уровне записей (RLS).

    Синтаксис: РАЗРЕШЕННЫЕ пишется после ключевого слова ВЫБРАТЬ

    Пример использования:

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

    6. Конструкция РАЗЛИЧНЫЕ - позволяет выбрать записи в которых отсутствуют повторные записи.

    Синтаксис: РАЗЛИЧНЫЕ пишется после ключевого слова ВЫБРАТЬ

    Пример использования:

    Запрос.Текст = //выбирает записи на которые есть права у читающего "ВЫБРАТЬ РАЗЛИЧНЫЕ | Контрагенты.Наименование |ИЗ | Справочник.Контрагенты КАК Контрагенты" ;

    Также Конструкция РАЗЛИЧНЫЕ может использоваться с оператором РАЗРЕШЕННЫЕ и другими операторами.

    Пример использования:

    Запрос.Текст = //выбирает различные записи на которые есть права у читающего "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ | Контрагенты.Наименование |ИЗ | Справочник.Контрагенты КАК Контрагенты";

    7. Конструкция ПЕРВЫЕ - выбирает указанное в параметре число записей из результата запроса.

    Синтаксис: ПЕРВЫЕ <число>

    Пример использования:

    Запрос.Текст = //выбирают первые 4 номера ГТД из справочника "ВЫБРАТЬ ПЕРВЫЕ 4 | НомераГТД.Ссылка |ИЗ | Справочник.НомераГТД КАК НомераГТД";

    8. Конструкция ДЛЯ ИЗМЕНЕНИЯ - позволяет заблокировать таблицу, работает только в транзакциях (актуально только для автоматических блокировок).

    Синтаксис: ДЛЯ ИЗМЕНЕНИЯ <НаименованиеТаблицы>

    Пример использования:

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

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

    Синтаксис: УПОРЯДОЧИТЬ ПО <НаименованиеПоля> АВТОУПОРЯДОЧИВАНИЕ

    Пример использования:

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

    10. Конструкция СГРУППИРОВАТЬ ПО - используется для группировки строк запроса по определенным полям. Числовые поля должны использоваться с любой агрегатной функцией.

    Синтаксис: СГРУППИРОВАТЬ ПО <НаименованиеПоля1>, .... , <НаименованиеПоляN>

    Пример использования:

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

    11. Конструкция ИМЕЮЩИЕ - позволяет применить агрегатную функцию к условию выборки данных, похожа на конструкцию ГДЕ.

    Синтаксис: ИМЕЮЩИЕ <агрегатная функция с условием>

    Пример использования:

    Запрос.Текст = //выбирает сгруппированные записи где поле ВНаличии больше 3 "ВЫБРАТЬ | ТоварыНаСкладах.Номенклатура КАК Номенклатура, | ТоварыНаСкладах.Склад, | СУММА(ТоварыНаСкладах.ВНаличии) КАК ВНаличии |ИЗ | РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах | |СГРУППИРОВАТЬ ПО | ТоварыНаСкладах.Номенклатура, | ТоварыНаСкладах.Склад | |ИМЕЮЩИЕ | СУММА(ТоварыНаСкладах.ВНаличии) > 3" ;

    12. Конструкция ИНДЕКСИРОВАТЬ ПО - используется для индексации поле запроса. Запрос с индексацией дольше выполняется, но ускоряет поиск по индексированным полям. Можно использовать только в виртуальных таблицах.

    Синтаксис: ИНДЕКСИРОВАТЬ ПО <Поле1, ... , ПолеN>

    Пример использования:

    Запрос.Текст = "ВЫБРАТЬ | Тз.НаименованиеОС, | Тз.НомерПапки, | Тз.КодОС, | Тз.Срок, | Тз.Тип |ПОМЕСТИТЬ ДанныеТз |ИЗ | &Тз КАК Тз | |ИНДЕКСИРОВАТЬ ПО | Тз.НаименованиеОС, | Тз.КодОС";

    13. Конструкция ГДЕ - позволяет наложить условие на любые поля выборки. В результат попадут записи только удовлетворяющие условию.

    Синтаксис: ГДЕ <Условие1 ОператорЛогСоединения УсловиеN>

    Пример использования:

    Запрос.Текст = //выбираются все записи у которых КомпенсацияОстаток <> 0 и //СуммаДляРасчКомпОстаток > 100 "ВЫБРАТЬ | КомпенсацияРПОстатки.Контрагент, | КомпенсацияРПОстатки.Ребенок, | КомпенсацияРПОстатки.КомпенсацияОстаток, | КомпенсацияРПОстатки.СуммаДляРасчКомпОстаток |ПОМЕСТИТЬ ДанныеТз |ИЗ | РегистрНакопления.КомпенсацияРП.Остатки КАК КомпенсацияРПОстатки |ГДЕ | КомпенсацияРПОстатки.КомпенсацияОстаток <> 0 | И КомпенсацияРПОстатки.СуммаДляРасчКомпОстаток > 100" ;

    14. Конструкция ИТОГИ... ПО ОБЩИЕ - применяется для подсчета итогов, в конструкции указываются поля по которым будут считаться итоги и агрегатные функции применяемые к итоговым полям. При использовании итогов на каждое поле следующее после конструкции ИТОГИ производится группировка данных. Есть необязательная конструкция ОБЩИЕ, ее использование также обеспечивает дополнительную группировку. Пример результата запроса вы увидите ниже.

    Синтаксис: ИТОГИ <АгрегатнаяФункция1, ... , АгрегатнаяФункцияN> ПО <ОБЩИЕ> <Поле1, ... , ПолеN>

    Пример использования:

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

    На рисунке обведены группировки которые образовались в ходе выполнения запроса, самая верхняя относится к секции ОБЩИЕ, а вторая к полю ДоговорКонтрагентаВидДоговора.

    Приветсвую вас, уважаемые читатели блога сайт! Сегодня, с помощью примеров, мы рассмотрим, как на практике можно использовать функцию запросов 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 символам. Это может привести к неожиданному аварийному завершению выполнения запроса.

    Например, запрос:
    Код 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) и длиной символов. Результат вычисления функции ПОДСТРОКА() имеет строковый тип переменной длины, причем длина будет считаться неограниченной, если имеет неограниченную длину и параметр не является константой или превышает 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