Почему движения на 23:59:59 не попадают в виртуальную таблицу Остатки и как это исправить

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При получении остатков из регистров накопления или бухгалтерии разработчики нередко сталкиваются с ситуацией: документ проведен на последнюю секунду дня (например, 31.10.2017 23:59:59), в параметрах виртуальной таблицы передается КонецДня('31.10.2017'), но движения этого документа не учитываются в результатах запроса. Разберем причины такого поведения платформы 1С:Предприятие и рассмотрим правильные способы получения актуальных остатков.

Причина поведения платформы 1С

Проанализируем, как платформа обрабатывает параметр даты в виртуальных таблицах:

  1. Неявное поведение типа Дата в таблице Остатки: когда в параметр Период виртуальной таблицы передачи передается простое значение типа Дата, платформа 1С всегда неявно интерпретирует его как ВидГраницы.Исключая. Это означает, что срез остатков строится строго на начало указанной секунды (на отметку 0 миллисекунд этой секунды). Движения документов, записанных в эту же секунду, фактически оказываются за пределами среза.
  2. Разница между таблицами: в таблицах Обороты и ОстаткиИОбороты параметр КонецПериода обрабатывается интервально (включая указанную секунду целиком). Однако в таблице Остатки параметр является точечным срезом времени и по умолчанию исключает переданную дату.

Способ 1. Использование объекта Граница во встроенном языке (Рекомендуемый)

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

Посмотрим на пример установки параметра запроса в программном коде:


ГраницаПериода = Новый Граница(КонецДня(КонПериода), ВидГраницы.Включая);
Запрос.УстановитьПараметр("КонПериода", ГраницаПериода);

Рассмотрим текст запроса к регистру бухгалтерии:


ВЫБРАТЬ
    Хозрасчетный.Субконто1 КАК Субконто1,
    Хозрасчетный.Субконто2 КАК Субконто2,
    Хозрасчетный.КоличествоОстаток КАК КоличествоОстаток,
    Хозрасчетный.СуммаОстаток КАК СуммаОстаток
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(
        &КонПериода,
        Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Материалы))
    ) КАК Хозрасчетный

При таком подходе платформа сформирует срез с включением всех записей регистра, приходящихся на последнюю секунду указанного дня.

Способ 2. Настройка параметров в Системе компоновки данных (СКД)

Если отчет разрабатывается на СКД, создавать объект Граница в модуле программно необязательно. Настроить корректное включение границы можно непосредственно в схеме компоновки данных.

Разберем варианты настройки выражений на вкладке Параметры схемы компоновки данных:

  1. Если используется отдельный параметр даты: в колонке «Выражение» для параметра КонецПериода укажем: Новый Граница(КонецПериода(&КонецПериода, "День"), ВидГраницы.Включая)
  2. Если используется стандартный период: при использовании пользовательского выбора СтандартныйПериод в выражении параметра конца периода пропишем: Новый Граница(&Период.ДатаОкончания, ВидГраницы.Включая)
  3. С проверкой на незаполненную дату: чтобы избежать ошибок при формировании остатков на неограниченную дату, применим следующее выражение:
    
    ВЫБОР 
        КОГДА &КонецПериода = ДАТАВРЕМЯ(1, 1, 1) ИЛИ &КонецПериода ЕСТЬ NULL 
            ТОГДА ДАТАВРЕМЯ(1, 1, 1) 
        ИНАЧЕ Новый Граница(КонецПериода(&КонецПериода, "День"), ВидГраницы.Включая) 
    КОНЕЦ
    

Способ 3. Получение остатков на МоментВремени документа

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

Посмотрим на пример:


ГраницаДокумента = Новый Граница(ДокументСсылка.МоментВремени(), ВидГраницы.Включая);
Запрос.УстановитьПараметр("ПериодОстатков", ГраницаДокумента);

Это исключает проблемы при наличии нескольких документов, записанных в пределах одной секунды 23:59:59, так как МоментВремени учитывает не только дату и время, но и уникальную ссылку документа.

Ограничения и нежелательные методы

Выясним, почему некоторые альтернативные решения могут приводить к скрытым ошибкам:

  1. Смещение даты на 1 секунду вперед (КонецДня(Дата) + 1): перевод даты на 00:00:00 следующего дня приведет к тому, что в срез попадут документы ввода остатков или регламентные операции, проведенные на полночь следующего дня. Кроме того, если этот же параметр передается в заголовок отчета, пользователю будет отображаться некорректная дата.
  2. Сериализация объекта Граница: следует помнить, что объект Граница является специализированным типом данных платформы для запросов и виртуальных таблиц. Его нельзя напрямую сохранять в реквизитах базы данных или передавать через форматы JSON/XDTO без предварительного преобразования в дату или момент времени.
← На главную