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

В своей практике пришел к моменту, когда назрел вопрос о получении таблицы остатков товара из регистра накопления, в котором содержится информация на КАЖДЫЙ день. Но как известно виртуальная таблица «Остатки» дает данные только о том периоде, когда они изменились. Ситуацию нужно было решить. На сегодняшний день через поиск я нашел несколько способов получения нужной таблице, но универсального решения не было. Вот некоторые из них:

  1. С помощью СКД
  2. С помощью вспомагательных регистров

Нужного запроса не нашел — или плохо искал, или нет. Поэтому задался поиском ответа на этот вопрос. Проблема разделилась на 2 части:

  1. Нужно построить таблицу дат (ибо «Остатки» не дают информации о каждом дне) с привязкой к нужному нам измерению регистра — в данном случае Номенклатура.
  2. Привязать к таблице дат таблицу с остатками.
  3. Ну и не забываем, что это надо реализовать одним запросом.

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

А вот с решения второй подзадачи оказались небольшие проблемы. Для выведения правильной информации нужно было построить следующую таблицу остатков
Начало периода | Конец периода | Номенклатура | Остаток
Но и эту задачу удалось решить. Ну а дальше только дело техники — связать две таблички и вывести нужный результат

Текст запроса

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ ТЗНоменклатур
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
ГДЕ
	(НЕ СпрНоменклатура.ПометкаУдаления)
	И (НЕ СпрНоменклатура.ЭтоГруппа)
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) КАК Дата,
	ТЗНоменклатур.Номенклатура
ПОМЕСТИТЬ ТаблицаДата
ИЗ
	(ВЫБРАТЬ
		6 * (t1.a - 1) + t2.b - 1 КАК n
	ИЗ
		(ВЫБРАТЬ
			1 КАК a
 
		ОБЪЕДИНИТЬ
 
		ВЫБРАТЬ
			2
 
		ОБЪЕДИНИТЬ
 
		ВЫБРАТЬ
			3
 
		ОБЪЕДИНИТЬ
 
		ВЫБРАТЬ
			4
 
		ОБЪЕДИНИТЬ
 
		ВЫБРАТЬ
			5
 
		ОБЪЕДИНИТЬ
 
		ВЫБРАТЬ
			6) КАК t1
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				1 КАК b
 
			ОБЪЕДИНИТЬ
 
			ВЫБРАТЬ
				2
 
			ОБЪЕДИНИТЬ
 
			ВЫБРАТЬ
				3
 
			ОБЪЕДИНИТЬ
 
			ВЫБРАТЬ
				4
 
			ОБЪЕДИНИТЬ
 
			ВЫБРАТЬ
				5
 
			ОБЪЕДИНИТЬ
 
			ВЫБРАТЬ
				6) КАК t2
			ПО (ИСТИНА)) КАК t,
	ТЗНоменклатур КАК ТЗНоменклатур
ГДЕ
	ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) <= &КонецПериода
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВложенныйЗапрос.Номенклатура,
	ВложенныйЗапрос.НачалоПериода КАК НачалоПериода,
	МАКСИМУМ(ВложенныйЗапрос.Количество) КАК Количество
ПОМЕСТИТЬ Остатки
ИЗ
	(ВЫБРАТЬ
		&НачалоПериода КАК НачалоПериода,
		ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
		ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество
	ИЗ
		РегистрНакопления.ТоварыНаСкладах.Остатки(&НачалоПериода, Склад = &Склад) КАК ТоварыНаСкладахОстатки
 
	ОБЪЕДИНИТЬ ВСЕ
 
	ВЫБРАТЬ
		НАЧАЛОПЕРИОДА(ТоварыНаСкладахОстаткиИОбороты.Период, ДЕНЬ),
		ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
		ТоварыНаСкладахОстаткиИОбороты.КоличествоНачальныйОстаток
	ИЗ
		РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , Склад = &Склад) КАК ТоварыНаСкладахОстаткиИОбороты) КАК ВложенныйЗапрос
 
СГРУППИРОВАТЬ ПО
	ВложенныйЗапрос.НачалоПериода,
	ВложенныйЗапрос.Номенклатура
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Остатки.НачалоПериода,
	МИНИМУМ(ДОБАВИТЬКДАТЕ(ЕСТЬNULL(ОстаткиКонец.НачалоПериода, ДОБАВИТЬКДАТЕ(&КонецПериода, СЕКУНДА, 1)), СЕКУНДА, -1)) КАК КонецПериода,
	Остатки.Номенклатура,
	Остатки.Количество
ПОМЕСТИТЬ ОстаткиПериодами
ИЗ
	Остатки КАК Остатки
		ЛЕВОЕ СОЕДИНЕНИЕ Остатки КАК ОстаткиКонец
		ПО Остатки.Номенклатура = ОстаткиКонец.Номенклатура
			И Остатки.НачалоПериода < ОстаткиКонец.НачалоПериода
 
СГРУППИРОВАТЬ ПО
	Остатки.НачалоПериода,
	Остатки.Номенклатура,
	Остатки.Количество
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТаблицаДата.Дата КАК Дата,
	ТаблицаДата.Номенклатура КАК Номенклатура,
	ЕСТЬNULL(ОстаткиПериодами.Количество, 0) КАК Количество
ИЗ
	ТаблицаДата КАК ТаблицаДата
		ЛЕВОЕ СОЕДИНЕНИЕ ОстаткиПериодами КАК ОстаткиПериодами
		ПО (ТаблицаДата.Дата МЕЖДУ ОстаткиПериодами.НачалоПериода И ОстаткиПериодами.КонецПериода)
			И ТаблицаДата.Номенклатура = ОстаткиПериодами.Номенклатура
 
УПОРЯДОЧИТЬ ПО
	Дата
ИТОГИ ПО
	Номенклатура