База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как исправить ошибку в запросе 1С при формировании соответствия даты к периоду? › Ответ в теме: Как исправить ошибку в запросе 1С при формировании соответствия даты к периоду?
В запросе основная ошибка находится в формировании ВТ_СоответствиеДатыПериоду.
Сейчас соединение выполняется только по условию:
|
1 |
|ПО ВТ_ОстаткиИОбороты.Период <= ВТ_ДатыНаКаждыйДень.Дата |
При этом отсутствует связь по товару. Поэтому для каждого дня выбираются периоды всех товаров, а МАКСИМУМ(Период) может быть взят от другого товара. В результате остатки могут подставляться не на тот товар.
Кроме того, если в регистре есть измерение Склад, текущий запрос может дублировать остатки по каждому складу, поскольку группировки по товару и периоду нет.
Исправленный вариант:
|
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 |
|ВЫБРАТЬ | ДатыНаКаждыйДень.Дата КАК Дата |ПОМЕСТИТЬ ВТ_ДатыНаКаждыйДень |ИЗ | &ДатыНаКаждыйДень КАК ДатыНаКаждыйДень |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Товары.Ссылка КАК Товар, | ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.Период, | &НачалоПериода | ) КАК Период, | СУММА(ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.КоличествоНачальныйОстаток, | 0 | )) КАК КоличествоНачальныйОстаток, | СУММА(ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.КоличествоКонечныйОстаток, | 0 | )) КАК КоличествоКонечныйОстаток, | СУММА(ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.КоличествоОборот, | 0 | )) КАК КоличествоОборот, | СУММА(ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.КоличествоПриход, | 0 | )) КАК КоличествоПриход, | СУММА(ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.КоличествоРасход, | 0 | )) КАК КоличествоРасход |ПОМЕСТИТЬ ВТ_ОстаткиИОбороты |ИЗ | Справочник.Номенклатура КАК Товары | ЛЕВОЕ СОЕДИНЕНИЕ | РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты( | &НачалоПериода, | &КонецПериода, | День, | ДвиженияИГраницыПериода, | ) КАК ОстаткиТоваровОстаткиИОбороты | ПО Товары.Ссылка = ОстаткиТоваровОстаткиИОбороты.Номенклатура |ГДЕ | НЕ Товары.ЭтоГруппа | |СГРУППИРОВАТЬ ПО | Товары.Ссылка, | ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.Период, | &НачалоПериода | ) | |ИНДЕКСИРОВАТЬ ПО | Товар, | Период |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВТ_ДатыНаКаждыйДень.Дата КАК День, | ВТ_ОстаткиИОбороты.Товар КАК Товар, | МАКСИМУМ(ВТ_ОстаткиИОбороты.Период) КАК ПериодОстатковИОборотов |ПОМЕСТИТЬ ВТ_СоответствиеДатыПериоду |ИЗ | ВТ_ДатыНаКаждыйДень КАК ВТ_ДатыНаКаждыйДень | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ОстаткиИОбороты КАК ВТ_ОстаткиИОбороты | ПО ВТ_ОстаткиИОбороты.Период <= ВТ_ДатыНаКаждыйДень.Дата | |СГРУППИРОВАТЬ ПО | ВТ_ДатыНаКаждыйДень.Дата, | ВТ_ОстаткиИОбороты.Товар | |ИНДЕКСИРОВАТЬ ПО | Товар, | День, | ПериодОстатковИОборотов |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВТ_СоответствиеДатыПериоду.День КАК День, | ВТ_ОстаткиИОбороты.Период КАК Период, | ВТ_СоответствиеДатыПериоду.Товар КАК Товар, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоНачальныйОстаток | ИНАЧЕ ВТ_ОстаткиИОбороты.КоличествоКонечныйОстаток | КОНЕЦ КАК НачальныйОстаток, | | ВТ_ОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоОборот | ИНАЧЕ 0 | КОНЕЦ КАК Оборот, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоПриход | ИНАЧЕ 0 | КОНЕЦ КАК Приход, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоРасход | ИНАЧЕ 0 | КОНЕЦ КАК Расход |ИЗ | ВТ_СоответствиеДатыПериоду КАК ВТ_СоответствиеДатыПериоду | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ОстаткиИОбороты КАК ВТ_ОстаткиИОбороты | ПО ВТ_СоответствиеДатыПериоду.Товар = | ВТ_ОстаткиИОбороты.Товар | И ВТ_СоответствиеДатыПериоду.ПериодОстатковИОборотов = | ВТ_ОстаткиИОборОТЫ.Период | |УПОРЯДОЧИТЬ ПО | Товар.Наименование, | День |
В последнем соединении в приведенном тексте допущена опечатка в имени алиаса. Должно быть именно:
|
1 2 3 4 |
| ПО ВТ_СоответствиеДатыПериоду.Товар = | ВТ_ОстаткиИОбороты.Товар | И ВТ_СоответствиеДатыПериоду.ПериодОстатковИОборотов = | ВТ_ОстаткиИОбороты.Период |
То есть полный последний блок нужно использовать так:
|
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 |
|ВЫБРАТЬ | ВТ_СоответствиеДатыПериоду.День КАК День, | ВТ_ОстаткиИОбороты.Период КАК Период, | ВТ_СоответствиеДатыПериоду.Товар КАК Товар, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоНачальныйОстаток | ИНАЧЕ ВТ_ОстаткиИОбороты.КоличествоКонечныйОстаток | КОНЕЦ КАК НачальныйОстаток, | | ВТ_ОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоОборот | ИНАЧЕ 0 | КОНЕЦ КАК Оборот, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоПриход | ИНАЧЕ 0 | КОНЕЦ КАК Приход, | | ВЫБОР | КОГДА ВТ_СоответствиеДатыПериоду.День = | ВТ_ОстаткиИОбороты.Период | ТОГДА ВТ_ОстаткиИОбороты.КоличествоРасход | ИНАЧЕ 0 | КОНЕЦ КАК Расход |ИЗ | ВТ_СоответствиеДатыПериоду КАК ВТ_СоответствиеДатыПериоду | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ОстаткиИОбороты КАК ВТ_ОстаткиИОбороты | ПО ВТ_СоответствиеДатыПериоду.Товар = | ВТ_ОстаткиИОбороты.Товар | И ВТ_СоответствиеДатыПериоду.ПериодОстатковИОборотов = | ВТ_ОстаткиИОбороты.Период | |УПОРЯДОЧИТЬ ПО | Товар.Наименование, | День |
Но есть еще один важный нюанс: ОстаткиИОбороты с периодичностью День может возвращать несколько строк на один товар и день, например по складам, сериям, характеристикам или организациям. Поэтому перед использованием данных нужно проверить измерения регистра.
Если отчет строится по всем складам, агрегация по товару и периоду, приведенная выше, правильна.
Если отчет строится по конкретному складу, склад лучше передать параметром виртуальной таблицы:
|
1 2 3 4 5 6 7 |
|РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты( | &НачалоПериода, | &КонецПериода, | День, | ДвиженияИГраницыПериода, | Склад = &Склад |) КАК ОстаткиТоваровОстаткиИОбороты |
Если нужно учитывать также характеристики и серии, их нужно добавить:
|
1 2 3 |
|Товары.Ссылка КАК Товар, |ОстаткиТоваровОстаткиИОбороты.Характеристика КАК Характеристика, |ОстаткиТоваровОстаткиИОбороты.Серия КАК Серия, |
и включить их:
|
1 2 3 4 5 6 7 8 |
|В СГРУППИРОВАТЬ ПО | Товары.Ссылка, | ОстаткиТоваровОстаткиИОбороты.Характеристика, | ОстаткиТоваровОстаткиИОбороты.Серия, | ЕСТЬNULL( | ОстаткиТоваровОстаткиИОбороты.Период, | &НачалоПериода | ) |
Также даты в параметре &ДатыНаКаждыйДень и периоды регистра должны быть приведены к одному времени, обычно к началу дня. Иначе сравнение:
|
1 |
|ВТ_ОстаткиИОбороты.Период <= ВТ_ДатыНаКаждыйДень.Дата |
может работать неправильно, если дата имеет время 00:00:00, а период движения содержит время документа.