При доработке типовых отчетов в конфигурации «1С:Бухгалтерия предприятие 3.0» (БП 3.0) программисты часто сталкиваются с тем, что система игнорирует указанное время в параметрах и принудительно выводит остатки на конец дня. Это происходит из-за глубокой интеграции механизмов бухгалтерского учета, где итоги традиционно рассматриваются в разрезе дней. Однако для оперативного учета часто требуется знать остаток, например, на 10:00:00 утра. Разберем по шагам, почему так происходит и как заставить отчет учитывать время.
Когда мы передаем дату в параметр запроса виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Остатки, система может вести себя по-разному в зависимости от того, как настроена Схема компоновки данных (СКД). Проанализируем основные факторы, влияющие на результат:
&НачалоПериода или &КонецПериода часто прописан код на языке выражений СКД, например: КонецПериода(&Период, "День"). Это выражение выполняется непосредственно перед выполнением запроса, перезаписывая любое время, которое вы передали из формы.СтандартныйПериод, платформа автоматически устанавливает время даты окончания на 23:59:59.ПодготовитьПараметрыОтчетаНаСервере готовит структуру параметров, которая позже может быть «нормализована» другими процедурами системы, приводя дату к началу или концу дня для соответствия методологии БУ.Первым делом нам необходимо проверить саму схему в расширении. Рассмотрим запрос, который используется в отчете «Остатки товаров»:
ВЫБРАТЬ
ХозрасчетныйОстатки.Счет КАК Счет,
ХозрасчетныйОстатки.Субконто1 КАК Номенклатура,
ХозрасчетныйОстатки.КоличествоОстаток КАК Количество
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&КонецПериода, Счет В (&СчетаУчета), , ) КАК ХозрасчетныйОстатки
Проанализируем вкладку «Параметры» в конструкторе СКД. Найдем параметр &КонецПериода. Если в колонке «Выражение» указано что-то вроде КонецПериода(&ДатаОтчета, "День"), это нужно удалить. Оставив поле пустым, мы разрешаем системе использовать точное значение даты и времени, переданное из программного кода.
Рассмотрим пример кода, который необходимо разместить в модуле формы отчета в расширении. Важно переопределить формирование параметров так, чтобы наше время не затиралось. Используем аннотацию &Вместо для процедуры ПодготовитьПараметрыОтчетаНаСервере:
&НаСервере
&Вместо("ПодготовитьПараметрыОтчетаНаСервере")
Функция Расш1_ПодготовитьПараметрыОтчетаНаСервере()
// Получаем менеджер отчета и стандартную структуру параметров
МенеджерОтчета = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ЭтотОбъект.ИмяФормы);
ПараметрыОтчета = МенеджерОтчета.ПустыеПараметрыКомпоновкиОтчета;
// Устанавливаем нашу дату со временем из добавленного реквизита формы
// Допустим, мы добавили реквизит Отчет.Расш1_КонецПериода с типом Дата (состав Дата и время)
ПараметрыОтчета.НачалоПериода = НачалоДня(Отчет.Расш1_КонецПериода);
ПараметрыОтчета.КонецПериода = Отчет.Расш1_КонецПериода;
// Заполняем остальные типовые параметры
ПараметрыОтчета.Организация = Отчет.Организация;
ПараметрыОтчета.Группировка = Отчет.Группировка.Выгрузить();
ПараметрыОтчета.НастройкиКомпоновкиДанных = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
Возврат ПараметрыОтчета;
КонецФункции
Обратите внимание на важный нюанс: при передаче даты в ПараметрыОтчета.КонецПериода, подсистема может все равно попытаться её изменить. Если это происходит, выясним причину в общем модуле БухгалтерскиеОтчетыКлиентСервер.
Для максимально точного получения остатков в 1С используется объект Граница. Он позволяет указать, нужно ли включать документы, записанные в ту же самую секунду, что и указанная дата. Рассмотрим, как применить этот метод. Если в СКД параметр ожидает тип Дата, то передача Границы может вызвать ошибку. Однако, если мы работаем с программным формированием запроса или настраиваем параметры перед выводом, это лучшее решение.
// Пример создания границы для включения движений текущей секунды
НужнаяДата = Отчет.Расш1_КонецПериода;
ПараметрГраница = Новый Граница(НужнаяДата, ВидГраницы.Включая);
// Установка параметра непосредственно в компоновщик настроек
ЗначениеПараметра = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода"));
Если ЗначениеПараметра <> Неопределено Тогда
ЗначениеПараметра.Значение = ПараметрГраница;
ЗначениеПараметра.Использование = Истина;
КонецЕсли;
Проанализируем работу стандартной формы. Если на форме отображается поле Период (тип СтандартныйПериод), то при нажатии кнопки «Сформировать» платформа сама может сбросить время в настройках компоновщика. Чтобы этого избежать, рекомендуем:
ДатаОстатков с составом «Дата и время».ПриКомпоновкеРезультата (в модуле объекта отчета) принудительно устанавливать значение параметра СКД из этого реквизита.Разберем типичную ошибку: использование КонецДня(Дата). Эта функция всегда вернет 23:59:59. Если ваша задача — получить остатки на утро, никогда не используйте функции приведения к периоду. Для решения проблемы в БП 3.0 наиболее эффективным оказывается сочетание очистки «Выражения» в параметрах СКД и программной установки параметра через объект Граница в расширении.
Выясним также, что если вы создаете отчет «с нуля» (как сделал автор вопроса в сообщении №6), проблема исчезает сама собой, так как в новом отчете нет типовых «наслоений» кода БП 3.0, которые нормализуют даты. Но если важно сохранить типовой функционал (расшифровки, настройки группировок), следуйте инструкции по модификации параметров через КомпоновщикНастроек в модуле формы или объекта.