Работа со строками в запросе
К сожалению, возможности запросов 1С в отношении строковых переменных крайне малы. Практически они исчерпываются одной функцией и одним оператором. Тем не менее, постоянно всплывают темы в духе «а как мне сделать это прямо в запросе?». Конечно, большинство задач решаются в СКД, оставшаяся часть решается пост-обработкой результата, но чисто в качестве разминки для ума, кое-что в запросе сделать можно.
- Описание
- Подробнее
Описание
Только ленивый, по-моему, не писал еще о вариантах вырезания гланд через анус автогеном запросами. Ну и я поделюсь.
К сожалению, возможности запросов 1С в отношении строковых переменных крайне малы. Практически они исчерпываются одной функцией и одним оператором. Тем не менее, постоянно всплывают темы в духе «а как мне сделать это прямо в запросе?». Конечно, большинство задач решаются в СКД, оставшаяся часть решается пост-обработкой результата, но чисто в качестве разминки для ума, кое-что в запросе сделать можно.
Во всех примерах я буду использовать следующие временные таблицы:
ВЫБРАТЬ
«_» КАК Симв,
1 КАК КолСимв
ПОМЕСТИТЬ тзКоличествоСимволов9
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«__»,
2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«___»,
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«____»,
4
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«_____»,
5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«______»,
6
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«_______»,
7
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«________»,
8
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«_________»,
9
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
«»,
0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Прав.Симв КАК Симв,
тзКоличествоСимволов9_Лев.КолСимв * 10 + тзКоличествоСимволов9_Прав.КолСимв КАК КолСимв
ПОМЕСТИТЬ тзКоличествоСимволов100
ИЗ
тзКоличествоСимволов9 КАК тзКоличествоСимволов9_Лев,
тзКоличествоСимволов9 КАК тзКоличествоСимволов9_Прав
;
////////////////////////////////////////////////////////////////////////////////
Для приведенных примеров их вполне хватит, смысл, думаю, понятен, так что не будем заострять внимание на оптимальности их построения.
Так же рекомендую экспериментировать с приведенными запросами в файловых базах – серверные более нежные и работать автогеном в таком грязном месте не любят. 🙂
- Подсчет количества символов в строке.
Тут всё очень просто
ВЫБРАТЬ
Номенклатура.Наименование,
КоличествоСимволов.КолСимв
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволов
ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволов.Симв)
Всё. Теперь можно отрезать последний пробел, например:
ВЫБРАТЬ
Номенклатура.Наименование,
КоличествоСимволов.КолСимв,
ВЫБОР
КОГДА Наименование подобно «% «
ТОГДА ПОДСТРОКА(Номенклатура.Наименование, 1, КоличествоСимволов.КолСимв — 1)
ИНАЧЕ Номенклатура.Наименование
КОНЕЦ КАК НаименованиеБезПробела
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволов
ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволов.Симв)
2. Разбить строку
Здесь чуть сложнее. Но теми же граблями.
Задача: в некоторой номенклатуре в наименовании записан некоторый текст в скобках. Надо вытащить этот текст в отдельное поле.
Для простоты договоримся, что скобочки в наименовании у нас один раз открываются и один раз закрываются.
ВЫБРАТЬ Различные
Номенклатура.Ссылка,
Выразить(ПОДСТРОКА(Номенклатура.Наименование, КоличествоСимволовДоОткрытия.КолСимв+2, КоличествоСимволовДоЗакрытия.КолСимв—КоличествоСимволовДоОткрытия.КолСимв—1) как строка(100)) КАК ТекстВСкобках
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоОткрытия
ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволовДоОткрытия.Симв + &СимволОткрытия + «%»)
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоЗакрытия
ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволовДоЗакрытия.Симв + &СимволЗакрытия + «%»)
ГДЕ
Номенклатура.Наименование ПОДОБНО «%» + &СимволОткрытия + «%» + &СимволЗакрытия + «%»
Тут &СимволОткрытия, понятно «(»,&СимволЗакрытия соответственно «)». Находим позицию символов и вытаскиваем подстроку. Помним, что запросы тошнит от строк неограниченной длины, поэтому используем ВЫРАЗИТЬ.
3. Сложное соединение по строке.
Ну и совсем извращение, но пример взят из реальной темы.
Существуют две таблицы:
В одной номера договоров в формате: «Номер-постфикс»
В другой номера тех же договоров, но дополненные неким доп-индексом в формате: «Номер/Индекс-постфикс».
Необходимо связать. Номер, индекс и постфикс могут быть разной длины, ориентироваться можно только на «/» и «-».
Сымитируем данные:
Выбрать
«30568-12» как ВнутреннийНомер
поместить тз1
Объединить все
Выбрать
«3568-12»
;
Выбрать
«30568/1-12» как ВнутреннийНомер
поместить тз2
Объединить все
Выбрать
«30568/155-12»
Объединить все
Выбрать
«30568/2-12»
Объединить все
Выбрать
«35681/2-12»
Объединить все
Выбрать
«3568/2-12»
Объединить все
Выбрать
«3568/2-13»
;
И начнем выпендриваться.
//Выделим из номеров те части, по которым сможем связывать
Выбрать
тз1сРазбиением.ВнутреннийНомер,
Подстрока(тз1сРазбиением.ВнутреннийНомер,1, КоличествоСимволовДоТире.КолСимв) как ДоСлэша,
Подстрока(тз1сРазбиением.ВнутреннийНомер,КоличествоСимволовДоТире.КолСимв+2, СтрДлина.КолСимв) как ПослеТире
поместить тз1сРазбиением
из тз1 как тз1сРазбиением
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоТире
ПО (тз1сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоТире.Симв+«-%»)
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК СтрДлина
ПО (тз1сРазбиением.ВнутреннийНомер ПОДОБНО СтрДлина.Симв)
;
Выбрать
тз2сРазбиением.ВнутреннийНомер,
Подстрока(тз2сРазбиением.ВнутреннийНомер,1, КоличествоСимволовДоСлэша.КолСимв) как ДоСлэша,
Подстрока(тз2сРазбиением.ВнутреннийНомер,КоличествоСимволовДоТире.КолСимв+2, СтрДлина.КолСимв) как ПослеТире
поместить тз2сРазбиением
из тз2 как тз2сРазбиением
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоСлэша
ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоСлэша.Симв+«/%»)
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоТире
ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоТире.Симв+«-%»)
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК СтрДлина
ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО СтрДлина.Симв)
;
ВЫБРАТЬ Различные
тз11.ВнутреннийНомер,
тз22.ВнутреннийНомер
ИЗ
тз1сРазбиением КАК тз11
Левое СОЕДИНЕНИЕ тз2сРазбиением КАК тз22
ПО тз11.ДоСлэша Подобно тз22.ДоСлэша
и тз11.ПослеТире Подобно тз22.ПослеТире
Для любителей возмущающаться напомню, что целью было отвлечься от работы J Если кому-то пригодится в практических целях, буду рада.

