"Распределение в запросе" или "избавляемся от перебора"

Публикация № 568299

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

запросы распределение перебор оптимизация серии

182
Хороший перебор - это отсутствие перебора. Рассмотрим пример замены полного перебора запросом.

В свое время, года 3 назад, возникла необходимость оптимизации конфигурации и устранения ее узких мест в одной компании. Одним из таких узких мест оказался, казалось бы, безобидный, механизм распределения товаров в реализации по сериям. Суть в том, что строк распределялось достаточно много и было это очень медленно. Не миллионы за раз, конечно, но на это самое распределение для одного документа могло уходить до минуты. От этого становилось всем очень грустно, т.к. параллельно бухгалтера препроводили документы, другие операторы тоже формировали документы отгрузки и когда отгружали «большого» клиента – жизнь на некоторое время замирала. К слову сказать, размер базы 1С за 2-3 года на тот момент составлял ~500 Гб, заказов от одного клиента за день могло прийти десяток-другой, а в некоторых из них строк могло быть более 1000, в общем «Реализация товаров и услуг» на 1000 строк - это не было ничем сверхъестественным. Реиндексация, обновление статистики, шринк и другие необходимые процедуры проводились регулярно, но сейчас речь не об этом. Вернемся к нашему объекту оптимизации. На тот момент механизм распределения был до банального прост:

  1. Запросом получали остатки по сериям (Номенклатура – Серия – Количество)
  2. Другим запросом получали таблицу товаров к отгрузке (Номенклатура – Заказ покупателя – Количество). 
  3. Проходил обыкновенный перебор для каждой номенклатуры по принципу «Пока КоличествоКРаспределению > 0 Цикл …….. ». 

Т.к. я всегда придерживался позиции, что сам факт перебора на больших объемах данных – это уже само по себе узкое место, то возможность «улучшения» алгоритма перебора я даже рассматривать не планировал. Нужна была альтернатива. Также на тот момент я уже давно набил руку в оптимизации сложных запросов и укрепился в выводе, что нет ни одной задачи, которую нельзя было бы решить исключительно запросом и точно знал, что качественный запрос (пакет запросов) в 99% случаев окажется самым эффективным решением, чем какая-либо пост-обработка результатов запроса. Вопрос оставался только в нахождении этого решения). 
Выходил я на перекур с достаточно тривиальным условием задачи (распределить количество по измерениям одной таблицы на количество по измерениям из другой) и 2-мя тезисами:

  • Мы имеем 2 таблицы, которые и так собираются запросом
  • SQL не знает никакого «Распределить». SQL знает только «больше», «меньше», «равно» (утрированно). Надо дать ему некий параметр для сравнения. Числовой параметр, по которому будет понятно какое количество еще можно распределить в условную строку. 

И в этот самый момент, когда я мысленно проговаривал второй тезис, слово «еще» и натолкнуло меня на решение. Далее, рисуя палочкой на снегу, я не успел докурить, как уже побежал пробовать свою гипотезу в консоли запросов.
Рассмотрим ниже простой пример:
У нас есть складские ячейки с количеством вмещаемого в них товара с одной стороны (A, B, C, D) и сам товар (X, Y, Z), который необходимо «как-то» разложить по этим ячейкам, но так, чтоб в ячейку не положили больше товара, чем может быть в ней места. 
A – 10 мест
B – 1 место
C – 5 мест
D – 8 мест

X – 13 шт
Y – 1 шт
Z – 4 шт

Результатом должна стать таблица распределения:
A-X-10
B-X-1
C-X-2
C-Y-1
C-Z-2
D-Z-2

Для этого нам надо определить порядок распределения, сделать это оказалось до банального просто:

ВЫБРАТЬ
    Ячейки.Ячейка КАК Ячейка,
    Ячейки.Количество,
    ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + 1 КАК ПорядокРаспределенияС,
    ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + Ячейки.Количество КАК ПорядокРаспределенияПо
ИЗ
    Ячейки КАК Ячейки
        ЛЕВОЕ СОЕДИНЕНИЕ Ячейки КАК Ячейки1
        ПО Ячейки.Ячейка > Ячейки1.Ячейка

СГРУППИРОВАТЬ ПО
    Ячейки.Ячейка,
    Ячейки.Количество


Кстати, здесь же можно учесть и порядок распределения, если, например, в какие-то ячейки товар надо класть в первую очередь. Решается изменением условия в соединении. 
Тоже самое и с товарами:

ВЫБРАТЬ
    Товары.Товар КАК Товар,
    Товары.Количество,
    ЕСТЬNULL(СУММА(Товары1.Количество), 0) + 1 КАК ПорядокРаспределенияС,
    ЕСТЬNULL(СУММА(Товары1.Количество), 0) + Товары.Количество КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ТоварыПоПорядку
ИЗ
    Товары КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Товары КАК Товары1
        ПО Товары.Товар > Товары1.Товар

СГРУППИРОВАТЬ ПО
    Товары.Товар,
    Товары.Количество

Для простоты понимания разложу все эти позиции поштучно в таблице и наложу одну на другую в порядке распределения:

Нам просто нужно написать граничные условия. А теперь осталось просто соединить эти таблицы и получим наш результат:

ВЫБРАТЬ
    ЯчейкиПоПорядку.Ячейка КАК Ячейка,
    ТоварыПоПорядку.Товар КАК Товар,
    ВЫБОР
        КОГДА ТоварыПоПорядку.ПорядокРаспределенияПо < ЯчейкиПоПорядку.ПорядокРаспределенияПо
            ТОГДА ТоварыПоПорядку.ПорядокРаспределенияПо
        ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияПо
    КОНЕЦ - ВЫБОР
        КОГДА ТоварыПоПорядку.ПорядокРаспределенияС > ЯчейкиПоПорядку.ПорядокРаспределенияС
            ТОГДА ТоварыПоПорядку.ПорядокРаспределенияС
        ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияС
    КОНЕЦ + 1 КАК Количество
ИЗ
    ЯчейкиПоПорядку КАК ЯчейкиПоПорядку
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТоварыПоПорядку КАК ТоварыПоПорядку
        ПО (ЯчейкиПоПорядку.ПорядокРаспределенияС <= ТоварыПоПорядку.ПорядокРаспределенияПо
                И ЯчейкиПоПорядку.ПорядокРаспределенияПо >= ТоварыПоПорядку.ПорядокРаспределенияС)

Сразу оговорюсь, что в запросе умышленно добавлено большее количество полей, чем надо. Можно было бы обойтись и одной границей распределения (нарастающим итогом) и не делать «+1», но как мне показалось – в таком виде это более наглядно для понимания. Оптимизацию запросов мы в этой теме не рассматриваем, поэтому и индексы здесь тоже не описаны. Ну а более сложные алгоритмы распределения (по нескольким измерениям, например) решаются только изменением условий соединения и проверки границ.

Вот и все. В итоге вместо минут ожидания на тех же объемах данных этот запрос выполнялся считанные милисекунды.

Прошу простить за обилие лирики в этой статье. Хотелось дать не математическое решение узкой задачи, а поделиться концептуальным подходом к решению подобных задач, именно ходом своих мыслей. Ну а также сделайте скидку на то, что это первая в моей жизни статья :)

182

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

Лучшие комментарии
23. ildarovich 6716 16.12.16 15:30 Сейчас в теме
Еще один пример того, что новое - это хорошо забытое старое
Вот ссылки:

http://infostart.ru/public/20221/
http://infostart.ru/public/58966/
http://infostart.ru/public/61295/
http://infostart.ru/public/62899/
http://infostart.ru/public/68225/
http://infostart.ru/public/88999/
http://infostart.ru/public/122548/

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

Теперь по сути:

В данном случае слишком упрощенно и неправильно противопоставлять запросную и внезапросную технику.
Рассуждения "сделаю запросом - так всегда будет быстрее" просто-напросто ошибочные и даже вредные.
Думаю, большой эффект в этом конкретном случае был не потому, что запросом лучше, а потому, что код ("перебор") был очень плохой.
Например, из-за того, что какие-то поля типа коэффициента единиц измерения мелкими запросами в цикле из базы дергались. Или индекса в таблице значений не было.

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

В общем, я против крайностей и "универсальных решений", за более взвешенное и обдуманное решение в каждом конкретном случае.
Krio2; apk-agroeco; 1cWin; hornet_X; hydro2588_2015; mason; Silenser; dbaser; 1cprogr_nsk; igormiro; Rego1337h; Andrsan; unichkin; PrinzOfMunchen; ra9000; sasha777666; h00k; Ali1976; sevushka; kuzyara; DrAku1a; sorb; ASysuev; PetrPan; Zabava_; varovinm; zarucheisky; MSChe; Dem1urg; bong; ABudnikov; Danil.Potapov; kiros; Chif13; nsirotkin@mail.ru; HAMMER_59; ZLENKO; soulsteps; brr; Turn123; Dach; Бывалый77; KoldunOne; Новиков; le0nid; Leoway; Sheff; hulio; Saint13; support; ILM; 1cmax; bulpi; Сурикат; genayo; starik-2005; c1nil; Alias; Armando; SunShinne; karpik666; uncle_Vasya; ardn; корум; ЧерныйКот; odin777; NeviD; +67 Ответить
Остальные комментарии
Избранное Подписка Сортировка: Древо
1. coollerinc 40 16.12.16 11:15 Сейчас в теме
Пытаюсь воспроизвести пример не получается, смущает, это сравнение "ПО Ячейки.Ячейка > Ячейки1.Ячейка" и "Товары.Товар > Товары1.Товар"

Это ссылки сравниваем?
2. alexandersh 207 16.12.16 11:27 Сейчас в теме
(1) Можно сравнивать любой реквизит, если он уникален и его тип допускает операции сравнения, но только ссылки точно гарантируют уникальность. В моем примере сравнивались ссылки.
3. alexandersh 207 16.12.16 11:29 Сейчас в теме
Ну а тестовый образец запроса можно сделать вообще на строковых данных )

выбрать "А" как Товар, 111 как Количество
поместить Товары

объединить

выбрать "Б" ....

и т.д.
4. coollerinc 40 16.12.16 12:24 Сейчас в теме
Спасибо все работает, это просто я офигел немного от такого подхода к запросам, для меня это в новинку. Срин шот прикладываю, которым можно дополнить статью
Прикрепленные файлы:
Innuil; klinval; +2 Ответить
6. alexandersh 207 16.12.16 12:57 Сейчас в теме
(4) Рад, если статья оказалась полезная ;)
7. sashocq 191 16.12.16 13:17 Сейчас в теме
Это гениально!
Прочитав постановку задачу ожидал большую кучу подзапросов с временными запросами. Но решение оказалось на удивление элегантным. Сохраню себе, пригодится.
8. Just4Fun 27 16.12.16 13:19 Сейчас в теме
Хорошее решение. Рекомендую.

Была аналогичная задача при закрытии месяца в УПП.
В типовом алгоритме был фрагмент кода, который строил большую таблицу перехода номенклатуры из одного состояния другое. А реализовано это было через "цикл в цикле" по таблице в 20 тыс. строк, что в итоге давало 400 млн итераций, и в свою очередь общее время проведения документа составляло 3-4 часа по каждому из разделов учета (БУ, НУ, УПР).
Здесь даже была статья по этой проблеме и ее решению. http://infostart.ru/public/176644/
Попробовал решение из статьи - эффект был, но не скажу, что проблема ушла. выигрыш был порядка 10%.

Несколько дней ходил и крутил проблему в голове. Идея, как и у автора текущей статьи, осенила неожиданно.
В итоге переложил типовой цикл на запрос и время его выполнения составило что-то около 3-5 секунд, а общее время проведения документа - несколько минут.
9. МихаилМ 16.12.16 13:52 Сейчас в теме
к сожалению 1с8 не умеет сравнивать ссылки на болше-меньше в запросе
хоть не ругается на эту ошибку.
поэтому,

Товары.Товар > Товары1.Товар - ошибочная конструкция.

dgolovanov; +1 2 Ответить
10. NeviD 16.12.16 13:56 Сейчас в теме
(9) Разве не умеет? Сам не раз так делал - всегда отлично отрабатывает.
Например, для нумерации данных во временной таблице. Так как в 1С нет подобия ROW_NUMBER, то для нумерации можно соединять таблицу саму с собой с сравнением по Таблица1.Ссылка > Таблица2.Ссылка.
И все хорошо работало.
11. alexandersh 207 16.12.16 14:18 Сейчас в теме
(9) Михаил, вопрос на засыпку: а SQL Server Engine умеет сравнивать UNIQUEIDENTIFIER на больше-меньше? ;-)
а то вы только что открытие для меня сделали))
12. alexandersh 207 16.12.16 14:19 Сейчас в теме
а вообще, ребята, спасибо всем за отзывы, прямо воодушевили меня покопаться в закромах, где-то есть у меня еще несколько старых примеров обработки больших объемов данных запросами.. может руки дойдут - напишу еще статейку )
uncle_Vasya; +1 Ответить
13. vasilev2015 1411 16.12.16 15:03 Сейчас в теме
Коллеги, запрос тоже может при исполнении запускать перебор.

Не обольщайтесь внешним видом.

Выигрыш может быть за счет переноса нагрузки на сервер
Или за счет использования поиска по индексу вместо перебора.

Например, в объектной модели программирования Таблицу значений индексировать командой ДобавитьИндекс и использовать НайтиСтроки(Отбор) вместо Для Каждого Строка ИЗ ТаблицаЗначений.

Статья не плюсовая, а скорее минусовая.
sasha777666; uncle_Vasya; +2 Ответить
15. alexandersh 207 16.12.16 15:09 Сейчас в теме
(13) Николай, я всегда за критику, но только когда она конструктивная. Если интересно - посмотри подобный запрос в профайлере и сравни с отбором по таблице значний (даже при добавлении индекса), результат кардинально будет отличаться. Это первое. Ну а второе - по поводу перебора в запросе - Не могу себе представить ситуацию, когда соединение по ключевым индексированным полям (Ref) вызовут в SQL перебор. Такого даже при желании не так просто добиться, или я не прав? ;-)
uncle_Vasya; +1 Ответить
14. МихаилМ 16.12.16 15:05 Сейчас в теме
извините. ошибся . но с с другими типами данных ссылки не умеет сравнивать , хотя и не ругается
19. alexandersh 207 16.12.16 15:16 Сейчас в теме
(14) Ах, речь о сравнении ссылок с другими типами... ну да, забавно ))
"Хозяйке на заметку": запрос вида "выбрать датавремя(2016,1,1,1,1,30) < 3.14" тоже ошибки не вызовет, однако его целесообразность и практический смысл лично для меня сомнительны)
uncle_Vasya; +1 Ответить
16. Fragster 928 16.12.16 15:13 Сейчас в теме
а теперь смотрим. допустим у нас склад с 1000 ячеек. (или остатки с 1000 мелких партий или еще что-то). первым запросом мы получаем 1000000 строк и далее тот же цикл происходит на стороне скуля (nested loops в плане запросов), только не 1000 строк, а 1000000.
uncle_Vasya; +1 Ответить
18. МихаилМ 16.12.16 15:15 Сейчас в теме
дополню
SQL Server Engine
умеет сравнивать bynary(16) c числами
но
1с8 в запросе к субд заменяет конструкцию типа ссылка > число

на истина ()

и

ссылка < число - на ложь .

прошу еще раз прощения за замечание не по делу.


умеет ли SQL Server Engine сравнивать значения типа UNIQUEIDENTIFIER - точно не знаю. но думаю что умеет.


20. NeviD 16.12.16 15:26 Сейчас в теме
(16) Если склад с 1000 ячеек, то в первом запросе будет 1000 строк. Там просто значения ячеек склада дополняются значенями ПорядокРаспределенияС и ПорядокРаспределенияПо.
22. alexandersh 207 16.12.16 15:29 Сейчас в теме
(16) Первым запросом мы получаем 1000 строк, смотрите внимательней.. и это в худшем случае, когда надо распределить ВСЕ на ВСЕ ;-)
если будет интересно - потом напишу статью, как используя этот метод, одним запросом на лету собрать движения по партиям в базе 1С Розница > 50 Гб, где партионного учета нет как такового, а задача была сделать такой отчет, не меняя типовую конфигурацию) отчет отрабатывал секунд 10-20 за месяц (10 розничных магазинов, торговля продуктами - в общем движений много).конечно, это уже была модификация данного метода, более оптимизированная, но я бы посмотрел, как бы вы это делали через таблицы значений))
24. Fragster 928 16.12.16 15:46 Сейчас в теме
(22) да, я ошибся. первым запросом мы просто делаем итерацию из 1000000 циклов, просто делает её скуль. На выходе количество строк не меняется, да.
про количество строк - например 1000 пустых ячеек при ячеистом хранении - не редкость. У меня на практике был склад с 50000 ячейками и 15к наименований на них.

обход двух таблиц одним циклом делается достаточно просто. просто вместо "Для каждого" используется "Пока Истина" и две переменных-счетчика.
29. alexandersh 207 17.12.16 14:24 Сейчас в теме
(24) а запросом все равно будет быстрей) читайте мой предыдущий ответ Сергею )
43. HelenV 03.02.17 13:26 Сейчас в теме
17. Fragster 928 16.12.16 15:14 Сейчас в теме
А можно в один проход обойти две одинаковым образом отсортированные таблицы.
21. ЧерныйКот 16.12.16 15:29 Сейчас в теме
Мне понравилось. Автор запросами разложил поштучно ячейки и товары, а потом соединил, просто и логично.
23. ildarovich 6716 16.12.16 15:30 Сейчас в теме
Еще один пример того, что новое - это хорошо забытое старое
Вот ссылки:

http://infostart.ru/public/20221/
http://infostart.ru/public/58966/
http://infostart.ru/public/61295/
http://infostart.ru/public/62899/
http://infostart.ru/public/68225/
http://infostart.ru/public/88999/
http://infostart.ru/public/122548/

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

Теперь по сути:

В данном случае слишком упрощенно и неправильно противопоставлять запросную и внезапросную технику.
Рассуждения "сделаю запросом - так всегда будет быстрее" просто-напросто ошибочные и даже вредные.
Думаю, большой эффект в этом конкретном случае был не потому, что запросом лучше, а потому, что код ("перебор") был очень плохой.
Например, из-за того, что какие-то поля типа коэффициента единиц измерения мелкими запросами в цикле из базы дергались. Или индекса в таблице значений не было.

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

В общем, я против крайностей и "универсальных решений", за более взвешенное и обдуманное решение в каждом конкретном случае.
Krio2; apk-agroeco; 1cWin; hornet_X; hydro2588_2015; mason; Silenser; dbaser; 1cprogr_nsk; igormiro; Rego1337h; Andrsan; unichkin; PrinzOfMunchen; ra9000; sasha777666; h00k; Ali1976; sevushka; kuzyara; DrAku1a; sorb; ASysuev; PetrPan; Zabava_; varovinm; zarucheisky; MSChe; Dem1urg; bong; ABudnikov; Danil.Potapov; kiros; Chif13; nsirotkin@mail.ru; HAMMER_59; ZLENKO; soulsteps; brr; Turn123; Dach; Бывалый77; KoldunOne; Новиков; le0nid; Leoway; Sheff; hulio; Saint13; support; ILM; 1cmax; bulpi; Сурикат; genayo; starik-2005; c1nil; Alias; Armando; SunShinne; karpik666; uncle_Vasya; ardn; корум; ЧерныйКот; odin777; NeviD; +67 Ответить
28. alexandersh 207 17.12.16 14:23 Сейчас в теме
(23) Сергей, в целом позиция понятна и отчасти правильная, я даже ваш ответ выделил лучшим).
Но по поводу конкретного случая готов поспорить: во-первых в изначальном условии я четко оговорил, что у нас уже есть 2 таблицы, которые мы получаем 2-мя другими запросами. Очевидно, что эти таблицы уже содержат отфильтрованный набор данных.
Это во-первых.
Во-вторых при продумывании своих решений я руководствуюсь именно пониманием как работает движок SQL. В данном конкретном примере, когда мы будем собирать нарастающий итог даже по всей таблице с 1 млн записей, при соединении этой таблицы самой с собой будет не 1000000*1000000 строк (полный перебор SQL), а те же 1 млн строк. SQL при выполнении соединения по ключевому полю руководствуется именно этим индексом, а так как агрегатные функции (в данном случае сумма) очень качественно обрабатываются движком SQL, то учитывая индекс по которому будет организован поиск и использование реквизитов правой части соединения только для расчета агрегатной суммы - SQL умеет хранить нарастающий итог по уже обработанным записям и будет всего 1 проход по этой таблицы - это можно будет при желание увидеть в плане запроса.
Простым языком:
запрос вида
"ВЫБРАТЬ
Ячейки.Ячейка КАК Ячейка,
Ячейки.Количество,
ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + 1 КАК ПорядокРаспределенияС,
ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + Ячейки.Количество КАК ПорядокРаспределенияПо
ИЗ
Ячейки КАК Ячейки
ЛЕВОЕ СОЕДИНЕНИЕ Ячейки КАК Ячейки1
ПО Ячейки.Ячейка > Ячейки1.Ячейка

СГРУППИРОВАТЬ ПО
Ячейки.Ячейка,
Ячейки.Количество"

будет стоить не намного дороже, чем даже такой:

"ВЫБРАТЬ
Ячейки.Ячейка КАК Ячейка,
Ячейки.Количество
ИЗ
Ячейки КАК Ячейки

СГРУППИРОВАТЬ ПО
Ячейки.Ячейка,
Ячейки.Количество"

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

Далее: почему еще запрос быстрее перебора? - да потому что перебор, например, в 1с, и, хотя бы тот же перебор, в SQL - это кардинально отличающиеся по затратам процедуры. нельзя забывать, что 1с - это классический интерпретатор, даже в случае выполнения кода на стороне сервера. И как бы это банально не звучало - каждая новая строка кода - это достаточно сложная операция для сервера (опять же все познается сравнении).

ну а касательно этой задачи - я готов с кем угодно посмотрить, что распределение в запросе для БОЛЬШИХ объемов данных - всегда оптимальней делать запросом. я делаю акцент именно на больших объемах данных, когда речь идет о распределении тысяч строк НА тысячи строк. в остальных же случаях - это место навряд ли потребовало оптимизации и там бы преспокойно жил бы Цикл))

Я не агитирую переписывать все циклы на запросы - я агитирую не делать больших циклов в узких местах ;-)
Andreynikus; +1 Ответить
31. ildarovich 6716 19.12.16 14:47 Сейчас в теме
(28)(29) Вы очень глубоко заблуждаетесь!

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

При расчете нарастающего итога:

N Число строк Затрачено миллисекунд
1 1 000 302
2 2 000 998
3 3 000 2 263
4 4 000 3 840
5 5 000 5 971
6 6 000 8 443
7 7 000 12 817
8 8 000 14 846
9 9 000 18 851
10 10 000 23 346

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

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

Что прямо противоречит озвученным вами выводам.

Вот таблица:
N Метод Число строк Затрачено миллисекунд
1 Скрипт 100 8
2 Запрос 100 48
3 Скрипт 200 8
4 Запрос 200 56
5 Скрипт 1000 37
6 Запрос 1000 716
7 Скрипт 2000 75
8 Запрос 2000 2457
9 Скрипт 10000 379
10 Запрос 10000 52873
11 Скрипт 20000 774
12 Запрос 20000 227231

Посмотрите на результат при двадцати тысячах строк: 0,7 секунд для кода против 227(!!!) секунд для запроса.
Для распределения по таблицам значений использовалась взятая из "Минимализмов" (http://infostart.ru/public/306536/) функция (задача 7).

Если захотите перепроверить, вот обработка, которой я пользовался:
Прикрепленные файлы:
ДоказательстваПротивЗапроса.erf
d4rkmesa; Serj1C; sasha777666; myjob1c; varovinm; sulfur17; ZLENKO; Dach; NeviD; klinval; +10 Ответить
39. alexandersh 207 21.12.16 10:02 Сейчас в теме
(31) да, действительно, спору нет, скрипт достаточно качественный, работает быстрее, мне понравился, по поводу скорости - поиграюсь на выходных со ссылочными типами, давно уже планы запроса не смотрел, снова стало интересно
25. klinval 275 16.12.16 16:00 Сейчас в теме
Для тех, кому как и мне, чтобы понять нужно поиграться в консоле запросов:
ВЫБРАТЬ
	"A" КАК Ячейка,
	10 КАК Количество
ПОМЕСТИТЬ Ячейки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"B",
	1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"C",
	5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"D",
	8
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"x" КАК Товар,
	13 КАК Количество
ПОМЕСТИТЬ Товары

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"у",
	1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"z",
	4
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Ячейки.Ячейка КАК Ячейка,
	Ячейки.Количество КАК Количество,
	ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + 1 КАК ПорядокРаспределенияС,
	ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + Ячейки.Количество КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ЯчейкиПоПорядку
ИЗ
	Ячейки КАК Ячейки
		ЛЕВОЕ СОЕДИНЕНИЕ Ячейки КАК Ячейки1
		ПО Ячейки.Ячейка > Ячейки1.Ячейка

СГРУППИРОВАТЬ ПО
	Ячейки.Ячейка,
	Ячейки.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Товары.Товар КАК Товар,
	Товары.Количество,
	ЕСТЬNULL(СУММА(Товары1.Количество), 0) + 1 КАК ПорядокРаспределенияС,
	ЕСТЬNULL(СУММА(Товары1.Количество), 0) + Товары.Количество КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ТоварыПоПорядку
ИЗ
	Товары КАК Товары
		ЛЕВОЕ СОЕДИНЕНИЕ Товары КАК Товары1
		ПО Товары.Товар > Товары1.Товар

СГРУППИРОВАТЬ ПО
	Товары.Товар,
	Товары.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЯчейкиПоПорядку.Ячейка КАК Ячейка,
	ТоварыПоПорядку.Товар КАК Товар,
	ВЫБОР
		КОГДА ТоварыПоПорядку.ПорядокРаспределенияПо < ЯчейкиПоПорядку.ПорядокРаспределенияПо
			ТОГДА ТоварыПоПорядку.ПорядокРаспределенияПо
		ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияПо
	КОНЕЦ - ВЫБОР
		КОГДА ТоварыПоПорядку.ПорядокРаспределенияС > ЯчейкиПоПорядку.ПорядокРаспределенияС
			ТОГДА ТоварыПоПорядку.ПорядокРаспределенияС
		ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияС
	КОНЕЦ + 1 КАК Количество,
	ТоварыПоПорядку.ПорядокРаспределенияПо,
	ЯчейкиПоПорядку.ПорядокРаспределенияПо КАК ПорядокРаспределенияПо1,
	ТоварыПоПорядку.ПорядокРаспределенияС,
	ЯчейкиПоПорядку.ПорядокРаспределенияС КАК ПорядокРаспределенияС1
ИЗ
	ЯчейкиПоПорядку КАК ЯчейкиПоПорядку
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТоварыПоПорядку КАК ТоварыПоПорядку
		ПО ЯчейкиПоПорядку.ПорядокРаспределенияС <= ТоварыПоПорядку.ПорядокРаспределенияПо
			И ЯчейкиПоПорядку.ПорядокРаспределенияПо >= ТоварыПоПорядку.ПорядокРаспределенияС
Показать

Автору плюс!
alex-pro; sulfur17; +2 Ответить
38. sulfur17 21.12.16 09:17 Сейчас в теме
(25)
ВЫБРАТЬ
"у",
1

Большое спасибо за запрос, очень помогли разобраться. Только у вас вот тут буква "у" русская, поэтому результат не совпадает с результатом топикстартера.
26. MarryJane 23 16.12.16 19:22 Сейчас в теме
О, нужно будет попробовать распределить сумму долга по документам. Отличая идея. если просто : Берем сумму долга на начало. Берем документы реализации и распределяем с конца на эту сумму долга, и получаем последние неоплаченные документы, и не требуется вести оплаты по документам.
27. genayo 17.12.16 07:53 Сейчас в теме
(26) По одному контрагенту это будет приемлемо. А вот по 1000 уже печально...
30. ture 557 19.12.16 14:16 Сейчас в теме
(00) порадовал заголовое и количество звёзд. Стало приятно на душе - "побольше" бы таких специалистов! Но скоро расстроился, т.к.давно влился в ряды таких специалистов.
Вы ведь знаете, как на самом деле перераспеделяется нагрузка между сервером 1С и сервером SQL(если не файловая)? Я обеими руками поддерживаю Вашу идею, если быть до конца правдивым.
32. I_G_O_R 57 19.12.16 21:23 Сейчас в теме
Попробовал использовать дробные числа, запрос работает неправильно...
ВЫБРАТЬ
	"A" КАК Ячейка,
	3.8 КАК Количество
ПОМЕСТИТЬ Ячейки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"B",
	1.2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"C",
	5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"D",
	8
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"x" КАК Товар,
	4.5 КАК Количество
ПОМЕСТИТЬ Товары

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"у",
	1.5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"z",
	4
;

Показать
33. klinval 275 20.12.16 09:12 Сейчас в теме
(32) да всё вроде логично - запрос расчитан на целые числа! Хотите не целые, вот вам:
ВЫБРАТЬ
	"A" КАК Ячейка,
	3.8 КАК Количество
ПОМЕСТИТЬ Ячейки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"B",
	1.2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"C",
	5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"D",
	8
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"x" КАК Товар,
	4.5 КАК Количество
ПОМЕСТИТЬ Товары

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"у",
	1.5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	"z",
	4
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Ячейки.Ячейка КАК Ячейка,
	Ячейки.Количество КАК Количество,
	ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + 0.01 КАК ПорядокРаспределенияС,
	ЕСТЬNULL(СУММА(Ячейки1.Количество), 0) + Ячейки.Количество КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ЯчейкиПоПорядку
ИЗ
	Ячейки КАК Ячейки
		ЛЕВОЕ СОЕДИНЕНИЕ Ячейки КАК Ячейки1
		ПО Ячейки.Ячейка > Ячейки1.Ячейка

СГРУППИРОВАТЬ ПО
	Ячейки.Ячейка,
	Ячейки.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Товары.Товар КАК Товар,
	Товары.Количество,
	ЕСТЬNULL(СУММА(Товары1.Количество), 0) + 0.01 КАК ПорядокРаспределенияС,
	ЕСТЬNULL(СУММА(Товары1.Количество), 0) + Товары.Количество КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ТоварыПоПорядку
ИЗ
	Товары КАК Товары
		ЛЕВОЕ СОЕДИНЕНИЕ Товары КАК Товары1
		ПО Товары.Товар > Товары1.Товар

СГРУППИРОВАТЬ ПО
	Товары.Товар,
	Товары.Количество
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЯчейкиПоПорядку.Ячейка КАК Ячейка,
	ТоварыПоПорядку.Товар КАК Товар,
	ВЫБОР
		КОГДА ТоварыПоПорядку.ПорядокРаспределенияПо < ЯчейкиПоПорядку.ПорядокРаспределенияПо
			ТОГДА ТоварыПоПорядку.ПорядокРаспределенияПо
		ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияПо
	КОНЕЦ - ВЫБОР
		КОГДА ТоварыПоПорядку.ПорядокРаспределенияС > ЯчейкиПоПорядку.ПорядокРаспределенияС
			ТОГДА ТоварыПоПорядку.ПорядокРаспределенияС
		ИНАЧЕ ЯчейкиПоПорядку.ПорядокРаспределенияС
	КОНЕЦ + 0.01 КАК Количество,
	ТоварыПоПорядку.ПорядокРаспределенияПо КАК ПорядокРаспределенияПо,
	ЯчейкиПоПорядку.ПорядокРаспределенияПо КАК ПорядокРаспределенияПо1,
	ТоварыПоПорядку.ПорядокРаспределенияС КАК ПорядокРаспределенияС,
	ЯчейкиПоПорядку.ПорядокРаспределенияС КАК ПорядокРаспределенияС1
ИЗ
	ЯчейкиПоПорядку КАК ЯчейкиПоПорядку
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТоварыПоПорядку КАК ТоварыПоПорядку
		ПО (ЯчейкиПоПорядку.ПорядокРаспределенияС <= ТоварыПоПорядку.ПорядокРаспределенияПо)
			И (ЯчейкиПоПорядку.ПорядокРаспределенияПо >= ТоварыПоПорядку.ПорядокРаспределенияС)

УПОРЯДОЧИТЬ ПО
	Ячейка,
	Товар
Показать

Сотых для большинства случаев должно хватить. В 1С обычно всё до сотых округляется (кроме курса валюты).

Дано:
Ячейка Количество
A 3,8
B 1,2
C 5
D 8

Товар Количество
x 4,5
у 1,5
z 4

Результат:
A x 3,8
B x 0,7
B z 0,5
C z 3,5
C у 1,5
36. I_G_O_R 57 20.12.16 10:19 Сейчас в теме
(33) (34) да я пробовал вместо 1 использовать 0.001, просто я заменил только в 2-местах вместо 3-х((

Я проверил обработку из (31), разница к сожалению большая и она не в пользу запроса. Я по ЗУПу еще помню, этот нарастающий итог не такой уж хороший, под конец года НДФЛ считался дольше чем в начале года (правда как ща не знаю).

Я собственно за то, что СУБД нам отдает данные, а логика выполняется на сервере приложений. Когда логика выполняется на СУБД, этот код со временем превращается в неподдерживаемый хаос.
37. ildarovich 6716 20.12.16 12:55 Сейчас в теме
(32 (33) (34) Не знаю, зачем там что-то прибавлять-вычитать, работает вообще без этого. Вот в этом, чуть более коротком варианте запрос работает для чисел вообще какой угодно разрядности:
ВЫБРАТЬ
	Ячейки.Ячейка,
	СУММА(Слева.Количество) - МИНИМУМ(Ячейки.Количество) КАК КоличествоОт,
	СУММА(Слева.Количество) КАК КоличествоДо
ПОМЕСТИТЬ ЛинейкаЯчеек
ИЗ
	Ячейки КАК Ячейки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Ячейки КАК Слева
		ПО (Слева.Ячейка <= Ячейки.Ячейка)

СГРУППИРОВАТЬ ПО
	Ячейки.Ячейка
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Товары.Товар,
	СУММА(Слева.Количество) - МИНИМУМ(Товары.Количество) КАК КоличествоОт,
	СУММА(Слева.Количество) КАК КоличествоДо
ПОМЕСТИТЬ ЛинейкаТоваров
ИЗ
	Товары КАК Товары
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Товары КАК Слева
		ПО (Слева.Товар <= Товары.Товар)

СГРУППИРОВАТЬ ПО
	Товары.Товар
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Ячейки.Ячейка КАК Ячейка,
	Товары.Товар КАК Товар,
	ВЫБОР
		КОГДА Товары.КоличествоДо < Ячейки.КоличествоДо
			ТОГДА Товары.КоличествоДо
		ИНАЧЕ Ячейки.КоличествоДо
	КОНЕЦ - ВЫБОР
		КОГДА Товары.КоличествоОт > Ячейки.КоличествоОт
			ТОГДА Товары.КоличествоОт
		ИНАЧЕ Ячейки.КоличествоОт
	КОНЕЦ КАК Количество
ИЗ
	ЛинейкаЯчеек КАК Ячейки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЛинейкаТоваров КАК Товары
		ПО Ячейки.КоличествоОт < Товары.КоличествоДо
			И Ячейки.КоличествоДо > Товары.КоличествоОт
Показать

Идея запроса вовсе не в целых числах, а в том, чтобы построить друг против друга линейку товаров и ячеек и найти пересечение отрезков на этих линейках.
Вот в этом обсуждении есть картинка: http://forum.infostart.ru/forum9/topic32459/message361861/#message361861 .
KazanKokos; sulfur17; NeviD; klinval; +4 Ответить
34. ture 557 20.12.16 09:13 Сейчас в теме
(32) нечего пенять на запрос. Его идея в целых числах, значит Вам нужно множить все на 1000
35. Dach 279 20.12.16 09:30 Сейчас в теме
Статья хорошая, хотя техника распределения нарастающего итога конечно не нова.

Как я был расстроен и опечален, когда немного более подробно изучил T-SQL... Мы здесь с вами изворачиваемся, чтобы посчитать нарастающий итог, таблицы сами с собой соединяем и т.д. А у sql-щиков есть уже "по умолчанию" ранжирование в запросах, расчет нарастающего итога и прочие плюшки - все буквально одной-двумя строками кода... Мечтательно представил, как бы парочку своих мегазапросов переписал на куда как более компактно.... Эх ))))
40. Infector 142 27.01.17 09:13 Сейчас в теме
В целом неплохо. Однако же как обстоит дело с ошибками округлений? На практике чаще приходится сталкиваться с подобными задачами немного видоизмененного рода, например с примесью механизмов FIFO/LIFO. Одна таблица содержит строки, которые можно разделить на группы по ряду признаков. (Например перечень номенклатуры с количествами, но еще неизвестной стоимостью). Вторая таблица содержит значения, которые нужно распределить и при этом не прихватить лишнего (Например остатки номенклатуры по количеству и сумме из внешнего источника), При этом нужно избегать ситуации, когда остаются копейки без количества (т.е. ошибки из-за округлений). С перебором подобные задачи на ура решаюся с помощью методов НайтиСтроки (Для таблицы значений) и НайтиСледующий(Для Выборки). Запросом к сожалению решить не удавалось. Сейчас пришел к тому, что многоие задачи распределения подлежат унификации.
41. Ish_2 1038 31.01.17 13:44 Сейчас в теме
(40)
Запросом к сожалению решить не удавалось.

"Фифо для любопытных"
http://infostart.ru/public/68225/
42. OPM 104 01.02.17 18:53 Сейчас в теме
(40) Посмотри в 1С:Бухгалтерии распределение 25 счета по 20 в регламентной операции, делается только запросами, и погрешностей округления нет.
44. Гость 19.03.17 14:25
Есть задача из универа:
Есть фура объемом 50 000т. Ее нужно загрузить так , чтобы Суммарная стоимость товара, перевозимого фурой, должна быть максимальной.

Результат должен быть такой:
код партии вес Стоимость
101 10 000 700 000
302 4 000 240 000
601 24 000 2 160 000
602 11 000 990 000

Пробую методом из статьи:


ВЫБРАТЬ
    "A" КАК Фура,
    50000 КАК Объем
ПОМЕСТИТЬ Фуры
;

////////////////////////////////////////////////////////////­////////////////////

ВЫБРАТЬ
    "101" КАК Партия,
    10000 КАК Вес,
    700000 КАК Стоимость
ПОМЕСТИТЬ Партии

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "201",
    12000,
    540000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "301",
    14000,
    840000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "302",
    4000,
    240000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "401",
    8000,
    640000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "501",
    16000,
    880000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "601",
    24000,
    2160000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "602",
    11000,
    990000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "701",
    10000,
    400000

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "801",
    18000,
    630000
;

////////////////////////////////////////////////////////////­////////////////////

ВЫБРАТЬ
    Фуры.Фура КАК Фура,
    Фуры.Объем КАК Объем,
    ЕСТЬNULL(СУММА(Фуры1.Объем), 0) + 1 КАК ПорядокРаспределенияС,
    ЕСТЬNULL(СУММА(Фуры1.Объем), 0) + Фуры.Объем КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ФурыПоПорядку
ИЗ
    Фуры КАК Фуры
        ЛЕВОЕ СОЕДИНЕНИЕ Фуры КАК Фуры1
        ПО Фуры.Фура > Фуры1.Фура

СГРУППИРОВАТЬ ПО
    Фуры.Фура,
    Фуры.Объем
;

////////////////////////////////////////////////////////////­////////////////////

ВЫБРАТЬ
    Партии.Партия КАК Партия,
    Партии.Вес КАК Вес,
    Партии.Стоимость КАК Стоимость,
    ЕСТЬNULL(СУММА(Партии1.Вес), 0) + 1 КАК ПорядокРаспределенияС,
    ЕСТЬNULL(СУММА(Партии1.Вес), 0) + Партии.Вес КАК ПорядокРаспределенияПо
ПОМЕСТИТЬ ПартииПоПорядку
ИЗ
    Партии КАК Партии
        ЛЕВОЕ СОЕДИНЕНИЕ Партии КАК Партии1
        ПО Партии.Стоимость < Партии1.Стоимость

СГРУППИРОВАТЬ ПО
    Партии.Партия,
    Партии.Вес,
    Партии.Стоимость
;

////////////////////////////////////////////////////////////­////////////////////

ВЫБРАТЬ
    ФурыПоПорядку.Фура КАК Фура,
    ПартииПоПорядку.Партия КАК Партия,
    ВЫБОР
        КОГДА ПартииПоПорядку.ПорядокРаспределенияПо < ФурыПоПорядку.ПорядокРаспределенияПо
            ТОГДА ПартииПоПорядку.ПорядокРаспределенияПо
        ИНАЧЕ ФурыПоПорядку.ПорядокРаспределенияПо
    КОНЕЦ - ВЫБОР
        КОГДА ПартииПоПорядку.ПорядокРаспределенияС > ФурыПоПорядку.ПорядокРаспределенияС
            ТОГДА ПартииПоПорядку.ПорядокРаспределенияС
        ИНАЧЕ ФурыПоПорядку.ПорядокРаспределенияС
    КОНЕЦ + 1 КАК Вес,
    ПартииПоПорядку.Стоимость КАК Стоимость,
    ПартииПоПорядку.ПорядокРаспределенияПо,
    ФурыПоПорядку.ПорядокРаспределенияПо КАК ПорядокРаспределенияПо1,
    ПартииПоПорядку.ПорядокРаспределенияС,
    ФурыПоПорядку.ПорядокРаспределенияС КАК ПорядокРаспределенияС1
ИЗ
    ФурыПоПорядку КАК ФурыПоПорядку
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПартииПоПорядку КАК ПартииПоПорядку
    ПО ФурыПоПорядку.ПорядокРаспределенияС <= ПартииПоПорядку.ПорядокРаспределенияПо
            И ФурыПоПорядку.ПорядокРаспределенияПо >= ПартииПоПорядку.ПорядокРаспределенияС
Показать


Результат получается такой:
Партия Вес Стоимость
601 24 000 2 160 000
602 11 000 990 000
501 15 000 880 000

Подскажите, как изменить условия, чтобы получалась максимальная загрузка по стоимости.
45. vpkon 14.06.17 12:47 Сейчас в теме
Спасибо, Александр!
Ваш код не очевиден. И тем ценен. Можно сказать, что вначале своей статьи вы описали инсайт (То есть, как на самом деле люди делают открытия - получают новое знание).
А спасибо, потому что Вы решили просто сложную задачу и поделились с нами.
46. Tracerdim 5 07.11.17 18:01 Сейчас в теме
Большое спасибо за статью. Раньше я, как раз, распределял одну таблицу на другую через нарастающий итог и всякие условия.
После наглядного представления с порядком распределения теперь проще распределять таблицы.
Оставьте свое сообщение

См. также

Полезняшки по СКД и построителям. Просто код 35

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования Универсальные функции

Полезные процедуры и функции для работы с построителями и СКД. Просто исходник.

10.10.2019    1783    Yashazz    31       

"Хочу универсально!" [Часть 1] 65

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Математика и алгоритмы Практика программирования Разработка

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

02.09.2019    3811    SeiOkami    35       

Иерархия без "В ИЕРАРХИИ" 113

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

Говорится о том, как эффективно представлять иерархию в СУБД, как получать и использовать эти представления при решении задач в запросной технике. Уточняются и дополняются запросы из статьи "Уровни, глубина, прародители, циклы и аналоги запросом" [https://infostart.ru/public/160707/].

22.08.2019    4237    ildarovich    16       

EnterpriseData – часть 3. Загрузка данных, идентификация объектов 61

Статья Программист Нет файла v8 v8::УФ 1cv8.cf ОС Бесплатно (free) Практика программирования Математика и алгоритмы Перенос данных из 1C8 в 1C8 Разработка

Основные этапы загрузки данных через EnterpriseData. Идентификация объектов загружаемых полностью и по ссылке. Приведены схемы процессов загрузки данных. Описание основных операций и обработчиков. Перечень процедур БСП, используемых при загрузке данных, структура «КомпонентыОбмена».

22.08.2019    3236    ids79    7       

Отслеживание выполнения фонового задания 133

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции Разработка

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    7901    ids79    14       

Обработчики событий при записи объектов. Зачем и что за чем? 188

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

Программисту, имеющему немного опыта на платформе 1С 8.3, бывает сложно разобраться: ПередЗаписью, ПриЗаписи, ПослеЗаписи, на сервере, на клиенте, в модуле формы, в модуле объекта.... Эта шпаргалка была создана в процессе обучения и реального опыта с целью разложить всё по полочкам, чтобы было четкое понимание в каком случае какой обработчик нужно использовать и в какой последовательности они запускаются при записи и проведении документов. Данная статья будет полезна в большей степени начинающим разработчикам. Но и опытным позволит освежить информацию, упорядочить её.

25.07.2019    10086    4    AlbinaAAA    22       

Управление качеством кода 123

Статья Программист Руководитель проекта Нет файла v8 Бесплатно (free) Математика и алгоритмы Рефакторинг и качество кода

О SonarQube, АПК, EDT. Какие преимущества дает их использование. Для каких команд подходит.

22.07.2019    6810    Stepa86    23       

Что делает "В ИЕРАРХИИ" в запросе? 85

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

Описание действий платформы 1С при использовании конструкции "В ИЕРАРХИИ" в запросах.

16.07.2019    6507    YPermitin    29       

Создание отчетов с помощью СКД - основные понятия и элементы 189

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования Математика и алгоритмы

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    16988    ids79    16       

Реализуем Стек, Очередь и Приоритетную очередь в 1С 50

Статья Программист Нет файла v8 1cv8.cf Россия Бесплатно (free) Практика программирования Математика и алгоритмы Разработка

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

24.06.2019    7038    RonX01    63       

Вычисление 200 тысяч знаков числа pi 73

Статья Программист Нет файла v8 Россия Бесплатно (free) Математика и алгоритмы

В статье рассматриваются возможности платформы выполнять сверхточные вычисления без использования сложных алгоритмов и внешних компонент на примере вычисления числа pi.

28.05.2019    3561    Oleg_nsk    93       

Регистры накопления. Виртуальные таблицы. Часть №1: Обороты 82

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Математика и алгоритмы Разработка

Описание работы платформы 1С:Предприятие 8.2 с виртуальной таблицей "Обороты" регистров накопления.

20.05.2019    9662    YPermitin    4       

Сохранение запроса со всеми параметрами и временными таблицами 20

Статья Программист Нет файла v8 v8::УФ Россия Бесплатно (free) Универсальные функции

Функция сохранения запроса со всеми параметрами и временными таблицами в формате *.q1c для открытия в консоли запросов с диска ИТС.

13.05.2019    2361    Serge R    5       

Даем названия переменным: как префиксы экономят наше время 10

Статья Программист Стажер Внешняя обработка (ert,epf) v8 Бесплатно (free) Практика программирования Математика и алгоритмы Разработка

Понятные названия переменных экономят время и силы разработчика : в начале, когда мы даём названия переменным, в процессе развития разработки, когда мы "на лету" понимаем назначение той или иной переменной, в конце, когда мы передаём разработку на поддержку других программистов, сами переходя к новым разработкам

06.05.2019    2880    Designer1C    69       

Доработка проведения типовых документов в УТ 11.4, КА 2.4, ЕРП 2.4 100

Статья Программист Нет файла v8 v8::УФ ERP2 УТ11 КА2 Россия УУ Бесплатно (free) Практика программирования Универсальные функции Разработка

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

22.03.2019    8625    ids79    14       

Заметки по SQL: Срез последних - аналог запроса 15

Статья Программист Нет файла v8 1cv8.cf Россия Бесплатно (free) Практика программирования Математика и алгоритмы

В статье описывается создание среза последних данных средствами классического языка запросов. Причем метод построения запроса был разработан еще во времена, когда автор работал с СУБД Oracle 9i и программировал на PL SQL. Основная идея заключается преобразовании запроса с подзапросом, в запрос без подзапроса (в примерах описывается преобразование до двух вложенных подзапросов). Запросы тестировались на реальных базах данных. Платформа - 1С:Предприятие 8.3 (8.3.10.2561).

15.01.2019    5789    IVC_goal    5       

Работа со строками: от простого к сложному 25

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Простые примеры работы со строками, в конце более читаемый разбор сложных текстов.

14.01.2019    7327    Evg-Lylyk    17       

Универсальные функции ЗУП 3.1 / ЗКГУ 3.1, которые помогут в разработке 458

Статья Программист Нет файла v8 v8::СПР ЗКГУ3.0 ЗУП3.x БУ Зарплата Управление персоналом (HRM) Бесплатно (free) Универсальные функции

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

14.11.2018    31167    GeterX    93       

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С 125

Статья Программист Нет файла v8 v8::blocking 1cv8.cf Бесплатно (free) Математика и алгоритмы Практика программирования

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    20615    ids79    40       

Кадровые данные сотрудников в ЗУП 3.1 в отчетах 38

Статья Программист Нет файла v8 v8::СПР ЗУП3.x Россия Управление персоналом (HRM) Бесплатно (free) Универсальные функции

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

07.11.2018    12717    fromlion    12       

Основные понятия и механизмы оптимизации клиент-серверного взаимодействия в 1C 144

Статья Программист Нет файла v8 Россия Бесплатно (free) Математика и алгоритмы Практика программирования

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

23.08.2018    20947    Rain88    42       

Простой способ программно открыть заполненную форму нового (незаписанного) документа в тонком клиенте 15

Статья Программист Нет файла v8 Бесплатно (free) Универсальные функции

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

09.06.2018    7329    Serge R    12       

Теорема номер тринадцать 15

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

Использование математических методов для языка запросов.

15.03.2018    8940    vasilev2015    24       

Минимализмы 3 350

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    35315    ildarovich    44       

Таблица значений в Таблицу HTML - функция с возможностью настройки цвета шапки, заголовков, выравнивания и размера колонок 83

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции

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

22.12.2017    18764    rpgshnik    21       

Пример преобразования двоичных данных в строку 26

Статья Программист Нет файла v8 Бесплатно (free) Универсальные функции

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

08.12.2017    12311    frkbvfnjh    19       

Введение в CI для 1С 87

Статья Программист Нет файла v8 Россия Бесплатно (free) Математика и алгоритмы

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

21.11.2017    18757    real_MaxA    22       

Определяем контекст сеанса 1С программно (Тонкий/Толстый клиенты/HTTP-Сервис/Фоновое задание и т.д.) 31

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции

Иногда возникает необходимость программно определить контекст сеанса в 1С. Скажем вам надо понять что этот сеанс запущен и используется HTTP-Сервисом и не регламентным заданием или толстым клиентом. Порывшись в интернете я нашел только два способа которые не позволяли отличить регламентное задание от HTTP-Сервиса, стандартная функция ТекущийРежимЗапуска() тоже не позволяет определить запуск HTTP-Сервиса. Но в 1С есть стандартные средства которые позволяют решить эту задачу.

08.11.2017    15273    azubar    9       

#Область ВНЕШНИЕ_ВЫЗОВЫ или MVC в 1С, библиотечность и упрощение интеграции кода 43

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Математика и алгоритмы Универсальные функции

Зачастую почти любой модуль в 1С содержит от одного до несметного множества вызовов других модулей. Как с этим бороться, чтобы было проще куда-то что-то переносить - в этом посте.

12.10.2017    14423    for_sale    58       

Получение даты, зная день недели и его порядок в месяце 10

Статья Программист Нет файла v8 Бесплатно (free) Универсальные функции

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

12.09.2017    8063    987ww765    10       

Групповая разработка конфигураций в крупном холдинге 68

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

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

15.08.2017    17000    stas_ganiev    15       

Разность дат 21

Статья Программист Нет файла v8 Бесплатно (free) Универсальные функции

Иногда требуется получить разность дат в виде типа: 5 дней 6 месяцев 4 года. Это можно сделать с помощью запроса, получив на выходе сразу 3 нужных числа, без последующих вычислений.

11.08.2017    9691    jun-ko    24       

Простой способ преобразовать UNICODE в строку или в структуру 23

Статья Программист Нет файла v8 Россия Windows Бесплатно (free) Практика программирования Универсальные функции

Первая функция получает Строку, которая содержит строчки вида «Ключ=Значение». Вторая функция получает Структуру.

07.07.2017    7127    dimasts    5       

Автоматизация процесса 1С-разработки 91

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

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

07.06.2017    22498    ekaruk    9       

Пишем игру Минер. Обработка событий ActiveX в 1С 29

Статья Программист Нет файла v8 Россия Windows Бесплатно (free) Практика программирования Математика и алгоритмы

Пример демонстрирует обработку событий генерируемых компонентой ActiveX в 1С.

29.05.2017    12380    user621724_Dimav1979    11       

Как я доступ на kb.1c.ru получал 90

Статья Программист Нет файла v8 Россия Бесплатно (free) Решение задач на 1С:Специалист Математика и алгоритмы

kb.1c - база знаний по технологическим вопросам крупных внедрений и не только. В этой базе знаний собираются методики и решения технологических проблем эксплуатации 1с, check-list'ы и инструкции по настройке ПО на серверах. Какие-то из размещенных статей дублируются на ИТС. Когда я искал пути получения доступа к нему я столкнулся с проблемой: мало кто доподлинно знает как получить доступ к нему, не работая у франчайзи 1с. Я опишу путь, который прошёл я, как физическое лицо.

01.05.2017    21997    ikekoval    33       

Заметки про запросы. Коллекция 136

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

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

26.12.2016    22630    vasilev2015    63       

Планы обмена. Квитировать или гарантировать? 24

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Математика и алгоритмы

Планы обмена предлагают использовать две стратегии удаления обработанных изменений: квитирование и гарантированная доставка сообщений. Как сделать правильный выбор?

12.12.2016    14155    zhichkin    9       

Некоторые принципы оптимизации запросов 1С (+SQL) 115

Статья Программист Нет файла v8 Бесплатно (free) Математика и алгоритмы

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

17.11.2016    8587    ture    40       

Пример работы с шаблоном Word через ole (клиент - сервер, тонкий клиент) - установка значений и заполнение таблицы 17

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

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

09.11.2016    9971    gortrex    8       

Использование git для доработки типовых конфигураций 1С 229

Статья Программист Нет файла v8 Беларусь Украина Россия Бесплатно (free) Математика и алгоритмы

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

11.10.2016    185777    pumbaE    31       

Оптимизация запросов 1С:Предприятие – от теории к практике 114

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Математика и алгоритмы

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

07.10.2016    30958    bpc222    20       

Парсер JSON (Штатные средства 1С 8.3.6) 59

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Хочу поделиться функцией чтения json, реализованной с помощью штатных средств платформы.

29.09.2016    46164    dour-dead    21       

Программное создание графических схем (v.2): API для ГрафическойСхемы 73

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Работа с интерфейсом Универсальные функции

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

27.09.2016    16835    serg_infostart    15       

Используем механизмы обмена данными БСП для произвольного обмена 147

Статья Программист Нет файла v8 Бесплатно (free) Универсальные функции Внешние источники данных БСП (Библиотека стандартных подсистем)

Механизм БСП заточен на обмен XML по правилам обмена. Чтобы использовать его для любого другого обмена, коих в мире немало, требуются доработки. В статье описан вариант, как из положения выйти.

23.08.2016    27588    Патриот    22