Остатки на каждый день в запросе

Столкнулся на практике с задачей, когда нужно было получить остатки на каждый день для предоставления в другую систему.

В запросе мог получить только остатки на начало и конец периода, плюс на те дни, когда были движения.

Работал на тестовой базе, проверял выборочно по одному товару за период 01.03.2017 по 04.04.2017.

Проверил остатки запросом:

ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ТоварыНаСкладахОстатки.Склад КАК Склад,
	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
	ТоварыНаСкладахОстатки.Период КАК Период,
	ТоварыНаСкладахОстатки.ВНаличииКонечныйОстаток КАК ВНаличииКонечныйОстаток,
	ТоварыНаСкладахОстатки.ВНаличииНачальныйОстаток КАК ВНаличииНачальныйОстаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&Дата1, &Дата2, День, ДвиженияИГраницыПериода, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки

УПОРЯДОЧИТЬ ПО
	Период

Получил данные:

И в отчете 1С по движениям товаров:

В запросе в отчете получил данные с остатками только на начало, конец и в даты движений, в остальные даты остатки NULL:

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

Запрос использует соединение с таблицей всех дней, всех выбранных товаров и всех выбранных складов:

/////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ТоварыНаСкладахОстатки.Склад КАК Склад,
	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
	ТоварыНаСкладахОстатки.Период КАК Период,
	ТоварыНаСкладахОстатки.ВНаличииКонечныйОстаток КАК ВНаличииКонечныйОстаток,
	ТоварыНаСкладахОстатки.ВНаличииНачальныйОстаток КАК ВНаличииНачальныйОстаток
ПОМЕСТИТЬ вт_ОстаткиДень
ИЗ
	РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(
			&ГраницаИнтервалаНачалоДня,
			&ГраницаИнтервалаКонецДня,
			День,
			ДвиженияИГраницыПериода,
			Номенклатура В
				(ВЫБРАТЬ
					вт_Номенклатура.Номенклатура
				ИЗ
					вт_Номенклатура)) КАК ТоварыНаСкладахОстатки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ДНИ.Период КАК Период,
	Н.Номенклатура КАК Номенклатура,
	С.Склад КАК Склад,
	СУММА(вт_ОстаткиДень.ВНаличииНачальныйОстаток) КАК СвободныйОстатокначалоДня,
	СУММА(вт_ОстаткиДень.ВНаличииКонечныйОстаток) КАК СвободныйОстатокКонецДня
ИЗ
	Дни КАК ДНИ
		ПОЛНОЕ СОЕДИНЕНИЕ вт_Номенклатура КАК Н
		ПО (ИСТИНА)
		ПОЛНОЕ СОЕДИНЕНИЕ вт_Склады КАК С
		ПО (ИСТИНА)
		ЛЕВОЕ СОЕДИНЕНИЕ вт_ОстаткиДень КАК вт_ОстаткиДень
		ПО (НАЧАЛОПЕРИОДА(ДНИ.Период, ДЕНЬ) = НАЧАЛОПЕРИОДА(вт_ОстаткиДень.Период, ДЕНЬ))
			И (вт_ОстаткиДень.Номенклатура = Н.Номенклатура)
			И (вт_ОстаткиДень.Склад = С.Склад)

СГРУППИРОВАТЬ ПО
	ДНИ.Период,
	С.Склад,
	Н.Номенклатура

УПОРЯДОЧИТЬ ПО
	С.Склад,
	Н.Номенклатура,
	ДНИ.Период

Код по обработке таблицы значений запроса:

	//Корректируем остатки за те дни, где их нет
	Инд1 = 1;
	Пока Инд1 < лТЗнДанные.Количество() Цикл //До предпоследнего
		Строка1 = лТЗнДанные[Инд1 - 1];
		ОстатокСлева = 0;
		//Ищем все остатки по товар+склад
		Для Инд2 = Инд1 По лТЗнДанные.Количество() Цикл
			Строка2 = лТЗнДанные[Инд2 - 1];
			Если Строка2.Номенклатура <> Строка1.Номенклатура ИЛИ Строка2.Склад <> Строка1.Склад 
				Тогда
				Инд1 = Инд2;
				Прервать;                
			КонецЕсли;                   
			
			//Находимся внутри       
			Если Строка2.СвободныйОстатокКонецДня = NULL Тогда    
				//На случай если остатков не будет на дату
				Строка2.СвободныйОстатокНачалоДня = ОстатокСлева; 
				Строка2.СвободныйОстатокКонецДня = ОстатокСлева; 
			Иначе                                 
				ОстатокСлева = Строка2.СвободныйОстатокКонецДня;
			КонецЕсли;

			//Выходим из цикла, обработав последнюю строку
			Если Инд2 = лТЗнДанные.Количество() Тогда
				Инд1 = Инд2;
				Прервать;
			КонецЕсли;

		КонецЦикла;
	КонецЦикла;

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *