При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда нужные данные отображаются на форме документа, но при попытке найти их в реквизитах самого объекта в конструкторе запроса выясняется, что таких полей просто не существует. В типовых конфигурациях, таких как 1С:Бухгалтерия предприятия 3.0, это стандартная практика для таких полей, как Статус оплаты, Срок оплаты или Состояние электронного документооборота. Рассмотрим подробно, как "добыть" эти данные и правильно использовать их в СКД.
Прежде всего, разберем причину этого явления. В современных конфигурациях 1С для оптимизации и унификации многие данные выносятся за пределы самого документа. Реквизит формы — это переменная, которая существует в оперативной памяти в момент работы пользователя с формой. Она может заполняться динамически при открытии или при изменении других данных. Система компоновки данных работает на уровне запросов к базе данных (SQL), и она "не знает" о том, что происходит в памяти открытой формы. Поэтому наша задача — выяснить, откуда форма берет эти данные в базе, и повторить этот алгоритм в запросе СКД.
Проанализируем ситуацию на примере поля Статус. Если мы откроем форму документа в конфигураторе и увидим реквизит, у которого в пути к данным указано просто имя (например, СтатусОплаты), а не Объект.СтатусОплаты, значит, это чисто визуальный элемент. Выясним, как он заполняется:
ПриЧтенииНаСервере или поиск по имени реквизита.Как показывает практика и обсуждение, в БП 3.0 такие сведения чаще всего хранятся в специализированных регистрах:
СрокиОплатыДокументов.СтатусыДокументов или вычисляются через регистры расчетов с контрагентами.Рассмотрим, как правильно составить запрос в СКД, чтобы получить эти данные. Мы будем использовать Левое соединение, чтобы в отчет попали все документы, даже если для них еще не установлены статусы или сроки оплаты.
Пример структуры запроса для получения счетов от поставщиков со сроками оплаты:
ВЫБРАТЬ
СчетНаОплату.Ссылка КАК Ссылка,
СчетНаОплату.Номер КАК Номер,
СчетНаОплату.Дата КАК Дата,
СчетНаОплату.Контрагент КАК Контрагент,
ЕСТЬNULL(СрокиОплаты.СрокОплаты, ДАТАВРЕМЯ(1, 1, 1)) КАК СрокОплаты,
ЕСТЬNULL(Статусы.Статус, ЗНАЧЕНИЕ(Перечисление.СтатусыОплаты.ПустаяСсылка)) КАК Статус
ИЗ
Документ.СчетНаОплатуПоставщика КАК СчетНаОплату
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СрокиОплатыДокументов КАК СрокиОплаты
ПО СчетНаОплату.Ссылка = СрокиОплаты.Документ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыДокументов КАК Статусы
ПО СчетНаОплату.Ссылка = Статусы.Документ
Важный момент: если регистр периодический (например, статус может меняться со временем), необходимо использовать таблицу СрезПоследних. Однако для документов в БП 3.0 регистры сведений по статусам часто являются непериодическими, где ключом (измерением) выступает сама ссылка на документ.
Если на форме документа вы видите флажок или текст Просрочено, это почти всегда вычисляемое значение. В СКД не нужно пытаться найти это поле в базе. Разберем, как реализовать это на вкладке "Вычисляемые поля":
ДнейПросрочки.Пример выражения для поля:
ВЫБОР КОГДА СрокОплаты < &ТекущаяДата И Статус <> ЗНАЧЕНИЕ(Перечисление.СтатусыОплаты.Оплачено) ТОГДА РАЗНОСТЬДАТ(СрокОплаты, &ТекущаяДата, "ДЕНЬ") ИНАЧЕ 0 КОНЕЦ
Здесь &ТекущаяДата — это стандартный параметр СКД, который можно задать в настройках или передавать из кода.
Иногда "реквизит формы" — это не данные документа, а фильтр, который пользователь установил на самой форме отчета (например, переключатель "Только просроченные"). Чтобы это значение повлияло на результат, проанализируем механизм передачи параметров в компоновщик настроек.
В модуле формы отчета, перед формированием, мы можем программно установить значение параметра СКД, основываясь на реквизите формы:
// В процедуре ПриКомпоновкеРезультата или перед вызовом формирования
ПараметрДанных = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ПоказыватьТолькоПросроченные");
Если ПараметрДанных <> Неопределено Тогда
ПараметрДанных.Значение = Объект.РеквизитФормыПросрочка;
ПараметрДанных.Использование = Истина;
КонецЕсли;
В некоторых случаях (например, статус "Оплачен" в старых редакциях или специфических документах) данные не записываются в регистр, а вычисляются функцией в модуле менеджера или формы. Если мы столкнулись с такой "дичью", у нас есть два пути:
Хозрасчетный.Остатки) или регистром накопления (ВзаиморасчетыСКонтрагентами), чтобы сравнить сумму документа с суммой оплат по нему.Резюме: Чтобы "засунуть" реквизит формы в СКД, нужно перестать искать его на форме и найти его в базе данных. В 90% случаев в БП 3.0 это решается через левое соединение с регистрами СтатусыДокументов и СрокиОплатыДокументов. Все остальное — это расчеты в самом запросе или в вычисляемых полях компоновки.