gifts2017

Определение длины строки в запросе методом половинного деления

Опубликовал Vladimir Vasiliev (vasvl123) в раздел Программирование - Практика программирования

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

Здесь описан другой способ (21. Определение длины строки в запросе).

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

Функция Дерево(Реквизит, Начало, Конец) Экспорт

	Если Начало + 1 = Конец Тогда
		Возврат Строка(Конец);
	КонецЕсли;
	Середина = Начало + Цел((Конец - Начало) / 2);
	СтрокаДерево = "ВЫБОР КОГДА ПОДСТРОКА(" + Реквизит + ", " + (Середина + 1) + ", 3) = """" ТОГДА " 
		+ Дерево(Реквизит, Начало, Середина) + " ИНАЧЕ " + Дерево(Реквизит, Середина, Конец) + " КОНЕЦ";
	Возврат СтрокаДерево;

КонецФункции // Дерево()

Где:

Реквизит – строка с именем таблицы и реквизита, содержащего определяемые строки.

Начало, Конец – интервал в котором будет производится поиск конца строки.

ТекстДерево = Дерево("Строки.Строка", -1, 300); 

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

Вставляем полученное дерево в запрос:

Запрос.Текст = 
	"ВЫБРАТЬ
	|	Строки.Строка,
	|	" + ТекстДерево + " КАК Длина
	|ИЗ
	|	Строки КАК Строки
	|
	|УПОРЯДОЧИТЬ ПО
	|	Длина УБЫВ";

Вот и все. Скоро напишу, для чего это было нужно)

Скачать файлы

Наименование Файл Версия Размер
Обработка пример для УФ
.epf 8,51Kb
02.01.16
0
.epf 8,51Kb Скачать
Обработка сравнение способов
.epf 8,50Kb
31.12.15
0
.epf 8,50Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Максим *** (premier) 27.12.15 15:48
(0) На скриншот посмотрел и страшно стало... за 1С-ников.
2. Vladimir Vasiliev (vasvl123) 27.12.15 16:51
Выглядит, конечно, не очень, но работает замечательно
3. Александр Капустин (kapustinag) 27.12.15 17:56
Скрин №2 точно в порядке? Номера ВСЕХ строк совпадают с их длинами.
Или это особенность алгоритма? -:)
4. Vladimir Vasiliev (vasvl123) 27.12.15 18:04
(3) kapustinag, для отладки сделал так, чтобы в начале каждой строки была написана своя длина)
5. Сергей (ildarovich) 29.12.15 16:27
Вот гораздо более компактная реализация той же самой идеи:
ВЫБРАТЬ
	"12345678901234567890123456789012345678901234567890" КАК Стр,
	1023 КАК Х
ПОМЕСТИТЬ Дано
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Стр, Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   0, 1) = "" ТОГДА Х -   1 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   1, 1) = "" ТОГДА Х -   2 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   3, 1) = "" ТОГДА Х -   4 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -   7, 1) = "" ТОГДА Х -   8 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  15, 1) = "" ТОГДА Х -  16 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  31, 1) = "" ТОГДА Х -  32 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х -  63, 1) = "" ТОГДА Х -  64 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 127, 1) = "" ТОГДА Х - 128 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 255, 1) = "" ТОГДА Х - 256 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	(ВЫБРАТЬ Стр, ВЫБОР КОГДА ПОДСТРОКА(Стр, Х - 511, 1) = "" ТОГДА Х - 512 ИНАЧЕ Х КОНЕЦ КАК Х
ИЗ	Дано КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ) КАК ВЗ
...Показать Скрыть
Этим запросом можно получить длину строки до 1023 быстро и без дополнительных таблиц.
yurii_host; jsr; Операция1Ы; vasvl123; +4 Ответить 1
6. Vladimir Vasiliev (vasvl123) 29.12.15 19:28
(5) ildarovich, Супер! Возьму на вооружение в новой обработке. Переносите способ в Ваш пост про минимализмы. Длину подстроки, однако, следует брать 3 символа, иначе пробел дает ложный конец строки, например, после 31 символа.
7. Олег Загородний (jsr) 31.12.15 11:20
(6) vasvl123, чтобы "отловить" любое количество внутренних пробелов, идущих подряд, длина подстроки должна быть достаточной, чтобы "дотянуться" до конца строки. Не вникая особо, можно везде поставить 1024. А хвостовые пробелы вообще не ловятся.
8. Vladimir Vasiliev (vasvl123) 31.12.15 12:28
Сравнил производительность обоих способов, выложил обработку и скрин. Думаю способ с деревом все же имеет право на жизнь.
9. Vladimir Vasiliev (vasvl123) 31.12.15 12:34
(7) jsr, чтобы наверняка, тогда да. Но не 1024, а половина длины строки, причем можно с каждым шагом уменьшать вдвое.