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