Почему не сходятся результаты запроса по счету и оборотно-сальдовая ведомость (ОСВ) в 1С

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет
← На главную

При разработке внешних отчетов или обработок программисты часто сталкиваются с ситуацией, когда данные, полученные «простым» запросом к виртуальной таблице остатков, не совпадают с цифрами в стандартной Оборотно-сальдовой ведомости (ОСВ). Особенно остро эта проблема проявляется в конце отчетного периода, например, на 31 июля в 23:59:59. Проанализируем, почему это происходит и как добиться идеального соответствия данных в 1С:УПП 1.3 и других конфигурациях.

Причина расхождения: Особенности оси времени в 1С

Разберем ситуацию: в ОСВ на конец дня числится 10 единиц товара, а запрос показывает 12. Выясняется, что в последнюю секунду дня (23:59:59) был оформлен расход на 2 единицы. Посмотрим на техническую сторону вопроса. В платформе «1С:Предприятие 8» дата — это не просто точка, а момент на оси времени. Если мы передаем в запрос обычную дату 31.07.2019 23:59:59, система по умолчанию интерпретирует ее как начало этой секунды. Следовательно, все документы, записанные в эту же самую секунду, не попадают в расчет остатков.

Стандартные отчеты, такие как ОСВ, используют специальные механизмы для включения движений «граничной» секунды. Чтобы наш запрос возвращал идентичный результат, нам необходимо использовать объект Граница.

Решение 1: Использование объекта Граница

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

Проанализируем правильный код инициализации границы:


ДатаКонцаПериода = КонецДня(ДатаОтчета); 
// Создаем объект Граница, включающий саму секунду
ПараметрыГраницы = Новый Массив;
ПараметрыГраницы.Добавить(ДатаКонцаПериода);
ПараметрыГраницы.Добавить(ВидГраницы.Включая);

КонечнаяГраница = Новый(Тип("Граница"), ПараметрыГраницы);

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

Запрос.УстановитьПараметр("Период", КонечнаяГраница);
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.ТоварыНаСкладах);

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

Решение 2: Использование Момента Времени

Если ваша задача — получить остатки не просто на конец дня, а на конкретный документ (чтобы увидеть остатки строго после проведения расходной накладной), используйте МоментВремени. Этот объект уникален для каждой транзакции и гарантирует правильную последовательность записей, даже если в одну секунду введено 100 документов.

Рассмотрим пример кода:


// Получаем момент времени конкретного документа
ТекМоментВремени = СсылкаНаДокумент.МоментВремени();

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

Запрос.УстановитьПараметр("Момент", ТекМоментВремени);

Оптимизация параметров виртуальной таблицы

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

Рассмотрим правильный подход — использование параметров виртуальной таблицы. Это позволяет SQL-серверу сразу отобрать нужные данные, используя индексы таблиц итогов.

Структура параметров виртуальной таблицы Остатки выглядит так:

  1. Период: Дата, Граница или МоментВремени.
  2. Условие счета: Фильтр по счету (обязательно передавайте его здесь).
  3. Виды субконто: Массив видов субконто, если нужна определенная иерархия.
  4. Условие: Массив условий по значениям субконто (например, конкретный склад или товар).

Пример оптимизированного запроса для 1С:УПП 1.3:


// Подготовим массив субконто для фильтрации
МассивСубконто = Новый Массив;
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады);

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

Запрос.УстановитьПараметр("ВидыСубконто", МассивСубконто);
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);

Дополнительные факторы влияния на корректность ОСВ

Если даже после применения Границы данные все равно «разлетаются», проанализируем следующие ситуации:

  1. Актуальность итогов: В 1С существует механизм хранения рассчитанных остатков. Если произошел сбой, итоги могут стать некорректными. Попробуйте выполнить пересчет через «Операции» — «Управление итогами».
  2. Развернутое сальдо: Проверьте настройки ОСВ. Если в отчете стоит галочка «Развернутое сальдо», а ваш запрос получает обычный остаток, итоговые строки могут не совпасть из-за наличия дебетовых и кредитовых остатков на разных субконто одного счета.
  3. Учет по организациям: В запросе всегда стоит добавлять фильтр по организации в параметры виртуальной таблицы, так как ОСВ чаще всего формируется в разрезе конкретного юрлица.

Подведем итог: для получения данных, идентичных Оборотно-сальдовой ведомости, всегда используйте объект Граница(КонецДня(Дата), ВидГраницы.Включая) и передавайте фильтры (Счет, Субконто, Организация) непосредственно в параметры виртуальной таблицы, а не в секцию ГДЕ. Это обеспечит и точность, и высокую скорость работы вашего отчета.

← На главную