Как в запросе получить Начальные и Конечные остатки на каждый день, месяц и другие периоды
Обычные формы;
Управляемые формы;
Запросы;
Всем известен тот факт, что если использовать в запросе только виртуальную таблицу регистра накопления Остатки и Обороты для получения остатков на каждый период, то этого будет недостаточно. Потому что запрос не отобразит записи на те периоды, в которых не было никаких движений.
Покажу вариант решения данной задачи, который я всегда использую. Для примера будем получать остатки товаров на каждый день. Для этого в запросе необходимо использовать таблицу, содержащую все дни из рассматриваемого периода. Сгенерировать эту таблицу можно разными способами, я просто создам таблицу значений и заполню ее строками с датами-днями из периода, например, возьмем март 2018 года.
&НаСервере
Функция Получить_ТЗ_Дни()
НачПериода = НачалоДня('20180301'); // 1 марта 2018
КонПериода = НачалоДня('20180331'); // 31 марта 2018
ТЗ_Дни = Новый ТаблицаЗначений;
ТЗ_Дни.Колонки.Добавить("День",Новый ОписаниеТипов("Дата"));
ДеньСчетчик = НачПериода;
Пока ДеньСчетчик <= КонПериода Цикл
НовСтрока = ТЗ_Дни.Добавить();
НовСтрока.День = ДеньСчетчик;
ДеньСчетчик = ДеньСчетчик + 24*3600;
КонецЦикла;
Возврат ТЗ_Дни;
КонецФункции
Теперь составляем правильный запрос с остатками товаров на каждый день (я буду использовать регистр накопления Товары на складах из конфигурации УТ 11.3):&НаСервере
Процедура ПолучитьОстаткиПоДням()
НачПериода = НачалоДня('20180301'); // 1 марта 2018
КонПериода = НачалоДня('20180331'); // 31 марта 2018
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЗ_Дни.День КАК День
|ПОМЕСТИТЬ ВТ_Дни
|ИЗ
| &ТЗ_Дни КАК ТЗ_Дни
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстаткиИОбороты.Склад КАК Склад,
| ВТ_Дни.День КАК ДатаДень,
| СУММА(ВЫБОР
| КОГДА ТоварыНаСкладахОстаткиИОбороты.Период = &НачПериода
| И ВТ_Дни.День = &НачПериода
| ТОГДА ТоварыНаСкладахОстаткиИОбороты.ВНаличииНачальныйОстаток
| КОГДА ТоварыНаСкладахОстаткиИОбороты.Период = &НачПериода
| ТОГДА ТоварыНаСкладахОстаткиИОбороты.ВНаличииНачальныйОстаток + ТоварыНаСкладахОстаткиИОбороты.ВНаличииОборот
| ИНАЧЕ ВЫБОР
| КОГДА ТоварыНаСкладахОстаткиИОбороты.Период < ВТ_Дни.День
| ТОГДА ТоварыНаСкладахОстаткиИОбороты.ВНаличииОборот
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ) КАК НачОстатокДень,
| СУММА(ВЫБОР
| КОГДА ТоварыНаСкладахОстаткиИОбороты.Период = &НачПериода
| ТОГДА ТоварыНаСкладахОстаткиИОбороты.ВНаличииКонечныйОстаток
| КОГДА ТоварыНаСкладахОстаткиИОбороты.Период <= ВТ_Дни.День
| ТОГДА ТоварыНаСкладахОстаткиИОбороты.ВНаличииОборот
| ИНАЧЕ 0
| КОНЕЦ) КАК КонОстатокДень
|ИЗ
| ВТ_Дни КАК ВТ_Дни
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачПериода, &КонПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты
| ПО ВТ_Дни.День >= ТоварыНаСкладахОстаткиИОбороты.Период
|
|СГРУППИРОВАТЬ ПО
| ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
| ТоварыНаСкладахОстаткиИОбороты.Склад,
| ВТ_Дни.День";
Запрос.УстановитьПараметр("НачПериода",НачПериода);
Запрос.УстановитьПараметр("КонПериода",КонецДня(КонПериода));
ТЗ_Дни = Получить_ТЗ_Дни();
Запрос.УстановитьПараметр("ТЗ_Дни",ТЗ_Дни);
ТЗ_ОстаткиТоваров = Запрос.Выполнить().Выгрузить();
КонецПроцедуры