|
кто делал списание по ФИФО прямо в запросе? | ☑ | ||
---|---|---|---|---|
0
vde69
модератор
28.10.13
✎
16:32
|
решил сделать прямо в запросе, чую можно но что-то муторное.
кто делал? поделитесь :) |
|||
1
Ненавижу 1С
гуру
28.10.13
✎
16:33
|
||||
2
Господин ПЖ
28.10.13
✎
16:34
|
все делали имхо... кто к экзамену по платформе готовился
|
|||
3
NcSteel
28.10.13
✎
16:35
|
(0) ИМХО, но глупость это ФИФО в запросах.
|
|||
4
Wobland
28.10.13
✎
16:37
|
(2) я не делал. сразу, ибо муторно и нафих не надо
|
|||
5
scanduta
28.10.13
✎
16:40
|
А в чем сложность то?
|
|||
6
Новиков
28.10.13
✎
16:40
|
(0) не, Дим. Не делай. Овчинка выделки не стоит. В цикле закрыть для средне-статистического документа с проверкой хватает/не хватает получается быстрее по дереву, нежели нужные колличества получать переджойнами.
Для маленьких, теория: http://infostart.ru/public/99207/ |
|||
7
kumena
28.10.13
✎
16:52
|
"все делали имхо... кто к экзамену по платформе готовился"
там только выборка данных в запросе |
|||
8
kumena
28.10.13
✎
16:53
|
смысл запроса быстро вытаскивать данные из базы за один раз.
смысла делать вычисления прямо тем же запросом по моему нет. |
|||
9
vde69
модератор
28.10.13
✎
17:00
|
нарастающий итог я сделал давно, здесь проблема как отделить часть данных
например надо списать 250р, строим времянку: сумма, дата - нарастающий итог +100 1.1.1 - 100 +200 2.1.1 - 300 -100 3.1.1 - 200 -100 4.1.1 - 100 по алгоритму (1) я получу 1.1.1 - 100 2.1.1 - 200 3.1.1 - 200 4.1.1 - 100 что не правильно я должен получить 1.1.1 - 100 2.1.1 - 200 то есть у меня проблемы с тем что бы в результат не попадали лишние строки |
|||
10
Ненавижу 1С
гуру
29.10.13
✎
09:59
|
(9) вообще-то строится отдельно нарастающий итог по приходу и отдельно по расходу и затем определяются несписанные партии, в (1) сильно упрощенный вариант
|
|||
11
GANR
29.10.13
✎
10:14
|
(0) Можно это сделать, но не нужно. (2) Я готовился, но мне в голову не приходило делать это в запросе - нарастающий итог там надо считать, а в 1С-запросе это будет очень и очень ресурсоемкой операцией, да и запрос может быть очень непростым.
А вот в MS SQL 2012 с его специально заточенными под подобные задачи оконными функциями решать такие задачи - одно удовольствие http://www.sql-tutorial.ru/ru/book_running_totals.html. |
|||
12
GANR
29.10.13
✎
10:17
|
+(11) Не факт, конечно, что в МС СКЛ 2012 это будет работать быстрее и менее ресурсоемко, но запрос написать стало существенно проще.
|
|||
13
vvf1973
29.10.13
✎
10:34
|
(9) интересно, а нарастающие итоги вы случайно не запросом делали? :-)
а так http://nashe1c.ru/materials-view.jsp?id=312 :-) |
|||
14
vde69
модератор
29.10.13
✎
10:39
|
в результате я отказался от идеи, все равно пришлось кое чего считать в 1с, как всегда истина где-то посередине...
|
|||
15
Sorm
29.10.13
✎
11:02
|
(11) Коррелированные подзапросы, конечно, красиво, но долго.
|
|||
16
MadHead
29.10.13
✎
11:11
|
Нарастающий итог в запросе еще то зло. Списание не рискнул бы делать в реальных задачах. А в отчетах иногда применяю
|
|||
17
GANR
29.10.13
✎
11:23
|
(15) Да нарастающий итог в запросе как ни делай - хоть коррелированный подзапрос, хоть с соединениями заморочиться (единственный вариант для 1С) - все равно ресурсоемко и долго будет, только оконные функции МС СКЛ 2012 могут сделать запрос более-менее нормальным.
|
|||
18
Serginio1
29.10.13
✎
12:03
|
(17) Если закинуть во внешнюю таблицу и проиндексировать то будет быстро. v8: Подзапросы с Выбрать Первые
|
|||
19
GANR
29.10.13
✎
12:34
|
(18) Ну да, индексы, конечно, ускорят процесс... Но даже если это будет и быстро, то сколько же оперативной памяти может сожрать ЭВМ, чтобы рассчитать все это безобразие в запросе, да и гибкость такого запроса будет никакая - лучше уж код. Там ведь надо каждую партию соединить со всеми партиями, поступившими раньше ее самой.
|
|||
20
PR
29.10.13
✎
12:36
|
(0) У меня только один вопрос. Нахрена?
|
|||
21
Лодырь
29.10.13
✎
12:43
|
(20)
1. Не надо писать гору ручного кода и обработка списания выглядит красиво. 2. Развлечение в стиле "а можно ли вырезать апендицит автогеном через задницу" 3. А вдруг будет работать быстрее? 4. Если могу, почему бы и нет? |
|||
22
Serginio1
29.10.13
✎
18:41
|
(19) Достали эти деревья, там где нужно сделать итоги по группе полей. Помню замучился и написал униврсальную процедуру списания
Функция ПолучитьТзСписаний(Тз,Регистр,КолонкаСписываемогоКоличества,КолонкаКоличества,КолонкиСумм,отказ,СтрокиДляСортировки="") Экспорт МассивИзмерений=новый Массив; Колонки=Тз.Колонки; Для каждого стр из Колонки Цикл Если (стр.Имя<>"ТзПоГруппе") и (стр.Имя<>КолонкаСписываемогоКоличества) Тогда МассивИзмерений.Добавить(Стр.Имя) КонецЕсли; КонецЦикла; Если ПустаяСтрока(КолонкиСумм) Тогда МассивКолонокСумм=Новый Массив; Иначе МассивКолонокСумм=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(КолонкиСумм,","); КонецЕсли; Резулт=Регистр.СоздатьНаборЗаписей().Выгрузить().СкопироватьКолонки(); ИмяРег=Регистр.СоздатьНаборЗаписей().Метаданные().Имя; Сравнение=Новый СравнениеЗначений; Для каждого стр из Тз Цикл ТзПоГруппе=стр.ТзПоГруппе; СписываемоеКоличество=ТзПоГруппе[0][КолонкаСписываемогоКоличества]; Если СписываемоеКоличество>Стр[КолонкаКоличества] Тогда СтрСообщ=ИмяРег+" Для измерений "; Для каждого Измерение из МассивИзмерений Цикл СтрСообщ=СтрСообщ+" "+Измерение+"="+Стр[Измерение] КонецЦикла; СтрСообщ=СтрСообщ+" |Остаток "+КолонкаКоличества+"="+Стр[КолонкаКоличества]+"<"+СписываемоеКоличество+" в накладной"; Сообщить(СтрСообщ); отказ=истина; //продолжить СписываемоеКоличество=Стр[КолонкаКоличества]; КонецЕсли; Если не ПустаяСтрока(СтрокиДляСортировки) Тогда ТзПоГруппе.Сортировать(СтрокиДляСортировки,Сравнение); КонецЕсли; ЗаполнитьТзСписания(ТзПоГруппе,Резулт,СписываемоеКоличество,КолонкаКоличества,МассивКолонокСумм); Если СписываемоеКоличество>0 Тогда СтрСообщ="Для измерений "; Для каждого Измерение из МассивИзмерений Цикл СтрСообщ=СтрСообщ+" "+Измерение+"="+Стр[Измерение] КонецЦикла; СтрСообщ=СтрСообщ+" |не списано "+СписываемоеКоличество; Сообщить(СтрСообщ); КонецЕсли; КонецЦикла; возврат Резулт КонецФункции и пример использования Рез=акСмешанный.глСгруппироватьТзПоПолям(Запрос.Выполнить().выгрузить(),"Номенклатура,ХарактеристикаНоменклатуры","Количество"); ТзРезулт=акСмешанный.ПолучитьТзСписаний(рез,РегистрыНакопления.акПродажи,"КоличествоСписания","Количество","СебеСтоимостьUSD,СебеСтоимостьRUR",Отказ); |
|||
23
Serginio1
29.10.13
✎
18:45
|
Процедура ЗаполнитьТзСписания(Тз,ТзСписания,СписываемоеКоличество,КолонкаКоличества,КолонкиСумм)
Если СписываемоеКоличество=0 Тогда возврат КонецЕсли; Для каждого Стр из Тз Цикл КоличествоПоСтроке=Стр[КолонкаКоличества]; Если КоличествоПоСтроке<=0 Тогда продолжить КонецЕсли; СтрТз=ТзСписания.Добавить(); ЗаполнитьЗначенияСвойств(СтрТз,Стр); Если СписываемоеКоличество>=КоличествоПоСтроке Тогда СписываемоеКоличество=СписываемоеКоличество-КоличествоПоСтроке; Иначе СтрТз[КолонкаКоличества]=СписываемоеКоличество; Если КоличествоПоСтроке<>0 Тогда Коэф=СписываемоеКоличество/КоличествоПоСтроке; Для каждого Колонка из КолонкиСумм Цикл СтрТз[Колонка] =Стр[Колонка]*Коэф КонецЦикла; КонецЕсли; СписываемоеКоличество=0; КонецЕсли; Если СписываемоеКоличество=0 Тогда возврат КонецЕсли; КонецЦикла; КонецПроцедуры |
|||
24
Classic
29.10.13
✎
18:48
|
Вот прям щас и делаю. ФИФО ж не только к товарным движениям относится?
|
|||
25
1Cv8_accepted
29.10.13
✎
18:49
|
(0) АВТОУПОРЯДОЧИВАНИЕ
|
|||
26
Classic
29.10.13
✎
18:49
|
Самыйй жир считать начальный остаток
|
|||
27
GROOVY
29.10.13
✎
18:50
|
Народ, все в запросах сделать можно, но не нужно. Даже с точки зрения производительности. Я уж молчу про поиск ошибок и последующей адаптации.
|
|||
28
1Cv8_accepted
29.10.13
✎
18:51
|
(0) А вообще зависит от объёмов данных. Иной раз лучше и на клиенте сложение-вычитание сделать, чтобы дать серверу глоток для следующего ожидающего запроса. Но это - такой тооонкий момент...
|
|||
29
1Cv8_accepted
29.10.13
✎
18:52
|
(27) д!
|
|||
30
kiruha
29.10.13
✎
19:00
|
(21)
Все правильно кроме - быстрее будет работать |
|||
31
Serginio1
29.10.13
✎
19:03
|
23+ Функция СравнитьПоля(Структ,Строка)
Для каждого стр из Структ Цикл Если Стр.Значение<>Строка[Стр.Ключ] Тогда возврат ложь КонецЕсли; КонецЦикла; возврат истина КонецФункции Процедура ДобавитьПоля(Тз,ТзОриг,Поля) Экспорт если ПустаяСтрока(Поля) Тогда возврат КонецЕсли; МассивПолей=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(Поля,","); Для каждого Поле из МассивПолей Цикл Колонка=ТзОриг.Колонки.Найти(Поле); Тз.Колонки.Добавить(Колонка.Имя,Колонка.типЗначения); КонецЦикла; КонецПроцедуры Процедура ПроссумироватьПоля(Тз,ТзСтрок,МассивСуммируемыхПолей) Для Каждого Стр из МассивСуммируемыхПолей Цикл Тз[стр] = ТзСтрок.Итог(Стр); КонецЦикла; КонецПроцедуры Функция глСгруппироватьТзПоПолям(Тз,Поля,СуммируемыеПоля,ПоляСортировкиТзПоГруппе="") Экспорт перем Тип,Длина,Точность,ЕстьСпр,ЕстьДок; ЕстьСпр=0; ЕстьДок=0; //Тз.ПолучитьПараметрыКолонки(поле,тип,Длина,Точность); если ПустаяСтрока(СуммируемыеПоля) Тогда МассивСуммируемыхПолей=Новый массив; Иначе МассивСуммируемыхПолей=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СуммируемыеПоля,","); КонецЕсли; Структ=Новый Структура(Поля); // Для того что бы правильно сртировались элементы с одинаковыми представление // Сначала отсортируем по внутреннему значению //а после группирования по представлению по возрастанию Сравнение=Новый СравнениеЗначений; // Тз.Сортировать(ПолучитьСтрокуСортПоля(Поле,Тз,ЕстьСпр,ЕстьДок)); ПоляСортировки=Поля; Если не пустаяСтрока(ПоляСортировкиТзПоГруппе) Тогда ПоляСортировки=ПоляСортировки+","+ПоляСортировкиТзПоГруппе КонецЕсли; Тз.Сортировать(ПоляСортировки,Сравнение); ТзФ=новый ТаблицаЗначений; ДобавитьПоля(ТзФ,Тз,Поля); ДобавитьПоля(ТзФ,Тз,СуммируемыеПоля); ТзФ.Колонки.Добавить("ТзПоГруппе",Новый ОписаниеТипов("ТаблицаЗначений")); ТекСтр=0; Заявка=0; НачСтр=-1; СтрТзф=""; Если Тз.Количество()>0 Тогда Для сч=0 По Тз.Количество()-1 Цикл строка=тз[сч]; Если (Сч=0) или не СравнитьПоля(Структ,Строка) Тогда Если НачСтр>-1 Тогда ТекТз=Тз.Скопировать(ПолучитьМассивСтрок(Тз,НачСтр,сч-1)); СтрТзф.ТзПоГруппе=ТекТз; ПроссумироватьПоля(СтрТзф,ТекТз,МассивСуммируемыхПолей); КонецЕсли; СтрТзф= ТзФ.Добавить(); Для каждого стр из Структ Цикл Поле=Стр.Ключ; Значение=Строка[поле]; Структ[Поле]=Значение; СтрТзф[Поле]=Значение; КонецЦикла; НачСтр=сч; КонецЕсли; // глКлонироватьЗапись(Тз,сч,ТекТз) КонецЦикла; Если НачСтр>-1 Тогда ТекТз=Тз.Скопировать(ПолучитьМассивСтрок(Тз,НачСтр,Тз.Количество()-1)); СтрТзф.ТзПоГруппе=ТекТз; ПроссумироватьПоля(СтрТзф,ТекТз,МассивСуммируемыхПолей); КонецЕсли; КонецЕсли; Возврат ТзФ; КонецФункции |
|||
32
КонецЦикла
29.10.13
✎
19:06
|
(11) Нарастающий итог уже давным давно считают одним простым запросом (по нужным полям)
|
|||
33
Serginio1
29.10.13
✎
19:09
|
Запрос=Новый Запрос;
Запрос.Текст="ВЫБРАТЬ | Таблица.Номенклатура КАК Номенклатура, | Таблица.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры, | Таблица.Количество КАК Количество, | Таблица.ПродажаRUR КАК ПродажаRUR, | Таблица.ПродажаUSD КАК ПродажаUSD, | Таблица.НомерСтроки КАК НомерСтроки |ПОМЕСТИТЬ Таблица |ИЗ | &Тз КАК Таблица |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Таблица.Номенклатура КАК Номенклатура, | Таблица.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры, | акПродажиОстатки.ДокументОприходования КАК ДокументОприходования, | Таблица.Количество КАК КоличествоСписания, | Таблица.ПродажаRUR КАК ПродажаRUR, | Таблица.ПродажаUSD КАК ПродажаUSD, | акПродажиОстатки.СебеСтоимостьUSDОстаток КАК СебеСтоимостьUSD, | акПродажиОстатки.СебеСтоимостьRURОстаток КАК СебеСтоимостьRUR, | акПродажиОстатки.КоличествоОстаток КАК Количество, | акПродажиОстатки.ДокументОприходования.Контрагент КАК Поставщик, | акПродажиОстатки.ХарактеристикаНоменклатуры.Прайс КАК Прайс, | Таблица.НомерСтроки КАК НомерСтроки |ИЗ | Таблица КАК Таблица | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.акПродажи.Остатки( | , | (Номенклатура, ХарактеристикаНоменклатуры) В | (ВЫБРАТЬ | тз.Номенклатура, | тз.ХарактеристикаНоменклатуры | ИЗ | Таблица КАК тз)) КАК акПродажиОстатки | ПО Таблица.Номенклатура = акПродажиОстатки.Номенклатура | И Таблица.ХарактеристикаНоменклатуры = акПродажиОстатки.ХарактеристикаНоменклатуры | |УПОРЯДОЧИТЬ ПО | НомерСтроки"; Запрос.УстановитьПараметр("Тз",Тз); Рез=акСмешанный.глСгруппироватьТзПоПолям(Запрос.Выполнить().выгрузить(),"Номенклатура,ХарактеристикаНоменклатуры","Количество"); Отказ=ложь; ТзРезулт=акСмешанный.ПолучитьТзСписаний(рез,РегистрыНакопления.акПродажи,"КоличествоСписания","Количество","СебеСтоимостьUSD,СебеСтоимостьRUR",Отказ); |
|||
34
GANR
29.10.13
✎
19:16
|
(22) Полезная вещь во многих случаях.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |