Ошибка получения остатков

16 июня 2013

Пример запроса

Рассмотрим следующий запрос:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|	СвободныеОстаткиОстатки.Склад,
|	СвободныеОстаткиОстатки.Номенклатура,
|	СвободныеОстаткиОстатки.КоличествоОстаток
|ИЗ
|	РегистрНакопления.СвободныеОстатки.Остатки(&ДатаОстатков, )
|				 КАК СвободныеОстаткиОстатки";

В нем используется виртуальная таблица "Остатки" регистра накопления "СвободныеОстатки". Запрос, соответственно, получает остатки номенклатуры по складам. В качестве параметров в запрос передается "ДатаОстатков", на которую и нужно получить необходимые остатки. Давайте рассмотрим пример значения параметра, который туда можно передать:

Вроде все правильно. Мы получим остатки на конец дня 16 июня 2013 года. Но здесь мы и получим ошибку, так как отчет в некоторых ситуациях будет выдавать некорректные остатки! Проанализируем причины.

Суть ошибки

Из-за технических особенностей платформы 1С:Предприятие 8 запрос к базе данных для виртуальной таблицы "Остатки" возвращает данные на переданную дату остатков за минусом одной секунды. Поясню. Например, остаток по номенклатуре "Мужские сапоги с натуральным мехом" на складе "Склад обуви" составляет 1355 пар обуви на дату 16.06.2013.

Введем этой же датой документ "Списание товаров" по этому же складу и номенклатуре. Спишем весь остаток.

Обратите внимание на дату документа. Логично, что после проведения документа наш запрос с прошлыми параметрами должен показать, что остатка теперь на складе нет. Однако мы получим результат, аналогичный предыдущему: 

В чем же дело?

Как правильно

Если мы в параметр запроса передадим дату на 1 секунду больше, то получим правильные результаты. Вот так изменится результат запроса, если мы получим остаток на дату 17.06.2013 00:00:00".  

Описанная особенность виртуальной таблицы остатков должна учитываться при разработке типовых решений.

Заключение

В заключение покажу еще один вариант передачи параметра в запрос к виртуальной таблице "Остатки". Один вариант мы уже рассматривали. Достаточно увеличить дату на одну секунду. Еще один вариант заключается в передаче границы периода в качестве параметра. Для нашего примера это будет выглядеть следующим образом:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|	СвободныеОстаткиОстатки.Склад,
|	СвободныеОстаткиОстатки.Номенклатура,
|	СвободныеОстаткиОстатки.КоличествоОстаток
|ИЗ
|	РегистрНакопления.СвободныеОстатки.Остатки(&ДатаОстатков, )
|				 КАК СвободныеОстаткиОстатки";
// Передаем границу периода в запрос
Запрос.УстановитьПараметр("ДатаОстатков", Новый Граница(ДатаОстатков, ВидГраницы.Включая));

Будьте внимательны при использовании виртуальной таблицы "Остатки".


comments powered by Disqus