Доброго дня!
Конфигурация комплексная 7.7, как оптимально организовать следующий алгоритм :
1. Получить все остатки на какую-то дату
2. Определить из каких приходов сформировался свободный остаток на каждую позицию из п.1, и узнать эти приходы.
---
Вопрос закрыт.

```1c
    ТекстЗапросаХранение = "
    |Период С КонДата По КонДата;
    |Фирма = Регистр.ПартииНаличие.Фирма;
    |Номенклатура = Регистр.ПартииНаличие.Номенклатура;
    |Поставщик = Регистр.ПартииНаличие.Номенклатура.Поставщик;
    |Количество = Регистр.ПартииНаличие.Количество;
    |СкладЗ = Регистр.ПартииНаличие.МОЛ;
    |ДатаПартииЗ = Регистр.ПартииНаличие.ДатаПартии;
    |ЦенаПартииЗ = Регистр.ПартииНаличие.СуммаРуб;
    |ПартияЗ = Регистр.ПартииНаличие.Партия;
    |Функция КоличествоКонОст = КонОст(Количество);
    |Группировка Номенклатура Без Групп;
    |Группировка ПартияЗ;
    |Условие (Фирма в ВбрФирма);
    |";
```
---
1. Получить все остатки как конечную дату Остаток типа "Дата"? Как это?

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

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

С бухитогами сложнее, там ОбратныйПорядок() не предусмотрен.
---
В общем случае делаете один запрос к регистру остатков или партий, что бы получить остатки по номенклатуре. Вторым запросом от Рождества Христова до интересующей даты берёте все движения по номенклатуре на остатках. Обходите результат запроса в обратном порядке, анализируя документы приходования товаров (это будет не только поступление), пока не наберёте нужного количества остатка. По каждой номенклатуре. Желательно еще решить для себя, что будете делать с документами возврата поставщику, возврата от покупателя, оприходование.
А перед всеми этими сложностями рекомендую посмотреть на метод расчёта себестоимости в учётной политике. Вдруг там стоит FIFO/LIFO. Тогда решение может быть гораздо проще.
---
Себестоимость по FIFO, по средней не было бы никаких партий.
Сделал запрос по регистру "ПартииНаличие", но там получается сводный остаток на конечную дату. По какому регистру гнать по документам ? И как запрос обойти в обратном порядке, можете на примере показать ?
---
Себестоимость по FIFO, по средней не было бы никаких партий
В таком случае всё довольно просто.

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

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

"Размазывать" можно примерно так:

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

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

    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
```

|
---
И как запрос обойти в обратном порядке, можете на примере показать ?

Группировка(<?>,)
Синтаксис:
Группировка(<Группировка>,<Направление>)
Назначение:
Получить следующее значение выборки Запроса
Возвращает: 1 - если получено следующее значение выборки запроса, 0 - иначе.
Параметры:
<Группировка> - выражение, содержащее номер или имя группировки.
<Направление> - необязательный параметр. Число: 1 - выборка значений группировки по возрастанию; -1 (минус единица) - выборка значений группировки по убыванию. Значение по умолчанию: 1.
---
Обходите результат запроса в обратном порядке, анализируя документы приходования товаров (это будет не только поступление), пока не наберёте нужного количества остатка. А я так понял задачу, что если в какой-то момент остаток выбранной номенклатуры был нулевым (продали всё), то дальше вглубь идти уже незачем - считаем, что "свободный остаток" сформирован более поздними документами. Которые при обратном порядке выборки уже обработаны.
---
А я так понял задачу, что если в какой-то момент остаток выбранной номенклатуры был нулевым (продали всё), то дальше вглубь идти уже незачем - считаем, что "свободный остаток" сформирован более поздними документами. Которые при обратном порядке выборки уже обработаны.
В общем и целом да. Такой метод понадобится, если запрос к регистру партий по приходным документам заказчика не устроит. "Красноты" много будет или что еще.
---
наверное я не совсем точно описал, есть некая дата, указанная на форме, на эту дату нужно сформировать остаток по каждой номенклатуре НО, не сводный а по документам прихода (ну т.е. партий).
---
Вопрос закрыт.

```1c
    ТекстЗапросаХранение = "
    |Период С КонДата По КонДата;
    |Фирма = Регистр.ПартииНаличие.Фирма;
    |Номенклатура = Регистр.ПартииНаличие.Номенклатура;
    |Поставщик = Регистр.ПартииНаличие.Номенклатура.Поставщик;
    |Количество = Регистр.ПартииНаличие.Количество;
    |СкладЗ = Регистр.ПартииНаличие.МОЛ;
    |ДатаПартииЗ = Регистр.ПартииНаличие.ДатаПартии;
    |ЦенаПартииЗ = Регистр.ПартииНаличие.СуммаРуб;
    |ПартияЗ = Регистр.ПартииНаличие.Партия;
    |Функция КоличествоКонОст = КонОст(Количество);
    |Группировка Номенклатура Без Групп;
    |Группировка ПартияЗ;
    |Условие (Фирма в ВбрФирма);
    |";
```