ФИФО для любопытных

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

Программирование - Практика программирования

87
Как одним запросом получить все движения расходных документов за период ?
В статье приводится альтернативный алгоритм списания по методу ФИФО .

Зачем это нужно ?

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


Постановка задачи .

Рассмотрим постановку задачи списания  по методу ФИФО в рамках простейшей конфигурации, содержащей справочник Номенклатура, документы РасходнаяНакладная и ПриходнаяНакладная, а также регистр накопления Партии. Период проведения расходных документов определен как [ДатаНачала,ДатаКонца].Получены две временные таблицы Приход и Расход (описание алгоритма будет сопровождаться демонстрационным примером).
Приход

Номенклатура

Партия МоментВремени Период Количество Сумма
Товар № 1 ПрихНакл №1            ..... 26.02.2010           100  1000
Товар № 1 ПрихНакл №2            ..... 01.03.2010           120

 1200

Таблица Приход может быть получена как объединение двух таблиц :таблица остатков партий на ДатаНачала и таблица движений документов ПриходнаяНакладная, полученная за период [ДатаНачала,ДатаКонца].

Расход

Номенклатура

Регистратор МоментВремени Период Количество Сумма
Товар № 1 РасхНакл №1            ..... 11.03.2010           80  800
Товар № 1 РасхНакл №2            ..... 14.03.2010

          40

 400

Товар № 1 РасхНакл №3            ..... 26.03.2010          100

 1000


Таблица Расход может быть получена при обращении к таблице Документы.РасходнаяНакладная за период  [ДатаНачала,ДатаКонца].

Требуется получить таблицу движений по регистру партий :

Номенклатура

Партия Период  Регистратор Количество Сумма


Алгоритм решения.

Рассмотрим упрощенный алгоритм получения движений регистра только по количеству. В демонстрационной конфигурации СписаниеПоМетодуФИФО.dt приведено более полное и подробное решение.

Этап I. 
Получим таблицы НарРасход и НарПриход , содержащие нарастающие итоги для каждой строки в колонках КоличествоДо и КоличествоПосле.

НарПриход

Номенклатура

Партия ... Период КоличествоДо КоличествоПосле
Товар № 1 ПрихНакл №1   26.02.2010           0       100 
Товар № 1 ПрихНакл №2   01.03.2010           100

      220

НарРасход

Номенклатура

Регистратор ... Период КоличествоДо КоличествоПосле
Товар № 1 РасхНакл №1   11.03.2010           0       80
Товар № 1 РасхНакл №2   14.03.2010

          80

     120

Товар № 1 РасхНакл №3   26.03.2010          120

     220

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

ВЫБРАТЬ

  
     Расход.Период,
    
Расход.МоментВремени,
     
Расход.Регистратор,
    
Расход.Номенклатура,
    
Расход.Количество,
    
Расход.Сумма,
    
СУММА(Расход1.Количество) - Расход.Количество КАК КоличествоДо,
    
СУММА(Расход1.Количество) КАК КоличествоПосле
ПОМЕСТИТЬ НарРасход
ИЗ  Расход КАК Расход
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Расход КАК Расход1
     ПО Расход.Номенклатура = Расход1.Номенклатура
     И Расход.МоментВремени >= Расход1.МоментВремени
СГРУППИРОВАТЬ ПО
    
Расход.Период,
    
Расход.МоментВремени,
    
Расход.Регистратор,
    
Расход.Номенклатура,
    
Расход.Количество,
    
Расход.Сумма

 

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

ВЫБРАТЬ
   
НарРасход.Период,
   
НарРасход.Регистратор,
   
НарПриход.Партия,
   
НарРасход.Номенклатура,
   
// Следующее поле "Количество" можно определить как
    // Мин(НарПриход.КоличествоПосле, НарРасход.КоличествоПосле)
    // - Макс(НарПриход.КоличествоДо, НарРасход.КоличествоДо)
   
ВЫБОР
     КОГДА
НарПриход.КоличествоПосле < НарРасход.КоличествоПосле
     ТОГДА НарПриход.КоличествоПосле
     ИНАЧЕ НарРасход.КоличествоПосле
     КОНЕЦ - ВЫБОР
            КОГДА
НарПриход.КоличествоДо > НарРасход.КоличествоДо
            ТОГДА НарПриход.КоличествоДо
            ИНАЧЕ НарРасход.КоличествоДо
     КОНЕЦ КАК Количество
ИЗ
  
НарРасход КАК НарРасход
   Внутреннее СОЕДИНЕНИЕ НарПриход КАК НарПриход
   ПО НарРасход.Номенклатура = НарПриход.Номенклатура
   И НарРасход.КоличествоПосле > НарПриход.КоличествоДо
   И НарРасход.КоличествоДо < НарПриход.КоличествоПосле
   И НарРасход.МоментВремени > НарПриход.МоментВремени


Таблица Движений
 

Номенклатура

Регистратор Партия Период Количество Сумма
Товар № 1 РасхНакл №1  ПрихНакл №1 11.03.2010           80  -нет
Товар № 1 РасхНакл №2  ПрихНакл №1 14.03.2010

          20

 -нет

Товар № 1 РасхНакл №2  ПрихНакл №2 14.03.2010           20

 -нет

Товар № 1 РасхНакл №3  ПрихНакл №2 26.03.2010          100  -нет

Этап III .

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

Замечания.

 

Приведенный в Этапе I запрос нагляден , но чрезвычайно затратен .В практических разработках при вычислении нарастающих итогов возможно применение подхода , описанного в статье "Подведем Итоги.Нарастающие"   //infos.capitally.ru/public/61295/. Применение же подхода Шепота - невозможно , потому что он ничего на эти темы не писал.

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

В тексте темы использована разукрашка Aleks-is http://www.infostart.ru/public/19856/

 

 

87

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

Наименование Файл Версия Размер
СписаниеПоМетодуФИФО.dt
.dt 35,91Kb
05.08.10
663
.dt 35,91Kb 663 Скачать бесплатно

См. также

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

Комментарии
Избранное Подписка Сортировка: Древо
1. Ish_2 1031 02.04.10 09:49 Сейчас в теме
Глюки и ошибки сайта при создании и редактировании новой публикации
вызывают грусть. И печальные обобщения.
2. Арчибальд 2709 02.04.10 09:53 Сейчас в теме
(1) Поставил плюс за внятность изложения. И чуть было не снял за мизантропию :D
3. Ish_2 1031 02.04.10 09:59 Сейчас в теме
Не снимай ! Я тебя еще повеселю .
Захотелось "внятно" ответить на тягучие разговоры о " жизни без последовательностей " и "отказе от партионного учета".
4. Шёпот теней 1741 02.04.10 10:33 Сейчас в теме
(3) ... хм ... прекрасно всем известно ... сделать можно всё ... как впрочем и оправдать ...

...

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

...

... вот ...
5. Арчибальд 2709 02.04.10 10:58 Сейчас в теме
(3) А кто это отказывался от партионного учета? Мы его заклеймим!
А жизнь без последовательностей радостна и безоблачна, и никакого отношения к партионному учету не имеет.
Партионный учет - объективная потребность (а значит, реальность).
Последовательность - химера, рожденная в воспаленных мозгах разработчиков. Последовательности ирреальны, ибо не встречаются в жизни.
К сожалению, в отличие от других нервно-паралитических болезней, эта (использование последовательностей) оказалась заразной. А поскольку из всех лекарств в арсенале восьмерки остались одни запросы...
6. Ish_2 1031 02.04.10 16:45 Сейчас в теме
(5) Арчибальд , ты , конечно, кавалер авторитетный и всё такое...

Но :
"Потребность = реальность",
"последовательность = химера"

- э..э .. перехвалили тебя .

В "восьмерке" не остались , а добавились запросы как признание столбовой дороги развития СУБД . Представленный алгоритм как раз и говорит :
авторитетному мужчине пора завязывать с 77.
7. anig99 2684 02.04.10 17:55 Сейчас в теме
поправь ссылочку в конце и на статью Шепота ещё можно сослаться.
8. Ish_2 1031 02.04.10 18:10 Сейчас в теме
(7) Поправил. И Шепоту досталось.
11. Ish_2 1031 03.04.10 19:53 Сейчас в теме
(10) В указанных ссылках у Шепота приводится понимание Шепотом нарастающих итогов и ни слова про их эффективное вычисление.
12. anig99 2684 04.04.10 07:26 Сейчас в теме
(11) но там примерно так же описан пример для получения этих самых нарастающих итогов.
13. Шёпот теней 1741 04.04.10 16:18 Сейчас в теме
существует множество разных языков ... все они что делаю хорошо а что-то плохо ...

язык запросов существует для получения копий таблиц + фильтрация из БД ...

пытаться программировать, манипулировать данными на уровни запросов - утопия ... и СКД это наглядно демонстрирует ... Запрос+ТЗ = универсально, практично, феерично ...

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

... понятно, как задача для ума может это и интересно ... но не более ...

... вот ...
14. Ish_2 1031 04.04.10 17:46 Сейчас в теме
(13) Черт возьми , стал бы я практиковаться "для ума " !
В настоящий момент я считаю такую процедуру самым быстрым и эффекивным способом получения всех движений по регистру партий (читай- перепроведения документов по регистру партий).
Нужна ,конечно, тестовая конфигурация для подтверждения этого мнения. Пока она не представлена.

Шепот , ты упорно не хочешь изучать СКД.
Можно сказать , что в узком смысле СКД = запрос+тз+обработка тз.
Уж за что 1с не должно быть стыдно , так это за СКД.

"пытаться программировать, манипулировать данными на уровни запросов - утопия ... и СКД."

Я не согласен с тобой. Работая в клиент-серверном варианте мы, наоборот, просто обязаны пытаться "программировать, манипулировать данными" при помощи запросов. Для тебя же запросы - средство простой выборки данных, после которой "тыканье кнопок" ,т.е. любимый кодинг.

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

21. anig99 2684 05.04.10 08:51 Сейчас в теме
(13) язык запросов 1с может и существует только для получения информации, но в БД в чистом виде всё основывается на этих запросах и их быстродействии. Если посмотреть на работы по анализу производительности Гилёва, то основа у него - разбор запросов к СУБД генерируемых платформой 1с. Если всё сводилось только к кодингу в классическом смысле, то можно было бы продолжать работать с файлами с текстовом формате. БД и были придуманы для ускорения работы с чтением и записью в огромных массивах данных. А основной язык общения с СУБД - это запросы. И чем больше объем данных, тем более эффективным является правильно построенный запрос в правильно созданной БД по сравнению с обработкой кодом.
Естественно, запросный подход не идеален (а уж тем более запросный 2го уровня, когда запрос "транслируется" в родной язык БД), в частности, с учетом нарастающих итогов... Поэтому нужно соизмерять важность скорости получения результата и сложность достижения этой скорости. Поэтому поводу - пусть 1с самый простой и самый долгий - "перепровести всё нах" или какой-то, видимо, относительно простой, но ОЧЕНЬ долгий алгоритм примененный в документе "корректировка стоимости партий" (у меня он идет 7 часов! а результирующих движений 3000-7000 тыс на регистр, т.е. большую часть времени происходят именно расчеты). Второй путь - код и много мелких запросов - сейчас я его использую и проверка Fifo хоть и занимает несколько часов, но всё же меньше, чем проведение по партиям. 3ий неизвестный по поведению относительно производительности - расчет в одном сложном и оптимизированном запросе.
Valerich; Шёпот теней; +2 Ответить
22. Ish_2 1031 05.04.10 09:08 Сейчас в теме
(21) Конечно.
Нужно только пробовать на твоей конфигурации , чтобы убедиться что эффективнее.

Меня смущает составное поле в условиях соединения - МоментВремени.
Индекировать врем.таблицу по нему нельзя. Означает ли это , что оптимизатор запроса будет сканировать не индекс , а основную таблицу - что приведет к замедлению ?
23. alexk-is 6403 05.04.10 17:06 Сейчас в теме
(22) Сделай 2 поля Период и МоментВремени. Период точно можно проиндексировать.
26. Ish_2 1031 05.04.10 17:26 Сейчас в теме
(23) Но тогда в условии соединения вместо

НарРасход.МоментВремени > НарПриход.МоментВремени

придется написать

НарРасход.Период> НарПриход.Период ИЛИ
НарРасход.Период = НарПриход.Период И
НарРасход.Регистратор > НарПриход.Партия

Насколько мне известно, оптимизатор запроса если в условии соединения есть "ИЛИ"
вынужден сканировать не индекс , а основную таблицу. Что тоже не есть хорошо, т.к.
таблицы НарПриход и НарРасход могут быть очень большого размера.
27. alexk-is 6403 05.04.10 17:43 Сейчас в теме
(26) Вот без ИЛИ
НарРасход.Период > НарПриход.Период И
НарРасход.МоментВремени > НарПриход.МоментВремени
28. Ish_2 1031 05.04.10 18:20 Сейчас в теме
(27) Не понял. В твоем выражении
"НарРасход.Период>НарПриход.Период" - лишнее условие.

Потому что из "НарРасход.МоментВремени > НарПриход.МоментВремени " совершенно очевидно следует "НарРасход.Период>=НарПриход.Период".
И оптимизатор запроса всё равно будет проверять условие по Моменту времени.
В чем выигрыш ?
29. Ish_2 1031 05.04.10 18:35 Сейчас в теме
(27) Редактирование поста (28) , судя по всему невозможно. В нем ошибка.
Мне непонятен смысл : зачем добавлять еще одно выражение , т.е.
"НарРасход.Период > НарПриход.Период "
если оптимизатор запроса всё равно будет проверять неиндексируемое поле МоментВремени в
"НарРасход.МоментВремени > НарПриход.МоментВремени"
В чем выигрыш ?
32. ildarovich 6483 05.04.10 20:41 Сейчас в теме
(22) Могу сделать следующий, на первый взгляд парадоксальный вывод:
сравнение
НарРасход.МоментВремени > НарПриход.МоментВремени
в Вашем запросе НЕ ТРЕБУЕТСЯ!!!
Эта логическая ошибка поясняется схемой в файле (рис.2). Кстати, схема, поясняет и сущность метода. На словах дело в том, что проверка нужна, чтобы избежать списаний "по-красному". Но если Вы вырезаете их такой проверкой, то почему не уменьшаете на сумму вырезанных списаний накопленный расход?
Выход в том, чтобы списывать по-красному (тогда проверка не нужна!), либо делать третий накопленный расход (запрос будет другим)
Прикрепленные файлы:
33. Ish_2 1031 06.04.10 00:19 Сейчас в теме
(32) Попытаюсь понять. Завтра.
Странно, но рисунки перед опубликованием рисовал до смешного похожие на Ваши .
Хотя, возможно, это единственный наглядный способ отображения сути соединения по двойному неравенству.
38. Ish_2 1031 06.04.10 09:35 Сейчас в теме
После набора длинного ответа на (32) - ошибка сайта.
Регулярные глюки сайта просто бесят.
39. Шёпот теней 1741 06.04.10 11:30 Сейчас в теме
(38) ... ИС - бегая за "формой" однозначно теряет в "содержании" ... вот ...
41. Арчибальд 2709 06.04.10 12:51 Сейчас в теме
(38) За одного бита дают 1/8 байта 8-)
40. Ish_2 1031 06.04.10 12:46 Сейчас в теме
(32) Не согласен.
Строка в условии соединения
"НарРасход.МоментВремени > НарПриход.МоментВремени "
совершенно необходима.

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

Компромиссом следует считать следующий подход :
Строка
"НарРасход.МоментВремени > НарПриход.МоментВремени " из условий соединения убирается.
А в поля выборки добавляется строка
«Выбор Когда НарРасход.МоментВремени > НарПриход.МоментВремени
Тогда Истина
Иначе Ложь
Конец как ПризнакСвоевременности»

Тогда появляется возможность «отловить» в входной таблице эту ошибочную ситуацию.

Поэтому предложение просто убрать строку
"НарРасход.МоментВремени > НарПриход.МоментВремени "
из условий соединения нельзя назвать верным.

А в файле СписаниеПоМетодуФИФО.dt применено ЛЕВОЕ СОЕДИНЕНИЕ.
С обработкой значений NULL.
43. ildarovich 6483 06.04.10 14:37 Сейчас в теме
(40) Да, правильно, если проверка и нужна, то только для вычислений "ПризнакСвоевременности", а не для отбора записей в соединяемой таблице. При этом индекс по МоментВремени не нужен.
А вот левое соединение и обработка NULL - это неправильно, так как если расход не сделан, то следующие "своевременные" расходы должны соединяться с приходами, пропущенными в паре с несвоевременными расходами.
15. Шёпот теней 1741 04.04.10 21:46 Сейчас в теме
Ish_2 у меня совершенно нет желания принижать твой труд и его оспаривать ... наоборот я им восхищаюсь равно как и трудами anig99 ...

.. хм... в сотни раз .... это конечно ты перебрал хотя упорствовать не буду ... но я точно знаю что труды ВалерычА ( http://infostart.ru/profile/36029/ ) гораздо продуктивнее ... он уже добился быстродействия в 100 раз а возможно и более ...

также хочется напомнить и про труд Владимира ( http://infostart.ru/profile/2905/ ) хотя и в рамках отдельной конфигурации ...

... добиваться же быстродействия в рамках запроса ...? для меня очень и очень не понятно - для меня это создание исскуственных трудностей на пути поиска простых и эффективных решений ...

... соглашусь и с возможной, своей полной или частичной - НЕграмотностью ...

... вот ...
16. Шёпот теней 1741 04.04.10 21:54 Сейчас в теме
(15) + забыл ... видимо не совсем точно написал : СКД как раз и демонстрирует что Запрос+ТЗ есть сила ...

... вот ...

17. Ish_2 1031 05.04.10 07:36 Сейчас в теме
(15) Шепот , принижай мой труд ! Разрешаю.
Но убедительно - с аргументами.
Представь себе , что я внимательно читаю и проверяю ,что ты мне написал.
Ссылки на Валерыча и Владимира не убеждают .
Они рассматривали совсем другие темы.
18. Шёпот теней 1741 05.04.10 07:58 Сейчас в теме
(17) ... уж нет ... увольте Вас убеждать, Вас - это ваше поколение ... мне хвататет этого удовольствия и в жизни ... ваш молодЁжный бег по кругу меня никак не интересует ...

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

... я сам закрываю 26 счет, для подсчёта нулевой рентабельности, нууу это типа точкаБЕЗубыточности ... 3 разными способами ... прекрасно знаю что 1С механизмы очень долгие и добиться увеличения быстродействия на порядок, заменив их на свои, это почти без проблем ....

ссылки на ВалерычА и Владимира считаю основными ... так как эти товарищи прекрасно демонстрирует силу самостоятельного программирования ... не умаляя 1С как сверхУниверсальную систему ...

... ВОТ ...
19. Шёпот теней 1741 05.04.10 08:05 Сейчас в теме
(17) спорить конечно бесПолезно т.к. рано или поздно все приходит к записи таблицы ... нууу, например у тебя: "...Полученную таблицу движений можно или "подокументно" записать в регистр партий или предварительно сравнить с существующими движениями в регистре и записать только "изменения". ..."

... по сути, мы пропагандируем одно и то же решение - оптимально, 1С часто это делает неЭффективно из-за своей гиперУниверсальности, любыми доступными методами собрать данные в таблицу и записать её ... здесь мы едины ... просто я считаю что запрос для оперирования данными не эффективен а ты считаешь наоборот ... вот ...
20. Ish_2 1031 05.04.10 08:50 Сейчас в теме
(19) Говорю тебе : молодое поколоние выбирает запросы . И осуждает Шепота.
За что ? А вот за это :
1. "... добиваться же быстродействия в рамках запроса ...? для меня очень и очень не понятно"
2. "просто я считаю что запрос для оперирования данными не эффективен.."

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


24. alexk-is 6403 05.04.10 17:09 Сейчас в теме
Запросы в статье можно раскрасить получше :)
25. Ish_2 1031 05.04.10 17:13 Сейчас в теме
(24) Возможно, нужно раскрасить по-приличней.
Но мы с Шепотом как-то всё по-дедовски , да по-старинке ....
30. alexk-is 6403 05.04.10 20:06 Сейчас в теме
В том, что во временной таблице его можно проиндексировать.
31. Ish_2 1031 05.04.10 20:27 Сейчас в теме
(30) Мда... Браво !
Действительно, МоментВремени НЕЛЬЗЯ влючать в индекс в основных таблицах и МОЖНО Включать в индекс во временной таблице.
34. ildarovich 6483 06.04.10 02:11 Сейчас в теме
Теперь о грустном...

Оценка трудоемкости запросов 1, 2 и 3 приводит к формуле

O(n * n / 2) + O(m * m / 2) + O(n * m / 2),

где n - число приходов, m - число расходов. Оценка обосновывается
методом "вложенных циклов", который используется при оптимизации запросов.
Действительно, для каждого прихода в запросе 1, например, требуется просуммировать
в среднем n / 2 записей (при использовании индекса по моменту времени). То есть,
трудоемкость пропорциональна квадрату числа приходов (расходов для запроса 2).
Ускорение по методу http://infostart.ru/public/61295/ изменит оценку на следующую

O(n * ln(n)) + O(m * ln(m)) + O(n * m / 2),

что, конечно, гораздо лучше, но при наличии процедурных подходов с трудоемкостью

O(n + m),

не требующих дополнительной памяти
(а в Вашем случае хранится и обновляется примерно log(n) уровней итогов),
преимуществ метода "одного запроса" не усматривается.

Вас мог смутить реальный выигрыш по быстродействию метода
http://infostart.ru/public/61295/ в задаче просроченной задолжности.
Но там не было внешнего цикла! Там был переход от пропорции O(n) к пропорции O(ln(n)),
что существенно. В задаче ФИФО есть внешний цикл - задачу накопления нужно решить для каждой накладной.
И это все меняет.

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

Кстати, похожий вопрос обсуждался здесь:
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=113703&pg=1
jafariuse; minikos; CheBurator; +3 Ответить
42. Ish_2 1031 06.04.10 13:10 Сейчас в теме
(34) Теперь о грустном :
К сожалению ,оценку трудоёмкости вычислений я забыл. Поэтому о верности приведенных формул мне судить трудно.
Но и без формул понятно , что количество вычислений в текущем алгоритме больше , чем при "процедурном подходе".

Разумеется , приведенный в теме алгоритм с эффективным вычислением нар.итогов многократно выиграет у простого перепроведения расходных документов ,если в каждом расходном документе предусмотрен запрос к остаткам регистра партий.

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


44. ildarovich 6483 06.04.10 14:44 Сейчас в теме
(42) Да, так. Причем для Вашего "модельного" случая код занимает один - два десятка строк.
46. Ish_2 1031 06.04.10 16:41 Сейчас в теме
35. CheBurator 3389 06.04.10 02:34 Сейчас в теме
А вот что, нельзя было 3-5 предложениями описать ИДЕЙНУЮ суть алгоритма?
36. Ish_2 1031 06.04.10 08:51 Сейчас в теме
(35) Возможно, ты прав.
Но я побоялся рисовать что-то подобное рисунку в (32). Подумал что это не облегчит понимание , а еще больше запутает.
37. Шёпот теней 1741 06.04.10 09:29 Сейчас в теме
(36) ... за одного битого - двух не-битых дают ... вот ...
45. Ish_2 1031 06.04.10 16:20 Сейчас в теме
А вот левое соединение и обработка NULL - это неправильно, так как если расход не сделан, то следующие "своевременные" расходы должны соединяться с приходами, пропущенными в паре с несвоевременными расходами.


Для каждой значения Номенклатуры из таблицы НарРасход мы строим движения по регистру партий.
Поэтому если N-расход по M-номенклатуре получился "красным" , то зачем нам последующие "своевременные" расходы N+1,N+2 и т.д. по M-номенклатуре ?
Совершенно очевидно , что они не имеют смысла .
Для М+1-номенклатуры , конечно, будет выстроена своя последовательность движений расходов. Как и для M+2,M+3 и т.д.

Вот почему утверждение в приведенной цитате - неверно.

Тем более если в таблице НарРасход для М-номенклатуры имеются записи со значением поля КоличествоДо больше любого КоличествоПосле в таблице НарПриход эта запись при ВНУТРЕННЕМ СОЕДИНЕНИИ просто "пропадёт" в выходной таблице "без следов".
При ЛЕВОМ СОЕДИНЕНИИ мы достигаем того, что в выходной таблице гарантировано будут присутсвовать все регистраторы-расходы. И по полям признакам мы сможеи определить какое движение регистратор - неверное (или "красное").
47. ildarovich 6483 06.04.10 17:49 Сейчас в теме
(45) Не буду занудой и соглашусь, так как речь идет о реакции на ошибку пользователя. А это, в общем-то, дело вкуса. Как в анекдоте про тараканов - неважно утонут они или подорвутся на минах :D
48. Ish_2 1031 06.04.10 18:03 Сейчас в теме
(47) Ну и заканчивая , можно сказать :
т.к. в рамках рассматриваемой простейшей конфигурации "запросный" метод значительно уступит по быстродействию "процедурному подходу" (т.е. "вручную" просканировать две исходные таблицы Приход и Расход для получения движений),
то единственной , достойной внимания особенностью представленного алгоритма является перенос в трехзвенной системе( клиент-сервер приложений- сервер БД) всех вычислений на сервер БД.
49. orefkov 1972 07.04.10 09:23 Сейчас в теме
Все в одном запросе это конечно хорошо, но пока больше походит на то, что 1С из инструментов дала только вилку, и для поедания супа приходиться изголятся и пытаться сложить ложку из кучи вилок. В нормальной БД получение нарастающих итогов легко делается процедурным методом на сервере - обходишь курсор и подбиваешь суммы.
50. Арчибальд 2709 07.04.10 09:54 Сейчас в теме
(49) Хоть не палочки бамбуковые :o
51. truba 07.04.10 10:13 Сейчас в теме
53. Ish_2 1031 08.04.10 10:19 Сейчас в теме
(51) Конечно, так. Но по ссылке в (34) нашел цитату Aleks2 на SQL.ru
Запомни:
1) Если у тебя есть возможность не пользоваться курсором - не пользуйся им.
2) Если у тебя НЕТ возможности не пользоваться курсором - ВСЕ РАВНО НЕ ПОЛЬЗУЙСЯ.
-------------
Запрос всегда быстрее курсора, единственное исключение: неправильный (неоптимальный) запрос.


В общем случае это ,конечно, неверно. Но уж больно симпатично.
54. orefkov 1972 09.04.10 12:39 Сейчас в теме
(53)
Ну, опять же на нормальной БД нарастющие итоги на врем-таблицу можно накрутить и без курсора.
update vt_total
set @СуммаНачало = case when vt_total.НоваяСтрока = 0 then @СуммаКонец else vt_total.СуммаНачало
,@СуммаКонец = @СуммаНачало + vt_total.Оборот
,vt_total.СуммаНачало = @СуммаНачало
,vt_total.СуммаКонец = @СуммаКонец 
55. Ish_2 1031 09.04.10 15:20 Сейчас в теме
(54) Ага,примерно так.
И получается , что наличие в языке запросов Update делает ненужными любые разговоры об эффективном вычислении нарастающих итогов , занимающего
львиную долю времени в текущем алгоритме.
56. hogik 428 09.04.10 17:52 Сейчас в теме
(55)(54)(51)
Логотип темы - «Мы пишем запросы!».
Позволю себе высказаться не в тему.
Для простого и эффективного решения аналогичных задач не требуются:
1) Наличие в языке запросов Update.
2) Временные таблицы.
3) Процедурные методы на сервере.
4) Курсоры.
5) Всякие «левые» и «правые» соединения.
Да и сами запросы не требуются. ;-)
Печально, что движение по «столбовой дороги развития СУБД»(с) ведет в тупик. А «круглые колеса, на каких во всем мире принято ездить»(с) ускоряют это движение… :-(
57. Ish_2 1031 10.04.10 17:44 Сейчас в теме
(56) Хм.. Владимир, Вы упорно отстаиваете свой экстравагантный взгляд на развитие СУБД с отрицанием языка запросов SQL . И ,как обычно, не приводите хотя бы внятного обозначения альтернативного подхода.
Впрочем , однажды Вы в своей теме привели текст кода а-ля Clipper Summer '87, обозначающий Ваш подход к решению такого рода задач и заставивший меня смахнуть слезу :

do while !eof()
.........
enddo

Т.е. сканирование таблицы и ручной кодинг.
Возврашаясь в 1987г , Вы отрицаете ту самую двадцатилетнюю "столбовую" дорогу :
-Утверждение стандарта SQL от 1992г.
-Развитие трехзвенной системы клиент-сервер приложений-сервер БД.

Оно конечно, Вам это никто не запретит. Но думаю , Вы найдете мало сторонников.
Если вдруг на каком -то этапе на "столбовой" дороге откажутся от языка запросов - я первый сниму перед Вами шляпу.
58. hogik 428 10.04.10 18:44 Сейчас в теме
(57)
Игорь.
Я не отрицаю язык запросов в развитии СУБД. Я утверждаю, что для наших задач надо иметь ДВА способа (ЯМД) обработки данных. И в задачах типа «Нарастающие итоги» просматривать таблицы построчно в обычном цикле на стороне клиента. Это быстрее работает, не загружает сервер лишней работой, проще писать ««ручной кодинг»». Есть алгоритмы, где эффективней использовать язык запросов.
А в целом, наличие двух ЯМД позволяет проектировать схему БД не под средства манипулирования данными, а под предметную область. И отпадает необходимость в «трехзвенной» архитектуре, как средства преобразования одного ЯМД в другой.
60. Ish_2 1031 10.04.10 20:10 Сейчас в теме
(58) Истина всегда конкретна (с).
Соображения общего плана (58) меня мало в чем убеждают.
Разберемся конкретно .
Мы разбираем задачу вычисления нарастающих итогов в клиент-серверной архитектуре.
Цитататы :
"Для простого и эффетнаективного решения аналогичных задач не требуются:
1..5 . Да и сами запросы не требуются.."
"И в задачах типа «Нарастающие итоги» просматривать таблицы построчно в обычном цикле на стороне клиента. Это быстрее работает, не загружает сервер лишней работой, проще писать ««ручной кодинг»»."

Из этих цитат вытекает , что в клиент-серверной архитектуре для вычисления нарастающих итогов:

1. БОЛЕЕ эффективно загрузить таблицу с сервера на клиента и далее на клиенте ручным кодингом просканировать таблицу в цикле (do while...skip...enddo).
2. МЕНЕЕ эффективно оставить таблицу на сервере и одной командой Update получить таблицу нарастающих итогов см (54)

Так ? Или я что-то напутал ?
62. hogik 428 10.04.10 22:44 Сейчас в теме
(60)
Игорь.
1) Для обработки таблицы навигационным способом не требуется загружать таблицу с сервера на клиент. Выполняется чтение по одной записи. Вычисление и накопление нарастающего итога на клиенте для каждой строки в переменной оперативной памяти. Выводится в отчет строка вместе с вычисленным итогом. Т.е. выполняется чтений столько раз, сколько строк в таблице (обозначим - N).
2) На сервере же формируется рабочая таблица (в простейшем случае N чтений и N записей). Далее читаем каждую строку рабочей таблицы (N чтений), вычисляем нарастающий итог и записываем его в каждую строку (N обновлений). Далее передаём все строки рабочей таблицы клиенту (N чтений). Итого 5*N чтений/записей.
По сети, в обоих способах, предаётся одинаковое количество строк.
63. Ish_2 1031 11.04.10 11:31 Сейчас в теме
(62) Владимир.
Чтение (62) вызвало у меня столько вопросов, что я просто оробел что-то спрашивать.
Допускаю, что моего разумения просто не хватает , чтобы осилить (62).
64. hogik 428 11.04.10 13:56 Сейчас в теме
(63)
Игорь.
Жалко, что Вы принципиально не используете «смайлы».
Сообщение #63 – это шутка?
Или намек на мою дурость?
65. Ish_2 1031 11.04.10 14:01 Сейчас в теме
52. Ish_2 1031 08.04.10 10:09 Сейчас в теме
(49) Я так и не отгадал загадку :
Почему в языке запросов 1с не разрешен Update.
Понятно , что не стоит разрешать Update при обращении к таблицам БД.
Но почему не разрешен Update к временным таблицам хоть убей - не пойму.
59. rhtr 65 10.04.10 19:34 Сейчас в теме
61. anig99 2684 10.04.10 22:21 Сейчас в теме
Кстати... С одной стороны, обработка на клиенте удобнее... С другой стороны это противоречит концепции тонкого клиента и web интерфейсов. Узкие или загруженные каналы требуют уменьшение объема передаваемой информации. Это раз. Во-вторых, клиентские машины могут быть маломощными не только из-за экономии средств. Нетбуки, наладонники и т.д. имеют возможность работы с 1с, но не могут переваривать огромные объемы информации. Поэтому нужно идти по пути переноса обработки данных с клиентских компьютеров на сервера в любом виде: будь то запрос, или инструкция к компилятору.
66. rhtr 65 13.04.10 03:28 Сейчас в теме
Этап III .Особенно - "предварительно сравнить с существующими движениями в регистре и записать только "изменения". А на этом месте можно поподробнее.Будет очень хорошо если дополните конфу.Вам же как Гению Партий!!!.
Пасиба :)
67. Ish_2 1031 13.04.10 08:11 Сейчас в теме
(66) Место Гения давно и прочно занято.
Вариант:
1. Мы получили запросом ТаблицуДвижений.
2. Делаем Полное Соединение с движениями из регистра партий.
3. Оставляем в таблице , полученной в п.2, только расхождения , т.е. получаем ТаблицуРасхождений.
4. Затем с помощью запроса
"Выбрать Различные Регистратор ИЗ ТаблицаРасхождений" получаем таблицу -столбец
с документами , которые нужно перепровести.
5. Сканируя таблицу, полученную в п.4, для каждого документа- регистратора выбираем нужные движения из ТаблицыДвижений и записываем их в регистр.
68. Арчибальд 2709 13.04.10 08:16 Сейчас в теме
(67)
Место Гения давно и прочно занято.
Кем :o
69. Ish_2 1031 13.04.10 08:23 Сейчас в теме
(68) Гений 1с , в миру Осипов Сергей.
Об изгнании его с ИС я писал в теме Life "Тошнота как реакция на свободу".
70. Арчибальд 2709 13.04.10 08:27 Сейчас в теме
(69) Фуу... А я-то понял, что его место на ИС кто-то занял :D
74. Шёпот теней 1741 09.08.10 08:12 Сейчас в теме
(69) ... а я не нашЁл у Вас этой статьи ... нельзя ли её где-нибудь и как-нибудь по-читать-то ... ? ... или дайте пожалуйств ссылку НЕумелым ... вот ...
72. Ish_2 1031 13.04.10 09:09 Сейчас в теме
(71) Пока нереально.
Если в языке запросов 1с появится Update , Declare , Create Table (для временных таблиц), то представленный алгоритм , на мой взгляд, для больших таблиц выиграет у любого другого.
Это предсположение основывается на том , что
вся тяжесть вычислений в алгоритме ложится на вычисление нарастающих итогов.
С помощью команды Update нарастающие итоги считаются очень быстро.
75. seleand 09.08.10 09:10 Сейчас в теме
(72) согласен с Маньяком. Решение задачи в лоб - это просто жесть.
Вы ждете возможностей языка, которые позволят втиснуть ваши огромные вычисления в рамки приличий по быстродействию? А решение лежит в другой стороне. Смоьтреть надо в сторону изменения структуры регистров, которая позволит анализировать только то, что реально нужно...
77. Ish_2 1031 11.08.10 16:38 Сейчас в теме
(75) Маньяк так Маньяк. Жесть так жесть. Это понятно.
Остальной текст "жестьтоко" загадочен.
73. NCCSOFT 130 09.08.10 08:02 Сейчас в теме
Два года назад я тоже самое пытался сделать для 7.7 :D на языке MS SQL, и там есть Update, но его скорость меня не устроила, так как базу проводил за 3 года (FIFO), потом выгружал в динамические таблицы в SQL - тоже тормоза... потом плюнул на все технологии выгрузил данные в txt-файл (10 мин), на Дельфи конвертирую в свой формат (2 мин), записываю (чтобы при следующих запусках не конвертировать по-новой), и делаю расчет по FIFO. База за 3 года проводится за 1 секунду (ОДНУ СЕКУНДУ). Вот и все. Разработка тут: Разработка тут Скоро сделаю внешнюю обработку для 8.1 - выгрузка данных, чтобы можно было проверять 1С - правильно ли она по FIFO считает.
Шёпот теней; +1 Ответить
76. Ish_2 1031 11.08.10 16:33 Сейчас в теме
(73) В солнечной Анапе , чтобы выйти в интернет на почте нужно предьявить паспорт.
Попросив уже сидевшего за компьютером человека посмотреть ИС , увидел комментарий и побежал за паспортом. Жара , скучно, на море ни ногой - делать нечего.
Как обычно , хмыкну там где восторгается Шепот.
Выгрузки - загрузки в txt, потом в свой формат и т.д, чтобы потом "ЗА ОДНУ СЕКУНДУ" !
- это для кого текст ? Для специалистов ? Если - да , то для каких ?

В статье предлагается общий алгоритм списания по методу ФИФО.
Который может быть реализован как на платформе 1с , так и на другой платформе средствами только TSQL. В последнем случае эффективность реализации алгоритма многократно выше.
( с помощью Update нарастающие итоги считаются быстрее)
79. NCCSOFT 130 11.08.10 21:12 Сейчас в теме
(76) Привет отдыхающим!! ;-)

Выгрузка и загрузка (конвертация) у меня происходят в 3 часа ночи... зато при открытии пользователем мгновенно загружается в динам.массив и идет работа с OLAP (по вчерашний день)....

Метод FIFO на 1С делал применительно к расчету дебиторки / кредиторки, когда считал взаиморасчеты и самое главное кол-во дней просрочки... быстродействия хватило... "Отчеты о просрочке долгов" А вот с партиями - увы нет - 1С это не потянет!!! - точнее база будет проводится столько ко же, как при обычном проведении, ну не 6 часов, а всего 2 часа :-) Потом на SQL делал хранимую процедуру метода FIFO - тоже тормоза... ну не может SQL сделать update даже миллиона записей!!!! (поле себестоимость) - не может и все!! select может, а update нет....

В общем то, статья хорошая, все нормально. Метод FIFO, LIFO,... известные. Есть даже метод "списания максимальной себестоимости" (который придумал мой знакомый)... Но мне все же нравится метод FIFO!

Кстати, когда я практически его реализовывал - и при гашение долгов и при гашении партий - выяснилось, что "в чистую" этот метод на практике не применим, и "за один проход" не получается. А причина была в том, до метода FIFO приходится делать первый проход при котором идет гашение с учетом явных ссылок (начиная от сторно, возврат ошибочно перечисленных сумм, возврата товара и других движений....). Вот, что хотелось бы добавить к статье.

(78) :-)
78. tango 488 11.08.10 16:51 Сейчас в теме
80. Ish_2 1031 16.08.10 11:45 Сейчас в теме
(78) Вот и ты , Миша, не любишь иша ... Как эта тетка на почте :

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

Крыть было нечем и я решился .. перегнувшись через стойку доверительно сообщил:
- Девушка , а трусы на мне не желтые , а померанчевые ! Бачишь ?

Пока она с трудом подбирала ответ я понял , что не попал. Мда... Здесь вам не инфостарт , "штучки-дрючки" не проходят и не дожидаясь ответа ,я поперся за паспортом.
81. Арчибальд 2709 16.08.10 11:49 Сейчас в теме
(80) Таки тетка или девушка?
82. Ish_2 1031 18.08.10 10:07 Сейчас в теме
(81) Кавалер к тетке обращается - "девушка!". Не знал ?
83. Арчибальд 2709 18.08.10 10:25 Сейчас в теме
(82) Не знал. Сам пользуюсь терминами "сударыня" или "миледи" :oops:
84. y-str 53 25.08.11 10:05 Сейчас в теме
Добрый день!

Создал новую публикацию (http://infostart.ru/public/88999/) с возможным альтернативным алгоритмом.
Милости прошу комментировать :)

---
С уважением,
Юрий Строжевский
85. ambal49 19.10.11 10:51 Сейчас в теме
Вопрос, а если приходная накладная сделана со знаком минус? получается она выпадет из последнего запроса а по идее должна скорректировать предыдущие распределения, либо надо все приходы со знаком минус переквалифицировать в расходы со знаком плюс :). Что тоже неправильно :)
86. Ish_2 1031 19.10.11 11:07 Сейчас в теме
(85) Приходы с отрицательной суммой в статье не рассматривается.
1. Или нужно дополнительно обрабатывать таблицу приходов , что избавиться от "минусов".
2. Или алгоритм по Фифо должен быть существенно усложнен.
87. vers139 51 09.11.11 18:57 Сейчас в теме
В СКД в вычисляемых полях появилось возможность использовать ВЫЧИСЛИТЬВЫРАЖЕНИЕ(). Лично у меня получилось поделить долг между накладными. Берём остатки по регистру взаиморасчёты, левое соединение на регистраторы регистра взаиморасчёты, сортировка в порядке убывания даты регистратора, группируем по клиенту и договору. + вычисляемое поле. В нём я использовал выражение:
Выбор 
Когда ВычислитьВыражение("Сумма(СуммаДок)", , , "Первая", "Текущая") < Долг 
тогда СуммаДок 
Когда ВычислитьВыражение("Сумма(СуммаДок)", , , "Первая", "Текущая") - Долг < СуммаДок 
тогда СуммаДок - (ВычислитьВыражение("Сумма(СуммаДок)", , , "Первая", "Текущая") - Долг) 
Иначе 0 
конец

Всё почти хорошо. Однако при использовании дополнительной группировки по степени просроченности долга (долг не просрочен, долг просрочен не более на 5 дней, долг просрочен на срок 5-30 дней и т.д.) вычисляемое поле вычисляется в пределах отдельной группировке по степени просроченности долга, а не в пределах клиента. Подозреваю, что надо "побаловаться" с параметрами ВычислитьВыражение(), но пока не додумал. Может у кого-то получилось понять суть этих параметров. Прошу поделиться идеями, ибо у меня уже мозг закипает.
88. Ish_2 1031 09.11.11 19:12 Сейчас в теме
(87) Вы описали задачу НЕ ФИФО , рассматриваемую в этой теме, а ПросроченныеДолги.
В голову даже не приходило решать эту с помощью выражений СКД.
Впрочем, я еще даже не установил 14 релиз платформы.
89. vers139 51 09.11.11 20:45 Сейчас в теме
(88) простите просматривал все темы по Накопленным итогам. В этой самые последние сообщения. Тем более, что дебиторка использует ЛИФО. Так что принцип, думаю, аналогичный.
90. S_DS 23.11.11 09:26 Сейчас в теме
91. Ish_2 1031 23.11.11 10:09 Сейчас в теме
(90) Как общее соображение принимается к сведению.
На мой вкус, только не хватает вывода или утверждения.
92. tormozit 5473 24.11.11 22:01 Сейчас в теме
Мне другая интересная задача недавно попалась -
Получить таблицу минимальных дозакупок на каждый день месяца для того чтобы вывести в ноль все ежедневные отрицательные остатки задним числом. Пример
Дата Остаток ! Дозакупка НовыйОстаток
01 -3 3 0
02 4 0 7
03 -1 0 6
04 -4 0 2
05 -7 5 0
06 2 0 7

Вот нужно получить колонку Дозакупка.
Естественно хотелось бы решить ее запросом.
93. Ish_2 1031 25.11.11 08:38 Сейчас в теме
(92) Мммм.. неплохо. Создай тему с решением.
Я сыграю "вторым номером", т.е. оппонентом.

P.S. На всякий случай : эффективного решения в данный момент у меня нет.
94. Ish_2 1031 05.12.11 11:09 Сейчас в теме
(92) Впрочем, возвращаясь к твоей задаче, замечу , что такая постановка малопригодна для практического применения. Оформляя доп.приходы по итоговым остаткам на конец дня , мы не учитываем реальную ситуацию,при которой отрицательные остатки могут возникать несколько раз в течение дня .
Конечно , можно решать и твою задачу как некий упрощенный частный случай.
Но для общего случая ( интересен , на мой взгляд именно он) правильно формулировать следующим образом :

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

На выходе должны получить таблицу РасходныеДокументыСОтрицательнымиОстатками.
Далее нужен анализ :
или сдвинуть расходный документ во времени в течение дня.
или оформить доп. приход.
Остатки на конец периода должны остаться неизменными.

Таким должен быть , на мой взгляд , подход к решения такой задачи.
95. cargobird 291 14.10.16 15:09 Сейчас в теме
Скачал, запускаю на 8.3.9 в Конфигураторе.
Загружает.
Задает вопрос о конвертации.
И после подтверждения сразу в дамп.
Разучилась, видимо, превращать базы на 8.1 в 8.2.
Пришлось искать 8.2 для конвертации и хорошо, что нашел, сконвертировал.
Но оказалось что все еще проще. В окне настройки инф.базы надо поменять с 8.3 на 8.2)
Или пятница, или уже очевидные вещи вылетают из головы)
96. CheBurator 3389 15.10.16 15:08 Сейчас в теме
осциллирующую функцию остатков разложить на сумму монотонно убывающих функций. каждая входящая партия остатков может только убывать. соответсвенно если по партии есть отрицательный остаток - нужно дозакупить этот отрицательный остаток. найти дату по минусовому хвосту - плвеое дело.
97. Ish_2 1031 06.11.16 09:43 Сейчас в теме
(96) CheBurator,
Привет , Чебур. Сколько лет прошло ?
Ты написал что-то умное и серьезное.
После школы, стало быть , еще не забыл про "монотонно убывающие функции".
А я забыл . Но был рад тебя почитать !
98. maxis33 42 01.07.19 19:02 Сейчас в теме
Отличный метод!
А LIFO из него никто не делал?
99. maxis33 42 03.07.19 18:52 Сейчас в теме
Создал отдельную темку на форуме про LIFO.. если кто знает, помогите плз...
http://forum.infostart.ru/forum9/topic220953/message2246820/#message2246820
100. Ish_2 1031 14.07.19 17:50 Сейчас в теме
(99) Давно это было..Вряд ли помогу.
Оставьте свое сообщение