Как в отчете 1С:Бухгалтерия 3.0 вывести остатки товаров на конкретное время?

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

При доработке типовых отчетов в конфигурации «1С:Бухгалтерия предприятие 3.0» (БП 3.0) программисты часто сталкиваются с тем, что система игнорирует указанное время в параметрах и принудительно выводит остатки на конец дня. Это происходит из-за глубокой интеграции механизмов бухгалтерского учета, где итоги традиционно рассматриваются в разрезе дней. Однако для оперативного учета часто требуется знать остаток, например, на 10:00:00 утра. Разберем по шагам, почему так происходит и как заставить отчет учитывать время.

Анализируем причину «округления» времени

Когда мы передаем дату в параметр запроса виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Остатки, система может вести себя по-разному в зависимости от того, как настроена Схема компоновки данных (СКД). Проанализируем основные факторы, влияющие на результат:

  1. Выражения параметров в СКД: В типовых отчетах в колонке «Выражение» параметров &НачалоПериода или &КонецПериода часто прописан код на языке выражений СКД, например: КонецПериода(&Период, "День"). Это выражение выполняется непосредственно перед выполнением запроса, перезаписывая любое время, которое вы передали из формы.
  2. Тип реквизита на форме: Если на форме отчета используется стандартный реквизит типа СтандартныйПериод, платформа автоматически устанавливает время даты окончания на 23:59:59.
  3. Подсистема «Бухгалтерские отчеты»: В БП 3.0 отчеты строятся через универсальные механизмы общих модулей. Функция ПодготовитьПараметрыОтчетаНаСервере готовит структуру параметров, которая позже может быть «нормализована» другими процедурами системы, приводя дату к началу или концу дня для соответствия методологии БУ.

Шаг 1. Модификация схемы компоновки данных (СКД)

Первым делом нам необходимо проверить саму схему в расширении. Рассмотрим запрос, который используется в отчете «Остатки товаров»:


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

Проанализируем вкладку «Параметры» в конструкторе СКД. Найдем параметр &КонецПериода. Если в колонке «Выражение» указано что-то вроде КонецПериода(&ДатаОтчета, "День"), это нужно удалить. Оставив поле пустым, мы разрешаем системе использовать точное значение даты и времени, переданное из программного кода.

Шаг 2. Программная установка параметров в расширении

Рассмотрим пример кода, который необходимо разместить в модуле формы отчета в расширении. Важно переопределить формирование параметров так, чтобы наше время не затиралось. Используем аннотацию &Вместо для процедуры ПодготовитьПараметрыОтчетаНаСервере:


&НаСервере
&Вместо("ПодготовитьПараметрыОтчетаНаСервере")
Функция Расш1_ПодготовитьПараметрыОтчетаНаСервере()
    
    // Получаем менеджер отчета и стандартную структуру параметров
    МенеджерОтчета = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ЭтотОбъект.ИмяФормы);
    ПараметрыОтчета = МенеджерОтчета.ПустыеПараметрыКомпоновкиОтчета;

    // Устанавливаем нашу дату со временем из добавленного реквизита формы
    // Допустим, мы добавили реквизит Отчет.Расш1_КонецПериода с типом Дата (состав Дата и время)
    ПараметрыОтчета.НачалоПериода = НачалоДня(Отчет.Расш1_КонецПериода); 
    ПараметрыОтчета.КонецПериода  = Отчет.Расш1_КонецПериода;

    // Заполняем остальные типовые параметры
    ПараметрыОтчета.Организация = Отчет.Организация;
    ПараметрыОтчета.Группировка  = Отчет.Группировка.Выгрузить();
    ПараметрыОтчета.НастройкиКомпоновкиДанных = Отчет.КомпоновщикНастроек.ПолучитьНастройки();

    Возврат ПараметрыОтчета;
КонецФункции

Обратите внимание на важный нюанс: при передаче даты в ПараметрыОтчета.КонецПериода, подсистема может все равно попытаться её изменить. Если это происходит, выясним причину в общем модуле БухгалтерскиеОтчетыКлиентСервер.

Шаг 3. Использование объекта «Граница»

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


// Пример создания границы для включения движений текущей секунды
НужнаяДата = Отчет.Расш1_КонецПериода;
ПараметрГраница = Новый Граница(НужнаяДата, ВидГраницы.Включая);

// Установка параметра непосредственно в компоновщик настроек
ЗначениеПараметра = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода"));
Если ЗначениеПараметра <> Неопределено Тогда
    ЗначениеПараметра.Значение = ПараметрГраница;
    ЗначениеПараметра.Использование = Истина;
КонецЕсли;

Шаг 4. Обход ограничений интерфейса

Проанализируем работу стандартной формы. Если на форме отображается поле Период (тип СтандартныйПериод), то при нажатии кнопки «Сформировать» платформа сама может сбросить время в настройках компоновщика. Чтобы этого избежать, рекомендуем:

Итоги и рекомендации

Разберем типичную ошибку: использование КонецДня(Дата). Эта функция всегда вернет 23:59:59. Если ваша задача — получить остатки на утро, никогда не используйте функции приведения к периоду. Для решения проблемы в БП 3.0 наиболее эффективным оказывается сочетание очистки «Выражения» в параметрах СКД и программной установки параметра через объект Граница в расширении.

Выясним также, что если вы создаете отчет «с нуля» (как сделал автор вопроса в сообщении №6), проблема исчезает сама собой, так как в новом отчете нет типовых «наслоений» кода БП 3.0, которые нормализуют даты. Но если важно сохранить типовой функционал (расшифровки, настройки группировок), следуйте инструкции по модификации параметров через КомпоновщикНастроек в модуле формы или объекта.

← На главную