Оптимальный алгоритм выбора остатков (7.7)

1. Александр (alex_gus) 14.11.17 18:22 Сейчас в теме
Доброго дня!
Конфигурация комплексная 7.7, как оптимально организовать следующий алгоритм :
1. Получить все остатки на какую-то дату
2. Определить из каких приходов сформировался свободный остаток на каждую позицию из п.1, и узнать эти приходы.
Найденные решения
10. Александр (alex_gus) 1 16.11.17 11:05 Сейчас в теме
Вопрос закрыт.
	ТекстЗапросаХранение = "
	|Период С КонДата По КонДата; 	
	|Фирма					  = Регистр.ПартииНаличие.Фирма;             
	|Номенклатура			  = Регистр.ПартииНаличие.Номенклатура;
	|Поставщик  			  = Регистр.ПартииНаличие.Номенклатура.Поставщик;
	|Количество 		      = Регистр.ПартииНаличие.Количество;
	|СкладЗ                   = Регистр.ПартииНаличие.МОЛ;
	|ДатаПартииЗ              = Регистр.ПартииНаличие.ДатаПартии;
	|ЦенаПартииЗ              = Регистр.ПартииНаличие.СуммаРуб;
	|ПартияЗ                  = Регистр.ПартииНаличие.Партия;
	|Функция КоличествоКонОст = КонОст(Количество);
	|Группировка Номенклатура Без Групп;
	|Группировка ПартияЗ;
	|Условие (Фирма в ВбрФирма);	
	|";
Показать
Остальные ответы
2. I Am (user856012) 14.11.17 18:57 Сейчас в теме
(1)
1. Получить все остатки как конечную дату
Остаток типа "Дата"? Как это?

Если подразумевался остаток на конечную дату, то запросом к регистру остатков.

Или к бухитогам - смотря по тому, какой учет вы подразумеваете, бухгалтерский или оперативный.
2. Определить из каких приходов сформировался свободный остаток на каждую позицию из п.1, и узнать эти приходы.
Опять-таки, если по оперучету, то выбираем движения по регистру, причем в обратном порядке, документы расхода пропускаем, документы прихода - запоминаем (например, в списке значений), но при этом контролируем остаток после каждого из них. Как только остаток стал равен 0 - прерываем обработку.

С бухитогами сложнее, там ОбратныйПорядок() не предусмотрен.
3. Владислав Чинючин (vcv) 84 14.11.17 20:18 Сейчас в теме
В общем случае делаете один запрос к регистру остатков или партий, что бы получить остатки по номенклатуре. Вторым запросом от Рождества Христова до интересующей даты берёте все движения по номенклатуре на остатках. Обходите результат запроса в обратном порядке, анализируя документы приходования товаров (это будет не только поступление), пока не наберёте нужного количества остатка. По каждой номенклатуре. Желательно еще решить для себя, что будете делать с документами возврата поставщику, возврата от покупателя, оприходование.
А перед всеми этими сложностями рекомендую посмотреть на метод расчёта себестоимости в учётной политике. Вдруг там стоит FIFO/LIFO. Тогда решение может быть гораздо проще.
4. Александр (alex_gus) 1 14.11.17 21:13 Сейчас в теме
(3)Себестоимость по FIFO, по средней не было бы никаких партий.
Сделал запрос по регистру "ПартииНаличие", но там получается сводный остаток на конечную дату. По какому регистру гнать по документам ? И как запрос обойти в обратном порядке, можете на примере показать ?
6. Владислав Чинючин (vcv) 84 15.11.17 05:22 Сейчас в теме
(4)
Себестоимость по FIFO, по средней не было бы никаких партий

В таком случае всё довольно просто.
Номенклатура = Регистр.ПартииНаличие.Номенклатура;
ПриходныйДокумент = Регистр.ПартииНаличие.Партия.ПриходныйДокумент;
Количество = Регистр.ПартииНаличие.Количество;
Функция КоличествоКонОст = КонОст(Количество);
Группировка Номенклатура без групп;
Группировка ПриходныйДокумент;

Но есть два но. Во-первых, очень часто встречается бардак в учёте партий. Пересорт разновсяческий, красные остатки. Это испортит картину. Во-вторых, запрос даст фактический остаток, а вы сказали "свободный остаток на каждую позицию". Это значит нужно вычесть из остатков резервы, которые не детализируются по партиям. Значит всё равно нужно обходить результат запроса и "размазывать" количество резерва на фактический остаток.

"Размазывать" можно примерно так:
ТекстЗапроса = "Номенклатура = Регистр.РезервыТМЦ.Номенклатура;
|Количество = Регистр.РезервыТМЦ.Количество;
|Функция КоличествоКонОст = КонОст(Количество);
|Группировка Номенклатура без групп;";
Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) <> 1 Тогда
  Возврат;
КонецЕсли;
ТаблицаРезервов = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТаблицаРезервов,0,0);
ТекстЗапроса = "Номенклатура = Регистр.ПартииНаличие.Номенклатура;
|ПриходныйДокумент = Регистр.ПартииНаличие.Партия.ПриходныйДокумент;
|Количество = Регистр.ПартииНаличие.Количество;
|Функция КоличествоКонОст = КонОст(Количество);
|Группировка Номенклатура без групп;
|Группировка ПриходныйДокумент;";
Если Запрос.Выполнить(ТекстЗапроса) <> 1 Тогда
  Возврат;
КонецЕсли;
Пока Запрос.Группировка(1) = 1 Цикл
  Строчка = 0;
  Если ТаблицаРезервов.НайтиЗначение(Запрос.Номенклатура,Строчка,"Номенклатура") = 1 Тогда
    КоличествоРезерва = ТаблицаРезервов.получитьЗначение(Строчка,"КоличествоКонОст");
  Иначе
    КоличествоРезерва = 0;
  КонецЕсли;
  Пока Запрос.Группировка(2) = 1 Цикл
    Если Запрос.КоличествоКонОст > 0 Тогда
      СвободныйОстатокПоДокументу = Запрос.КоличествоКонОст - Макс(КоличествоРезерва, 0);
      КоличествоРезерва = Макс(КоличествоРезерва - СвободныйОстатокПоДокументу, 0);
      Если СвободныйОстатокПоДокументу > 0 Тогда

          Вот тут делаем что надо с ненулевым свободным остатком по документу. Выводим в отчёт, например.

      КонецЕсли;
  КонецЦикла;
КонецЦикла;
Показать

|
7. Владислав Чинючин (vcv) 84 15.11.17 05:24 Сейчас в теме
(4)
И как запрос обойти в обратном порядке, можете на примере показать ?


Группировка(<?>,)
Синтаксис:
Группировка(<Группировка>,<Направление>)
Назначение:
Получить следующее значение выборки Запроса
Возвращает: 1 - если получено следующее значение выборки запроса, 0 - иначе.
Параметры:
<Группировка> - выражение, содержащее номер или имя группировки.
<Направление> - необязательный параметр. Число: 1 - выборка значений группировки по возрастанию; -1 (минус единица) - выборка значений группировки по убыванию. Значение по умолчанию: 1.
5. I Am (user856012) 14.11.17 21:32 Сейчас в теме
(3)
Обходите результат запроса в обратном порядке, анализируя документы приходования товаров (это будет не только поступление), пока не наберёте нужного количества остатка.
А я так понял задачу, что если в какой-то момент остаток выбранной номенклатуры был нулевым (продали всё), то дальше вглубь идти уже незачем - считаем, что "свободный остаток" сформирован более поздними документами. Которые при обратном порядке выборки уже обработаны.
8. Владислав Чинючин (vcv) 84 15.11.17 05:32 Сейчас в теме
(5)
А я так понял задачу, что если в какой-то момент остаток выбранной номенклатуры был нулевым (продали всё), то дальше вглубь идти уже незачем - считаем, что "свободный остаток" сформирован более поздними документами. Которые при обратном порядке выборки уже обработаны.

В общем и целом да. Такой метод понадобится, если запрос к регистру партий по приходным документам заказчика не устроит. "Красноты" много будет или что еще.
9. Александр (alex_gus) 1 16.11.17 10:10 Сейчас в теме
(8) наверное я не совсем точно описал, есть некая дата, указанная на форме, на эту дату нужно сформировать остаток по каждой номенклатуре НО, не сводный а по документам прихода (ну т.е. партий).
10. Александр (alex_gus) 1 16.11.17 11:05 Сейчас в теме
Вопрос закрыт.
	ТекстЗапросаХранение = "
	|Период С КонДата По КонДата; 	
	|Фирма					  = Регистр.ПартииНаличие.Фирма;             
	|Номенклатура			  = Регистр.ПартииНаличие.Номенклатура;
	|Поставщик  			  = Регистр.ПартииНаличие.Номенклатура.Поставщик;
	|Количество 		      = Регистр.ПартииНаличие.Количество;
	|СкладЗ                   = Регистр.ПартииНаличие.МОЛ;
	|ДатаПартииЗ              = Регистр.ПартииНаличие.ДатаПартии;
	|ЦенаПартииЗ              = Регистр.ПартииНаличие.СуммаРуб;
	|ПартияЗ                  = Регистр.ПартииНаличие.Партия;
	|Функция КоличествоКонОст = КонОст(Количество);
	|Группировка Номенклатура Без Групп;
	|Группировка ПартияЗ;
	|Условие (Фирма в ВбрФирма);	
	|";
Показать
Оставьте свое сообщение