Агрегатное суммирование строк в запросе – сложно, но не невозможно

Публикация № 200275 09.09.13

Разработка - Математика и алгоритмы

метод запрос строки агрегатная функция

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

Во многих типовых конфигурациях в документах есть реквизит «Содержание» типа строка, где перечислены фамилии сотрудников, упоминающиеся в строках табличной части, или список номенклатуры, имеющейся в таблице товаров. При заполнении этого реквизита естественно было бы сгруппировать строки по ссылке на документ, определив реквизит «Содержание» с помощью агрегатной функции суммы как СУММА(СсылкаНаОбъектТЧ.Наименование). К сожалению, агрегатная функция СУММА не воспринимает аргумент строкового типа.

Подобных задач довольно много, но если число исходных строк не фиксировано и достаточно велико, все они в общем случае решаются дополнительной обработкой результата запроса. Начиная с релиза 8.2.13(?), в СКД для решения этой задачи даже появилась специальная функция «СоединениеСтрок», что также свидетельствует о популярности задачи «агрегатной конкатенации». Многие сомневаются в возможности решения этой задачи одним пакетным запросом, а зря!

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

Для начала придется пояснить, чем конкатенация отличается от других агрегатных функций: суммирования, усреднения, выбора максимума и минимума. Дело в том, что все перечисленные функции коммутативны, то есть их результат не зависит от порядка операций. А у конкатенации – зависит. Это означает, что для конкатенации недостаточно одного столбца. Обязательно должен существовать второй (а лучше - первый) столбец, который будет определять порядок подстрок в результирующей строке. Это следует из теории реляционных СУБД, с точки зрения которой таблицы

А    Т   О   Т     Р
 В    О   Т    А    В
 Т    В   В    В    О
 О    А   А    Р    Т
 Р    Р   Р    О    А

это представление одной и той же таблицы. По которой нельзя определить, что должно получиться в результате конкатенации. А по таблице 

 3 Р
 4 А
 5 В
 1 Н
 2 И
 6 Н
7 А

можно.

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

Для простоты будем считать, что порядок соединения задан числами от 1 до N, где N – число строк. Следовательно, исходная таблица «Таб» имеет вид

ё а
1 Строка1
2 Строка2
   
N СтрокаN

Соединим для начала попарно все соседние нечетные и четные строки. Для этого определим число «е» как округление результата деления номера строки на два и построим таблицу «Шаг»

е ё а
1 1 Строка1
1 2 Строка2
2 3 Строка3
2 4 Строка4
3 5 Строка5
     

После этого сгруппируем строки по полю «е», соединив операцией «+» две строки: левую – нечетную, которая отличается тем, что «2 * е – ё = 1», и правую – четную, для которой «2 * е – ё <> 1». В результате получим таблицу

ё а
1 Строка1Строка2
2 Строка3Строка4
3 Строка5Строка6
   

 

Повторяя этот приём нужное количество раз, получим в первой строке конкатенацию всех строк.

Соответствующий описанному приему запрос имеет вид:

ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; 
УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е;
УНИЧТОЖИТЬ Шаг;

В запросе нарочно сокращены необязательные поля, чтобы его запись было короче, а местами имела смешной вид. Например, такой вид имеют рядом написанные буквы «е» и «ё».

Если в исходной таблице было 2 строки, для завершения алгоритма понадобится один повтор, 4 и менее – два, 8 и менее – три, 16 и менее – четыре,32 и менее - пять, 64 и менее – шесть, 128 и менее – семь, 256 и менее – восемь, … 2048 и менее – одиннадцать. Принцип, думаю, понятен, обойдемся без формулы с логарифмом по основанию два.   

А как определить нужное число повторений заранее? Не зная числа соединяемых строк? И вот тут-то и нужно вспомнить, что хотя число строк ничем не ограничено, но ограничен размер строки, который будет принимать результат наших вычислений. Результирующая строка – это строка ограниченного типа, которая в 1С не может содержать больше 2047 символов! Следовательно, использовать более 11-ти соединений вообще не нужно, так как результат будет просто некуда поместить.

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

Кроме того, если ограничение будет когда-либо повышено, то нужно будет всего немного увеличить число повторений.  Даже строка неограниченного типа не может быть длиннее 2^31 -1 символов. Что означает, что будет нужно добавить еще всего лишь двадцать повторений. Отметим, что операции группировки для данного случая выполняются достаточно быстро. Притом, что строки идут по порядку.

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

Первое обстоятельство - это способ реализации суммирования двух полей строкового типа при получении нового поля в запросе, о котором мы обычно не задумываемся. Точнее, способ вычисления длины поля строкового типа, содержащего результат. Во-первых, можно складывать только поля строк ограниченного типа (ну или приведенного к нему неограниченного типа с использованием оператора «ВЫРАЗИТЬ»). Во-вторых, результирующее поле будет также строкой ограниченного типа, длина которой будет равна сумме длин соединяемых полей. Независимо от того, сколько символов на самом деле занято в этих полях!

Для нас это означает, что имея на первом шаге строки длины 32, например, мы не сможем выполнить  более шести повторений (64->128->256->512->1024->2048), так как длины строк будут на каждом шаге считаться по-максимуму, а не по реальному содержанию. А шесть повторений – это всего 64 сложенные строки, причем в результирующей 2047-символьной строке может быть реально занято совсем немного места.

Максимальную плотность упаковки символов в результирующей строке можно обеспечить, если перед соединением предварительно разбить строки на отдельные символы. И не только разбить, но и затем правильно последовательно пронумеровать. Это может быть довольно дорогая в  вычислительном отношении операция, поскольку глобальный номер отдельного символа конкретной строки будет зависеть от числа символов в строках впереди нее. То есть потребуется медленное тэта-соединение таблицы строк с самой собой.

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

Разбивка строк на символы выполняется с использованием соединения с искусственной таблицей, содержащей числа от 0 до 2047, полученной методом «Порождающего запроса» [//infostart.ru/public/90367/].

Числа от 0 до 2047 записываются в таблицу РА9876543210, название которой составлено из первой буквы слова «Разряд» и номеров содержащейся в ней двоичных разрядов (в шестнадцатеричной системе – цифр не хватило, десятый разряд обозначен буквой «А»). Это делает следующий фрагмент запроса:

ВЫБРАТЬ РАЗЛИЧНЫЕ Дано.Колонка НомерСтроки, Дано.Колонка а ПОМЕСТИТЬ Дано ИЗ &Дано КАК Дано;
ВЫБРАТЬ 0 ё ПОМЕСТИТЬ Р0 ОБЪЕДИНИТЬ ВЫБРАТЬ 1;
ВЫБРАТЬ 2 * Р1.ё + Р0.ё ё ПОМЕСТИТЬ Р10 ИЗ Р0 Р1, Р0;
ВЫБРАТЬ 4 * Р32.ё + Р10.ё ё ПОМЕСТИТЬ Р3210 ИЗ Р10 Р32, Р10;
ВЫБРАТЬ 16 * Р7654.ё + Р3210.ё ё ПОМЕСТИТЬ Р76543210 ИЗ Р3210 Р7654, Р3210;
ВЫБРАТЬ 8 * Р76543210.ё + 2 * Р10.ё + Р0.ё + 1 ё ПОМЕСТИТЬ РА9876543210 ИЗ Р76543210, Р10, Р0 ГДЕ 8 * Р76543210.ё + 2 * Р10.ё + Р0.ё < &ШиринаКолонки

Параметр «ШиринаКолонки» обозначает длину строки в поле «КОЛОНКА» (если 0, то 2047).

Собственно разбивка на символы выполняется в следующем фрагменте запроса. Результат помещается в таблицу «Буквы»

ВЫБРАТЬ НомерСтроки, ё, ПОДСТРОКА(а, ё, 1) а ПОМЕСТИТЬ Буквы ИЗ Дано, РА9876543210 ГДЕ ПОДСТРОКА(а, ё, 1) + "!" <> "!"

После этого получается таблица длин строк и с ее использованием буквы «а» получают глобальные номера «ё» в таблице «Таб».

ВЫБРАТЬ НомерСтроки, МАКСИМУМ(ё) СтрДлина ПОМЕСТИТЬ Длины ИЗ Буквы СГРУППИРОВАТЬ ПО НомерСтроки;
ВЫБРАТЬ ё + СУММА(ЕСТЬNULL(СтрДлина, 0)) ё, а Поместить Таб ИЗ Буквы КАК Буквы ЛЕВОЕ СОЕДИНЕНИЕ Длины ПО Буквы.НомерСтроки > Длины.НомерСтроки 
СГРУППИРОВАТЬ ПО Буквы.НомерСтроки, ё, а

Второе усложняющее обстоятельство – это «проблема пробелов». Дело в том, что при работе со строками в запросе к результату как будто бы автоматически применяется функция «СокрП». То есть становится невозможно зафиксировать добавление пробела справа. Операция вроде бы выполняется, а добавленные пробелы сразу же пропадают. В результирующей строке это выглядит как исчезнувшие пробелы. «пока лечили» превращается в «покалечили», "несу разное" в "несуразное" и так далее.

Выход был найден в том, что обычный пробел в строках при их разбивке на символы заменялся на неразрывный пробел – символ с кодом 160 (Символы.НПП). Поскольку внешне эти символы выглядят неотличимо, то запрос принимает крайне любопытный вид. Он получает буквально неочевидные свойства. Честно говоря, такой «невидимый» трюк приходится использовать впервые. Кроме того, при каком-либо копипасте запроса этот особенный пробел может подмениться обычным. Будьте внимательнее – следите за своими пробелами!

С учетом последнего уточнения предпоследний фрагмент принимает следующий вид (в кавычках после "Тогда" - неразрывный пробел!):

ВЫБРАТЬ НомерСтроки, ё, ВЫБОР ПОДСТРОКА(а, ё, 1) КОГДА " " ТОГДА " " ИНАЧЕ ПОДСТРОКА(а, ё, 1) КОНЕЦ а ПОМЕСТИТЬ Буквы ИЗ Дано, РА9876543210 
ГДЕ ПОДСТРОКА(а, ё, 1) + "!" <> "!"

Ну а весь собранный в единое целое запрос получает в итоге следующий законченный вид:

ВЫБРАТЬ РАЗЛИЧНЫЕ Дано.Колонка НомерСтроки, Дано.Колонка а ПОМЕСТИТЬ Дано ИЗ &Дано КАК Дано;
ВЫБРАТЬ 0 ё ПОМЕСТИТЬ Р0 ОБЪЕДИНИТЬ ВЫБРАТЬ 1;
ВЫБРАТЬ 2 * Р1.ё + Р0.ё ё ПОМЕСТИТЬ Р10 ИЗ Р0 Р1, Р0;
ВЫБРАТЬ 4 * Р32.ё + Р10.ё ё ПОМЕСТИТЬ Р3210 ИЗ Р10 Р32, Р10;
ВЫБРАТЬ 16 * Р7654.ё + Р3210.ё ё ПОМЕСТИТЬ Р76543210 ИЗ Р3210 Р7654, Р3210;
ВЫБРАТЬ 8 * Р76543210.ё + 2 * Р10.ё + Р0.ё + 1 ё ПОМЕСТИТЬ РА9876543210 ИЗ Р76543210, Р10, Р0 ГДЕ 8 * Р76543210.ё + 2 * Р10.ё + Р0.ё < &ШиринаКолонки;
ВЫБРАТЬ НомерСтроки, ё, ВЫБОР ПОДСТРОКА(а, ё, 1) КОГДА " " ТОГДА "_" ИНАЧЕ ПОДСТРОКА(а, ё, 1) КОНЕЦ а ПОМЕСТИТЬ Буквы ИЗ Дано, РА9876543210 ГДЕ ПОДСТРОКА(а, ё, 1) + "!" <> "!";
ВЫБРАТЬ НомерСтроки, МАКСИМУМ(ё) СтрДлина ПОМЕСТИТЬ Длины ИЗ Буквы СГРУППИРОВАТЬ ПО НомерСтроки;
ВЫБРАТЬ ё + СУММА(ЕСТЬNULL(СтрДлина, 0)) ё, а Поместить Таб ИЗ Буквы КАК Буквы ЛЕВОЕ СОЕДИНЕНИЕ Длины ПО Буквы.НомерСтроки > Длины.НомерСтроки СГРУППИРОВАТЬ ПО Буквы.НомерСтроки, ё, а;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ "" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА "" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО е; УНИЧТОЖИТЬ Шаг;
ВЫБРАТЬ а ИЗ Таб

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

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

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

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

Наименование Файл Версия Размер
Отчет для тестирования метода

.erf 9,70Kb
69
.erf 9,70Kb 69 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Новиков 292 09.09.13 20:57 Сейчас в теме
Снимаю шляпу. Одного скептика, в моем лице, вы убедили :)
2. Поручик 4623 10.09.13 08:22 Сейчас в теме
(0) Начиная с релиза 8.2.14, в СКД появилась специальная функция «СоединениеСтрок» и прочие нужные функции для ТЗ и массивов, которые выручили меня при построении некоторых упоротых отчетов.

Но применить Такое в обычном запросе, у меня бы ума не хватило.
user1671936; RuSeek; pvlunegov; maksa2005; Hoppius; acanta; neo-ti; androgin; +8 Ответить
3. ildarovich 7662 10.09.13 11:10 Сейчас в теме
Еще несколько соображений, которые потом нужно будет включить в статью:
1) Соединив фрагменты с первого по начало третьего, можно получить несложный и быстрый запрос для определения длины строк в запросе, реализовав отсутствующую в запросе функцию СтрДлина.
2) Если длина соединяемых строк равна 25-ти (длина наименования элементов в справочниках по умолчанию), а число соединяемых строк не более 64-х, то можно использовать только концовку запроса (одиннадцать повторений), чтобы ОЧЕНЬ БЫСТРО получить желаемый результат. Зависимость, наверное, понятна: если исходная длина соединяемых строк равна или менее 8, то ограничение на число строк - 2048 / 8 = 256; если равна или менее 16, то ограничение - 2048 / 16 = 128 и так далее.
3) Поскольку последний фрагмент является конкатенацией абсолютно одинаковых кусков кода, то запись запроса в программе можно существенно (более чем в три раза) сократить за счет динамического формирования текста запроса. Здесь это не сделано из-за того, что динамическое формирование текста запроса было запрещено условиями задачи.
4) Также можно сэкономить на переписываниях таблиц Таб и Шаг, объединив действие двух запросов в одном. Это не было сделано потому, что запись запроса в таком виде является более громоздкой из-за отсутствия возможности запомнить результат целого от деления на два для его последующего использования в трех местах. Есть и вариант вообще без деления - за счет представления номера символа в текстовой строке из "0" и "1". При этом вместо деления используется сдвиг. Он также оказался длиннее в записи (но быстрее).
4. AlexO 132 10.09.13 15:38 Сейчас в теме
потом выяснится, что все уперлось в сортировку букв...
я думал об этом на заре 1С, но создавать ТЗ с "1 буква - одна запись" это такая ерунда... а уж в на базе 1С - совсем бесперспективное дело.
Это ж сколько миллионов записей получится при такой разбивке хотя б 100 тыс наименований элементов справочников....
Ведь здесь сколько букв в наименовании - столько строк, и так по каждому наименованию....
5. AlexO 132 10.09.13 15:40 Сейчас в теме
.. не говоря уже о том, что пихать столько кода в любой запрос - это похоронить сам запрос без права отладки.
6. mymyka 10.09.13 16:20 Сейчас в теме
(5)Уважаемым ildarovich имеет весьма своеобразную технику написания кода, но в данном конкретном случае зря хаешь, это действительно достойная и оригинальная работа. Тем более, что в самом начале публикации написано же:
Метод сложный и по сравнению с внезапросной техникой представляет больше спортивный, чем практический интерес.
8. andrewks 1356 10.09.13 16:29 Сейчас в теме
(6) всё правильно, задача изначально ставилась как практическая (в ветке форума), однако к моменту, когда спор зашёл о том, возможно ли подобное в чистом запросе в принципе, задача (а точнее, её решение) представляла по большей части сугубо научный интерес
7. andrewks 1356 10.09.13 16:24 Сейчас в теме
в плане решения реальных задач - конечно, изврат :)

зато как красиво! и в алгоритмическом смысле тоже очень полезно баловаться подобными задачками
9. ildarovich 7662 10.09.13 16:53 Сейчас в теме
Могу сказать, что в одном проекте эта штука сейчас действительно используется. В конфигурации "1С: Консолидация" выбирать данные из консолидируемых информационных баз требуется принципиально запросами. Там текст запроса прямо в справочник правил подключения пишется. Конфигурация очень непростая, место для постобработки найти трудно. Артикулы в базах филиалов сильно замусорены. Где точка добавлена, где вместо нуля буква "О", где вместо латинских русские буквы. Народ в филиалах у клиента косячит как может. Вот этим самым запросом артикулы разбираются на символы, заменяются по таблице, затем по указанному принципу собираются, и в Консолидацию уже приходят "чистые".
10. AlexO 132 10.09.13 17:45 Сейчас в теме
(9)
А обработки не справляются? Почему нельзя обработками сделать?
11. Новиков 292 10.09.13 21:04 Сейчас в теме
(10) это академический интерес, направленный на разубежденье критиков, что сделать это можно. Практический аспект применения этого алгоритма автор описывал.
12. andrewks 1356 10.09.13 21:09 Сейчас в теме
Числа от 0 до 2047 записываются в таблицу РА9876543210, название которой составлено из первой буквы слова «Разряд» и номеров содержащейся в ней двоичных разрядов (в шестнадцатеричной системе – цифр не хватило, десятый разряд обозначен буквой «А»)

A - одиннадцатый разряд
13. andrewks 1356 10.09.13 21:11 Сейчас в теме
в последнем запросе

ВЫБРАТЬ НомерСтроки, ё, ВЫБОР ПОДСТРОКА(а, ё, 1) КОГДА " " ТОГДА "_"


подчёркивание сделано специально, чтобы выделить необходимость замены этого символа на НПП?
14. ildarovich 7662 11.09.13 14:26 Сейчас в теме
(13) Нет, это получилось случайно, забыл убрать. У меня в коде в приложенной обработке, в которой я отлаживал запрос, используется "_", которое реплейсом заменяется на Символы.НПП. Но так даже лучше, потому что неразрывный пробел или на сайт или с сайта не копируется.
(12) Все же я считал разряды от нулевого и в этом смысле это десятый разряд (одиннадцатая цифра, но разряд номер 10).
Тут осталась более важная неточность - сколько символов можно максимально получать в запросе: 2047 или 2048? В 1С есть ограничение 1024 на длину ограниченной строки. 2048 - это видимо, что-то связанное с юникодом. Я ошибочно написал 2047(вроде тест это показал, но сейчас перепроверил - не так), хотя на самом деле - ограничение - 2048 символов! Я поправлю потом в статье.
Кстати, возможно, получится ускорить фрагмент с нумерацией символов (есть некоторые идеи). Тогда планирую написать универсальную обработку для конкатенации наименований номенклатуры и т.п. в ТЧ документов и сравнить три подхода: код, СКД и этот по скорости.
Также было бы интересно сравнить быстродействие метода при объединении 2048 односимвольных строк (концовка запроса) с работой RCTE на чистом SQL. Сдается мне, что из-за того, что в SQL строки "наращиваются"(?), RCTE может проиграть по быстродействию данному подходу (см. статью "Опять двойка").
16. andrewks 1356 11.09.13 15:04 Сейчас в теме
(14)
Все же я считал разряды от нулевого

мне кажется, нумерация разрядов с нуля - не совсем корректно.

так можно прийти к "единичной", "семичной", "девятичной" и "пятнадцатиричной" системам счисления :)
15. bulpi 209 11.09.13 14:51 Сейчас в теме
Автор, а что за странное условие
ГДЕ ПОДСТРОКА(а, ё, 1) + "!" <> "!"

Почему нельзя было написать
ГДЕ ПОДСТРОКА(а, ё, 1)<> ""

????
18. ildarovich 7662 11.09.13 15:13 Сейчас в теме
(15) - Отличный вопрос! Думаю, над ним уже поломал голову andrewks. Вообще-то еще немного информации есть в обсуждении темы, с которой все началось: http://forum.infostart.ru/forum26/topic69221/.
Но оказалось, что если подстрока в запросе равно пробелу " ", то она равна и пустышке "". То есть фактически " " = "". Из-за этого поначалу я не мог при разбивке отличить выход за границы строки от пробела внутри строки, поэтому приходилось обрезать пробелы справа сравнением с максимальным не пробельным символом чтобы отличить середину строки от заграницы - использовать лишний запрос. В посте (84) приведен такой вариант. Потом появилось такое сравнение. Равенство свидетельствует, что подстрока - точно пустышка, а мы за границей.
anchovy; krv2k; artbear; bulpi; +4 Ответить
44. AlexO 132 08.06.15 12:57 Сейчас в теме
(18)
Но оказалось, что если подстрока в запросе равно пробелу " ", то она равна и пустышке "".
А с Символ(32) сравнить?
И что-то ни разу не попадалось, что пустая строка - равна при сравнении "пробелу".
45. ildarovich 7662 13.06.15 12:55 Сейчас в теме
(44) AlexO, в запросе это так, там все приводится к CHARVAR, поэтому ВЫБОР КОГДА "" = " " ТОГДА "всегда" ИНАЧЕ "никогда" КОНЕЦ. Также будет ВЫБОР КОГДА "" = &СимволПробела ТОГДА "всегда" ИНАЧЕ "никогда" КОНЕЦ, где Запрос.УстановитьПараметр("СимволПробела", Сивол(32)).
19. MiCe 9 12.09.13 02:37 Сейчас в теме
так генерировать лучше
ВЫБРАТЬ  РАЗЛИЧНЫЕ ПЕРВЫЕ 2048
АдресныйКлассификатор.Код
поместить таб
ИЗ
	РегистрСведений.АдресныйКлассификатор КАК АдресныйКлассификатор;
ВЫБРАТЬ 
	КОЛИЧЕСТВО(таб.Код) номер
ИЗ
	таб КАК таб
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ таб КАК таб1
		ПО таб.Код >= таб1.Код

СГРУППИРОВАТЬ ПО
	таб.Код
упорядочить по КОЛИЧЕСТВО(таб.Код) 
Показать
21. ildarovich 7662 12.09.13 09:49 Сейчас в теме
(19) Категорически не согласен! - Ваш способ невероятно долог по сравнению с "Порождающим запросом" (с). Для примера попробуйте сгенерировать таблицу из миллиона чисел. Если хватит памяти, Вам придется подождать несколько дней. Порождающий запрос тратит на это доли секунды. Во вторых, не в каждой конфигурации есть адресный классификатор. Кстати, в конце статьи про порождающий запрос есть функция, которая генерирует ТЕКСТ ЗАПРОСА, формирующий в указанной таблице искусственную таблицу заданного диапазона чисел.
Вот как с использованием этой функции выглядит процедура генерации "ребер звезды" для обработки ГрафоГраф
Функция РебраЗвезды() Экспорт	
	Возврат НовыйЗапрос(	
	СтрЗаменить(ProtoText(ВсегоВершин), "r" + ВсегоВершин, "Числа") + ";" +	
	"ВЫБРАТЬ
	|	1 КАК Имя1,
	|	А.Х + 1 КАК Имя2,
	|	0.1 КАК Упругость
	|ИЗ
	|	Числа КАК А
	|ГДЕ
	|	А.Х > 0
	|
	|УПОРЯДОЧИТЬ ПО
	|	Имя1,
	|	Имя2"	
	).Выполнить().Выгрузить()
КонецФункции
Показать
ProtoText - это упомянутая функция. Видно, что код получается простым.
20. MiCe 9 12.09.13 02:48 Сейчас в теме
да... еще... в 1Сы используется кодировка utf8.... а в mssql utf16....
так что делайте выводы.... все строковые данные обрабатывает 1с сервер.... оттуда и проблема пробела....
22. таксяк 16.09.13 09:30 Сейчас в теме
"Многие сомневаются в возможности решения этой задачи одним пакетным запросом, а зря!" а кто сомневался-то? Сомнения были, что можно задачу решить не создавая код запроса программно - так и есть. Если есть возможность кодировать - то создавать запрос вообще не нужно.
Имхо - бессмысленное творение.
23. ildarovich 7662 16.09.13 09:56 Сейчас в теме
(22) Видимо, Вы что-то недопоняли: код запроса не формируется программно!!! Он записан в тексте статьи ПОЛНОСТЬЮ. В таком виде копируется в консоль запросов и решает задачу. Автор задачи согласился с тем, что задача решена в соответствии с заданием.
А у меня к Вам другой вопрос: в процессе обсуждения задачи Вы говорили о RCTE и прочих возможностях "сборки" агрегатной строки на SQL.
Если Вы такой большой знаток MSSQL, не могли бы Вы написать CTE (RCTE), которая собирала бы в одну строку таблицу из 2048 строк, в каждой строке которой будет по одному символу. Меня интересует время выполнения данной CTE. Вполне возможно, что оно будет больше, чем время выполнения запроса на 1С, составленный по предлагаемой методике.
24. p1l1gr1m 17.09.13 00:11 Сейчас в теме
Прочитав заголовок статьи, решил, что сначала надо самому додуматься до решения. Целый час ломал голову - как это сделать без заранее определенного количества соединений или подзапросов, в итоге сдался, прочитал - а вы оказывается пользуетесь определенным заранее количеством подзапросов в пакетном запросе. Да, это работает, да, это обусловлено ограничениями передаваемого типа строки, но все же это не flawless victory, а решение задачи с "допущениями")
dutlovva; madfox; MrFlanker; +3 Ответить
25. ildarovich 7662 17.09.13 10:05 Сейчас в теме
(24) Ваше разочарование похоже на разочарование ребенка, которому объяснили секрет фокуса. Но не становитесь, пожалуйста на сторону обывателя, который считает фокусы обманом и надувательством. С точки зрения фокусника, все его секреты - это хорошее знание законов физики, математики, химии и психологии.
В тот момент, когда я первый раз сказал, что знаю решение, я знал тот факт, что число записей в таблице любой СУБД КОНЕЧНО, помнил притчу о падишахе, зернышке и шахматной доске и имел запрос, который каскадно соединяет две строки в одну. Я полез разбираться в ограничениях СУБД, файловых систем и начал переводить терабайты в байты, чтобы узнать число необходимых соединений. Тогда в тех же ограничениях прочитал про максимальный размер строки, который может храниться в колонке таблицы. Ну и поскольку запрос возвращает именно таблицу, а не формирует файл, то стало понятно, что пользоваться нужно меньшим лимитирующим ограничением. Оно оказалось очень удобным - хватило всего 11 соединений. Так что в решении используется не допущение, а научный факт!
Кстати, на практике я использую динамическое построение запроса, которое здесь было запрещено правилами. При этом решение выглядит гораздо менее громоздким.
acanta; Serj1C; ColaKola; +3 Ответить
36. a1ex4ndr 5 04.09.14 17:51 Сейчас в теме
(24)
Да, это работает, да, это обусловлено ограничениями передаваемого типа строки, но все же это не flawless victory, а решение задачи с "допущениями")

Вроде претензий никаких и не было :)
26. MrFlanker 210 18.01.14 18:37 Сейчас в теме
Ну в принципе очевидное решение. Не очевиден расчет 11 итераций,....здесь присутствует элемент научной работы. Работа интересная в научном плане (для студента 1-3 курса например), имеет мало практического значения.

Выбор языка программирования и реализация монстроподобны.

Зато эрудиция автора, позволяющая использовать банальные демагогические приемы (см. Википедию) позволяет ему чувствовать себя достаточно уверенно на фоне чужих комментариев.
27. kiruha 388 03.06.14 11:14 Сейчас в теме
Интересно, забавно и не практично.
Еще с 7.7 народ понял что неограниченные строковые поля - это особы случай и нет никакого смысла пихать его в колонку для этого не предназначенную. В таких полях может быть сотни строк теоретически
В БД для этого даже используют спец типы.

На практике (1С!) достаточно получить "содержание" в отдельную таблицу, проиндексировать и получать его по мере вывода в табл документ. Аналогично со "сложением"
28. Pawlick 10 07.07.14 01:24 Сейчас в теме
Ув. ildarovich.
Вы пишите,что этим способом решена задача чистки артикулов. Ради спортивного интереса пробую решить подобную задачу с помощью Вашего метода в надежде добиться лучшего по времени результата по сравнению с тупым перебором. Очевидно, что в случае с артикулами, первоначальная таблица "Дано" должна распознаваться алгоритмом именно как коллекция значений для обработки (т.е. таблица артикулов, в которых что ли бо нужно изменить), а не как разобранное предложение, которое необходимо собрать.
К сожалению, у меня не хватило ума переписать запрос нужным образом и собрать передаваемые артикулы в первоначальное состояние. Если не затруднит: ткните носом в решение. Без Вашей помощи я видимо не разберусь.
PS.
Или же чистка артикулов происходит по одному, перебором?
29. ildarovich 7662 07.07.14 14:05 Сейчас в теме
(28) Pawlick, вот адаптированная обработка. Потребовалось добавить группировку по номеру строки. В расчете на то, что артикул будет не длиннее 64-х символов запрос получился таким
ВЫБРАТЬ Дано.НомерСтроки НомерСтроки, Дано.Колонка а ПОМЕСТИТЬ Дано ИЗ &Дано КАК Дано;
ВЫБРАТЬ 0 ё ПОМЕСТИТЬ Р0 ОБЪЕДИНИТЬ ВЫБРАТЬ 1;
ВЫБРАТЬ 2 * Р1.ё + Р0.ё ё ПОМЕСТИТЬ Р10 ИЗ Р0 Р1, Р0;
ВЫБРАТЬ 4 * Р32.ё + Р10.ё ё ПОМЕСТИТЬ Р3210 ИЗ Р10 Р32, Р10;
ВЫБРАТЬ 16 * Р54.ё + Р3210.ё + 1 ё ПОМЕСТИТЬ Р543210 ИЗ Р10 Р54, Р3210;
ВЫБРАТЬ НомерСтроки ж, ё, ВЫБОР ПОДСТРОКА(а, ё, 1) КОГДА "" "" ТОГДА ""_"" ИНАЧЕ ПОДСТРОКА(а, ё, 1) КОНЕЦ а ПОМЕСТИТЬ Буквы ИЗ Дано, Р543210 ГДЕ ПОДСТРОКА(а, ё, 1) + ""!"" <> ""!"";
ВЫБРАТЬ ж, ё, ВЫБОР КОГДА а ПОДОБНО ""[a-z,0-9]"" ТОГДА а ИНАЧЕ ""_"" КОНЕЦ а ПОМЕСТИТЬ Таб ИЗ Буквы;
ВЫБРАТЬ ж, ВЫРАЗИТЬ(ё/2 КАК ЧИСЛО(15,0)) е, ё, а ПОМЕСТИТЬ Шаг ИЗ Таб; УНИЧТОЖИТЬ Таб;
ВЫБРАТЬ ж, е ё, МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА а ИНАЧЕ """" КОНЕЦ) + МАКСИМУМ(ВЫБОР е*2-ё КОГДА 1 ТОГДА """" ИНАЧЕ а КОНЕЦ) а ПОМЕСТИТЬ Таб ИЗ Шаг СГРУППИРОВАТЬ ПО ж, е; УНИЧТОЖИТЬ Шаг;
...еще пять повторов...
ВЫБРАТЬ ж НомерСтроки, а КОЛОНКА ИЗ Таб УПОРЯДОЧИТЬ ПО ж
Условие правильности символа в артикуле - это либо латинские буквы, либо цифры. Все другие символы заменяются неразрывным пробелом. Правило легко поменять вплоть до использования таблицы замен.
Прикрепленные файлы:
ОчисткаАртикулов.erf
30. Pawlick 10 07.07.14 14:24 Сейчас в теме
(29)
спасибо огромное, Щас буду пробовать.
31. u_n_k_n_o_w_n 33 21.07.14 06:41 Сейчас в теме
Добрый день!
Пытаюсь разобраться с Вашей статьей.
Ника не могу понять фразу: "Соединим для начала попарно все соседние нечетные и четные строки."
Тогда у вас должна получиться примерно следующая таблица:
е ё а
1 1 Строка1
1 2 Строка2
2 пропускаем так, как четная
3 2 Строка2
3 4 Строка4
4 пропускаем так, как четная
5 4 Строка5
5 6 Строка5
и т.д.

тогда получается что нечетные строки, суммируются несколько раз.
Правильней я думаю будет фраза: "Соединим для начала попарно все нечетные и четную строку, следующую за нечетной."

ildarovich; +1 Ответить
32. ildarovich 7662 21.07.14 09:18 Сейчас в теме
(31) u_n_k_n_o_w_n, да, возможно, предложение получилось двусмысленным. Можно было написать так:
...Соединим для начала попарно каждую нечетную со следующей за ней четной строкой...
Чуть длиннее, но, кажется, более точно. - Поправлю в статье при случае.
u_n_k_n_o_w_n; +1 Ответить
33. u_n_k_n_o_w_n 33 22.07.14 11:56 Сейчас в теме
Добрый день!
Есть ТЗ со следующей структурой:
ПГ1; ПГ2,КОД, ТС.
Где ПГ1 – поле группировки 1, ПГ2 – поле группировки 2, Код – уникальные номера (начинаются с 1) в рамках полей группировки, ТС – текстовое поле для суммирования.
ТЗ содержит N количество строк.
Подскажите можно ли применить Ваш запрос в моем случае.
Спасибо.
PS: Долго думал, как мне можно доработать Запрос под свои цели, но пока не получается.
34. ildarovich 7662 23.07.14 17:44 Сейчас в теме
(33) u_n_k_n_o_w_n, вот обработка с готовым запросом. От запроса в статье он отличается дополнительными группировками по ПГ1, ПГ2
Прикрепленные файлы:
СпецКонкатенация.erf
proger1c81; u_n_k_n_o_w_n; +2 Ответить
35. u_n_k_n_o_w_n 33 23.07.14 16:25 Сейчас в теме
Спасибо огромное, буду пытаться освоить науку.
37. BigB 187 02.10.14 20:17 Сейчас в теме
БРАВО! (стоя хлопаю в ладоши)
38. Steelvan 272 09.03.15 13:20 Сейчас в теме
Заголовок "Агрегатное суммирование строк в запросе – сложно, но не невозможно" как то звучит по-американски (двойное отрицание усложняет восприятие).

Думается мне, что
"Агрегатное суммирование строк в запросе – сложно, но возможно" будет звучать по-русски (нормально, и даже немного в рифму).
39. ildarovich 7662 09.03.15 17:58 Сейчас в теме
40. нормальный такой 92 18.03.15 16:12 Сейчас в теме
Привет, чет ошибку сыпет на 8,3,4
эт нормально?

http://take.ms/ObhsZ
41. ildarovich 7662 18.03.15 17:06 Сейчас в теме
(40) нормальный такой, это НЕ нормально, все должно работать. Если меняли запрос, приведите его полный текст. И что задавали в параметрах. Чтобы я мог попытаться воспроизвести ошибку.
Вообще поле "а" формируется на предыдущих шагах запроса. Как подстрока длины 1. Как оно стало неограниченным мне непонятно.
Давайте разбираться.
42. нормальный такой 92 18.03.15 17:40 Сейчас в теме
(41) неа, не менял.
Скопировал как представлено в шапке, вставил в конструктор запроса и получил такую ошибку.
Сейчас посидел поковырял Ваш запрос и понял примерно что происходит.
На N итерации возникает вот такая ошибка как я привел, если сократить запрос до N-1 итераций, то ошибки не возникает.
46. ildarovich 7662 13.06.15 13:02 Сейчас в теме
(42) нормальный такой, извините, забыл в свое время ответить, в чем я разобрался.

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

Но при практических экспериментах в большинстве случаев ограничением является большее число - 2048, что и было использовано мною в статье. Система (где 1024, где 2048) безусловно есть, но я не стал детально это исследовать.
43. пользователь 08.06.15 08:56
Сообщение было скрыто модератором.
...
47. proger1c81 29.02.16 10:52 Сейчас в теме
Добрый день, Маэстро запросов!
Думал, что никогда мне на практике не понадобится суммирование строк....
но как говорится: "никогда не говори никогда"....
Помогите, пожалуйста, написать запрос для ТЗ со следующей структурой:
ПГ; ТС.
Где ПГ – поле группировки, ТС – текстовое поле для суммирования.
ТЗ содержит N количество строк.

и подскажите, пожалуйста, как можно задать разделитель строк?
например: как у вас показано на скриншоте выше:
петух ку
петух ка
петух ре
петух куу
корова му
корова муу
собака
Если задать разделитель строк "-", в результате должно получиться три строки:
петух ку-ка-ре-куу
корова му-муу
собака
причем в конце разделитель осутствует
48. ildarovich 7662 29.02.16 12:01 Сейчас в теме
(47) proger1c81, мне кажется, что лучше всего скачать файл, прикрепленный к сообщению (34) в данной теме. Там можно вообще ничего не менять, определив поле ПГ2 = 0. То есть там все уже готово. Если что-то будет не получаться, сообщите.
По поводу разделителей: то же самое. Достаточно вместо поля ТС в исходной таблице взять Разделитель + ТС КАК ТС. Получится все, как вам нужно, но в самом начале итоговой строки будет один лишний разделитель (-ку-ка-ре-ку). Поэтому потребуется к итоговому полю применить выражение ПОДСТРОКА(а, 2, 1024), чтобы убрать этот лишний начальный разделитель.
49. proger1c81 29.02.16 13:14 Сейчас в теме
(48) я попробовал указанный файл прежде чем задать вопрос. Т.к. там запрос сделан с учетом уникального поля "Код", а моя структура ТЗ отличается как раз отсутствием этого уникального поля "Код". Если я беру ту структуру и делаю ПГ2=0 и Код=0, то суммирование строк не происходит.
50. ildarovich 7662 29.02.16 17:22 Сейчас в теме
(49) proger1c81, теперь понял в чем дело.
Но это уже принципиальный вопрос. Дело в том, что сложить строки без наличия такого уникального кода НЕЛЬЗЯ. Принципиально нельзя. И вне запроса, кстати, тоже. Это и в статье и в комментариях к исходному обсуждению обсуждалось. Так как сложение строк не коммутативно, то есть принципиально требует указания их порядка в сложении. Поэтому поле код (или номер) нужно получить. Например, соединив исходную таблицу саму с собой по условию ПГ = ПГ И КакоеЛибоПоле >= КакоеЛибоПоле и посчитав число записей самосоединяемой таблицы, удовлетворяющих этому условию.
51. proger1c81 01.03.16 10:23 Сейчас в теме
(50) Спасибо за данную статью! Невозможное стало возможным!
Встроенная функция СКД СуммироватьСтроки() в моем случае не помогала, т.к. все ресурсы (числовые, строковые через СуммироватьСтроки()) выводятся в конце таблицы. Может быть СКД и позволяет выводить ресурсы в начале или в середине таблицы, но я не знаю, как это сделать. А у меня задача стояла, чтобы результирующее поле "суммированная строка" располагалось в любом месте (в начале, середине). В результате получил таблицу следующего вида (см.скриншот)
Прикрепленные файлы:
52. herfis 468 01.03.16 10:51 Сейчас в теме
(51) proger1c81, Задача вывода ресурсов в произвольном месте в СКД легко решалась с помощью специальной группировки. А с какого-то релиза это штатная возможность: в настройках СКД "Другие настройки", опция "Авто позиция ресурсов". По дефолту установлено старое поведение "После всех полей" для лучшей обратной совместимости. Достаточно переклацнуть на "Не использовать".
53. proger1c81 02.03.16 10:43 Сейчас в теме
(52) herfis, Спасибо за подсказку о штатной возможности в СКД размещения ресурсов.
Подскажите, как в СКД с помощью функции СуммироватьСтроки() указать нужный разделитель. СКД сцепляет строки с помощью символа Переноса строки, что по моему условию задачи не подходит.
Вот как получается с помощью СКД (см.скриншот):
Прикрепленные файлы:
54. palsergeich 11.03.17 20:32 Сейчас в теме
(53) 2м параметром передайте разделитель в строковом ввиде
55. user1073248 31.08.20 12:51 Сейчас в теме
А существует ли какая-то возможность приобрести обработку не за стартмани? Я бы заплатил.
56. Dzenn 794 11.03.21 17:10 Сейчас в теме
Такие запросы — это верный способ принять смерть от рук следующего программиста ;-)
57. twilight_dream 16.03.21 11:19 Сейчас в теме
я тупой ничего не понял. Откуда взялось Р1.ё во второй строке, если таблицы Р1 нет в запросе?
58. ildarovich 7662 17.03.21 12:51 Сейчас в теме
(57) В запросе есть Р0. Р1 - это алиас той же таблицы.
ВЫБРАТЬ 0 ё ПОМЕСТИТЬ Р0 ОБЪЕДИНИТЬ ВЫБРАТЬ 1;
ВЫБРАТЬ 2 * Р1.ё + Р0.ё ё ПОМЕСТИТЬ Р10 ИЗ Р0 Р1, Р0;
Здесь намеренно, для краткости, пропущено слово "КАК". Синтаксис это допускает.

Возможно, вам понятнее было бы так:
ВЫБРАТЬ 
     0 КАК ё 
ПОМЕСТИТЬ Р0 

ОБЪЕДИНИТЬ 

ВЫБРАТЬ 
     1
;
////////////////////////////////////////////////
ВЫБРАТЬ 
     2 * Р1.ё + Р0.ё КАК ё 
ПОМЕСТИТЬ Р10 
ИЗ 
     Р0 КАК Р1, 
     Р0 КАК Р0
;
...
Показать
Собственно, все это, скорее, этюд по программированию на языке запросов, упражнение. На практике можно применять в крайнем случае. Людям, не любящим головоломки, такие запросы лучше обходить стороной.
Да и в 20-й платформе уже будет преобразование типов в запросе. Подождать осталось совсем немного.
Оставьте свое сообщение

См. также

АВС-анализ и табличное программирование

Математика и алгоритмы Анализ учета Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Абонемент ($m)

Представлен простейший алгоритм решения задачи АВС-анализа. На данном примере продемонстрирован метод табличного программирования, описанный в книге "Совершенный код. Мастер-класс", автор Стив Макконнелл.

2 стартмани

16.12.2022    1947    RustIG    6    

15

Если хочется низко-низкоуровневого программирования с битами и байтами

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Все знают, что подавляющее большинство современных компьютеров работает в двоичном коде, т.е. оперирует всего двумя значениями - битами - "0" и "1". Потом из них складываются байты, слова, кило-, мега- и гигабайты etc. Но что происходит внутри процессора, как именно обрабатываются двоичные числа, например выполняются арифметические операции? Об этом — в публикации. Статья, я думаю, будет особенно интересна тем читателям, у которых во время обучения не было соответствующих курсов.

1 стартмани

01.12.2022    750    Alxby    16    

9

Если хочется функционального программирования с функциями высшего порядка и map, filter, reduce

Математика и алгоритмы Универсальные функции Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

07.07.2022    2272    Alxby    42    

16

Работа с абстрактным массивом

Математика и алгоритмы Универсальные функции Платформа 1С v8.3 Россия Абонемент ($m)

Абстрактные типы данных и алгоритмы уверенно набирают популярность в языках общего назначения. Встроенный язык 1С является предметно-ориентированным и не спешит развиваться в сторону поддержки абстракций. Однако потребность в них существует, т.к. задачи, решаемые на платформе, не уступают разнообразию из других ЯП. Предлагаю рассмотреть вариант реализации абстрактного массива в 1С.

1 стартмани

07.07.2021    6350    kalyaka    57    

31

Работа с 1С:Аналитика Промо

Онлайн-курс предусматривает изучение возможностей системы “1С:Аналитика”, которая работает как составная часть платформы “1С:Предприятие” и обеспечивает оперативный просмотр и анализ необходимых данных.

4500 рублей

10 способов получить модуль числа (а может, и больше)

Математика и алгоритмы Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    25224    sam441    36    

54

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

Математика и алгоритмы Платформа 1С v8.3 1С:Бухгалтерия 3.0 Россия Абонемент ($m)

Создание собственного, отличного от платформенного алгоритма нумерации документов определенного вида.

1 стартмани

11.04.2019    6855    xan333    12    

5

Основы компьютерной графики (Часть 2)

Математика и алгоритмы Работа с интерфейсом Управляемые формы Конфигурации 1cv8 Россия Абонемент ($m)

Статья является продолжением публикации "Основы компьютерной графики". Во второй части будут рассмотрены следующие темы: 1. Преобразования в трехмерном пространстве. 2. Ортографическая проекция трехмерного изображения на экран. 3. Определение, какой поверхностью (лицевой/задней) проецируется грань на экран. 4. Перспективная проекция.

1 стартмани

03.08.2018    6941    HAMMER_59    13    

14

Основы компьютерной графики

Математика и алгоритмы Работа с интерфейсом Управляемые формы Конфигурации 1cv8 Абонемент ($m)

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

1 стартмани

30.07.2018    8760    HAMMER_59    39    

25

Распознавание и загрузка документов в 1С Промо

Универсальная программа-обработка для распознавания любых сканов или фото первичных документов в 1С (счета-фактуры, УПД, ТТН, акты и тд). Точность распознания до 98%.

от 11 рублей

Любое число больше 7 можно разложить на сумму троек и пятерок

Математика и алгоритмы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Абонемент ($m)

Наткнулся в интернете на школьную задачу: "Докажите, что любое число больше 7 можно представить в качестве суммы чисел 3 и 5". Представляю решение на 1С. (есть рекурсия, пример работы с событием ИзменениеТекстаРедактирования).

1 стартмани

06.07.2018    7156    Eskimos    6    

6

Итераторы выборки

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

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

1 стартмани

16.05.2018    10347    kalyaka    10    

9

Строим "фасады" в 1С

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Как реализовать функционал, чтобы не было “мучительно больно” при расширении требований.

1 стартмани

04.05.2018    18874    ktb    41    

66

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    41053    rpgshnik    60    

136

Случайность, совпадение, закономерность. Генератор случайных чисел

Математика и алгоритмы Игры Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Объект ГенераторСлучайныхЧисел удобно выдает случайные числа в заданном интервале значений. Исследование особенностей, рассуждения на тему случайных чисел, практика применения. Увлекательно в игровой форме можно исследовать работу генератора случайных чисел.

1 стартмани

20.01.2018    56363    Ликреонский    61    

8

Программы для исполнения 54-ФЗ Промо

С 01.02.2017 контрольно-кассовая техника должна отправлять электронные версии чеков оператору фискальных данных - правила установлены в 54-ФЗ ст.2 п.2. Инфостарт предлагает подборку программ, связанных с применением 54-ФЗ, ККТ и электронных чеков.

Черпаем простые числа решетом Аткина

Математика и алгоритмы Запросы Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

09.01.2018    9688    scientes    7    

8

Преобразование массива структур в дерево значений. Представление массива подчиненных друг другу "объектов" в иерархическом виде без использования рекурсии

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Задача преобразовать массив некоторых структур в дерево значений возникла, когда я получил JSON от сервиса о структуре папок пользователя. А именно строка JSON была получена через API Google Drive, когда пользователю предлагается выбрать одну из его папок. При преобразовании JSON у меня получился массив структур, в которых есть некоторый ключ уникальности и ключ родителя-структуры. Предлагаю ознакомиться с алгоритмом не использующую рекурсию, который достаточно быстро создает дерево значений, для последующего показа пользователю.

1 стартмани

07.11.2017    14559    Arxxximed    15    

11

Github и 1С. Пошаговая инструкция на конкретном примере

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Статья для тех, у кого есть неудержимое желание программировать и хочется доработать какую-то конфигурацию (или проект на 1С), выложенный на Github, но останавливают незнакомые слова Git, Github, Fork, Commit, Pull request, Merge, Issue.

1 стартмани

26.10.2017    55813    BlizD    61    

275

Сборка автомата (с примерами)

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Посмотрим, нужен ли 1снику автомат, как его собрать и где это может пригодиться.

1 стартмани

19.09.2017    15214    pm74    45    

38

Простой способ индексирования интервалов

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

28.09.2016    43992    ildarovich    22    

212

Видеокурс-практикум: как подготовить и написать ТЗ, ЗНР, ЧТЗ. Промо

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

3 500 рублей

Разбиение / "суммирование" строк в запросе

Запросы Платформа 1С v8.3 Бесплатно (free)

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

13.10.2015    15542    ditp    12    

42

Степень сходства двух наименований справочника

Математика и алгоритмы Платформа 1С v7.7 Платформа 1С v8.3 Абонемент ($m)

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

1 стартмани

25.02.2015    23249    etmarket    46    

17

Как нарисовать граф на 1С

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Описывается реализация на языке запросов 1С метода расположения вершин графа на плоскости, основанного на использовании электромеханической аналогии. При этом вершины графа представляются одноименными электрическими зарядами, дуги - пружинками. Силы взаимодействия вершин в этой системе переводят их из случайного начального в нужное конечное положение. Приведена обработка рисования графов "ГрафОграф", реализующая данный подход, показывающая также динамику процесса. Граф можно задать списком ребер вручную, выбрать из нескольких предопределенных примеров или сформировать по данным информационной базы.

1 стартмани

09.08.2013    76161    ildarovich    117    

414

АЦРК: Многовариантный автоматический запрет редактирования (для конфигурации УТ 10.3)

Закрытие периода Математика и алгоритмы Инструменты администратора БД Платформа 1С v8.3 1С:Управление торговлей 10 Абонемент ($m)

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

1 стартмани

22.07.2013    21661    acrk    9    

9

Разработка многоязычной системы

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

В статье затронуты некоторые аспекты многоязычности системы с точки зрения их технической реализации

1 стартмани

20.06.2013    22766    obemgyorik    54    

33

Готовые переносы данных из различных конфигураций 1C Промо

Рекомендуем готовые решения для переноса данных из различных конфигураций 1C. C техподдержкой от разработчиков и гарантией от Инфостарт.

Передача аргумента, полученного по ComConnector, на сервер

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

С точки зрения инкапсуляции, данные, переданные по COMConnector, следует обрабатывать в базе-приемнике. И тут возникает проблема, малопонятная для новичка из-за сложностей в отладке модуля внешнего соединения. Аргументы попросту не передаются в серверные модули.

1 стартмани

20.03.2013    6670    asved.ru    3    

4

INFOSTART EVENT 2012: разбор решений конкурса разработчиков

Математика и алгоритмы Запросы Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

В статье проводится разбор присланных решений на конкурс разработчиков от компании "Первый БИТ". Приводятся планы выполнения запросов и сравниваются показатели быстродействия и оптимизации.

1 стартмани

25.12.2012    16022    krolya    49    

39

Алгоритм определения вхождения точки в полигон

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Нередко встает необходимость ведения аналитики по территориальному признаку. Вручную, человеческими руками определить к какому региону относится контрагент, адрес доставки, розничная точка или ещё что-либо проблем не составляет. А если этих точек необходимо обрабатывать 500 в день или даже больше? Задача становится трудоемкой и её решение таким образом не рационально. Можно ли это сделать автоматически?

1 стартмани

28.11.2012    27399    logos    29    

46

Опять двойка!

Математика и алгоритмы Платформа 1С v8.3 Абонемент ($m)

Продолжение тем, связанных с использованием степеней двойки «Порождающий запрос» [http://infostart.ru/public/90367/], «Транзитивное замыкание запросом» [http://infostart.ru/public/158512/]. На этот раз речь пойдет об операциях со строками.

1 стартмани

26.11.2012    32203    ildarovich    31    

58

Объектно-ориентированный взгляд на программирование в 1С

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Рассматриваем программирование в 1С как работу с объектами и классами.

1 стартмани

18.04.2012    35639    BorisMor    241    

127

Программы для исполнения 488-ФЗ: Маркировка товаров Промо

1 января 2019 года вступил в силу ФЗ от 25.12.2018 № 488-ФЗ о единой информационной системе маркировки товаров с использованием контрольных (идентификационных) знаков, который позволяет проследить движение товара от производителя до конечного потребителя. Инфостарт предлагает подборку программ, связанных с применением 488-ФЗ и маркировкой товаров.

Использование нарастающих итогов в партионном учете и не только

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Данный материал является иллюстрацией способов работы с запросами, использующими методику вычисления «нарастающих итогов». Также в данной статье рассматриваются вопросы практического использования запросов такого рода при партионном учете и расчете задолженностей. Фактически в данной статье рассматриваются альтернативы запросам, приведенным в статьях http://infostart.ru/public/61295/ и http://infostart.ru/public/68225/. Полный текст статьи можно также найти на http://nashe1c.ru/materials-view.jsp?id=383.

1 стартмани

25.08.2011    14980    y-str    107    

11

Модуль менеджера или статические методы класса?

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Зачем в платформе 8.2 добавили модуль менеджера объекта, как его использовать? Попробуем разобраться.

1 стартмани

02.07.2010    68262    zfilin    97    

338

Как я победил блокировки (deadlock)

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Статья о том, как сделать работу нормальной, комфортной для пользователей, в большой базе с большим количеством пользователей.

1 стартмани

28.09.2009    22423    Minotavrik    64    

94