Описание¶
Справочник регламентированной отчетности предназначен для разработки и хранения отчетов, данные в которых могут быть модифицированы и/или дополнены пользователем. В отличие от остальных отчетов системы, регламентированные отчеты могут работать в режиме ввода данных, в этих отчетах могут быть настроены формулы расчета полей, они умеют хранить введенные пользователем данные и производить пересчеты связанных ячеек.
Поля¶
| Наименование | Описание |
|---|---|
| Дата | Дата формирования отчетов |
| Компания | Компания |
| Отчетность |
Справочник вариантов/групп отчетов. Используется для группировки отчетов по смысловому признаку. Примеры:
Для каждой группы создаётся свой набор отчетности. |
Команды¶
| Наименование | Описание |
|---|---|
| Обновить | Переформировывает отчет с сохранением данных, введенных пользователем |
| Переформировать | Полностью обновляет отчет, введенные пользователем данные – очищаются |
| Дизайнер |
Переводит отчет в режим Дизайнер. В этом режиме, производится настройка формы и алгоритма формирования отчета. Примеры использования функций, см. ниже |
Дизайн отчета¶
Процедура разработки отчета состоит из двух этапов. Первый этап – формирование печатной формы (макета), второй – разработка программного модуля.
Форма отчета должна быть задана как Макет:

Поля, в которые пользователь будет вводить данные, а также поля, которые будут рассчитываться автоматически, в макете отчета должны быть отмечены как параметры:

Параметр расшифровки заполнять не нужно, он заполнится автоматически, при сохранении отчета.
Каждый параметр отчета, рассчитываемый по какой-то формуле, должен иметь соответствующую процедуру в модуле. Например, на картинке ниже показан параметр C30 и процедура его расчета:

Любой регламентированный отчет должен иметь как минимум одну процедуру Make ():

Эта процедура также является точкой входа при формировании отчета.
В примере выше указан минимальный набор кода для формирования отчета.
Первая строка модуля производит инициализацию внутренней переменной area.
Вторая строка выводит отчет на экран.
Типизированные ячейки¶
Для любой ячейки отчета можно указать тип содержащегося в нем значения. Однако, данная функция недоступна в пользовательском (1С:Предприятие) режиме редактирования макета. Разработку форм отчетов, для которых есть необходимость в задании типа вводимых значений, необходимо вести в режиме 1С:Конфигуратор. В этом режиме, система позволяет задавать дополнительные свойства ячейкам:

Не рекомендуется использовать типизацию для ячеек, где предполагается хранить текст (строковые значения). Вместо этого, отключите флаг Содержит значение. В противном случае, пустые ячейки, не определенные начальными значениями при заполнении, будут принимать значение 0, что может не соответствовать ожиданиям разработчика отчета.
После разработки формы в конфигураторе, её следует перенести в редактируемый отчет, используя обычное копирование/вставку:

Функции¶
Помимо стандартного использования процедур и функций языка программирования 1С, в системе разработан ряд специальных функций, для облегчения вывода данных в отчет.
get ( Parameter, Report = undefined ), getLast ( Parameter, Report = undefined )¶
Возвращает значение поля отчета. Вариант метода getLast () возвращает значение из предыдущего отчета. Предыдущий отчет – это отчет, период формирования которого меньше текущего отчета.
Parameter: Строка, задается имя области (имя параметра макета)
Report: Строка, идентификатор отчета. Если не указан – значение будет взято из области текущего отчета, если указан – значение берется из отчета с соответствующим идентификатором. Идентификатор отчета задается в форме редактирования элемента отчета.
sum ( Parameter, Report = undefined ), sumLast ( Parameter, Report = undefined )¶
Возвращает сумму значений полей. Вариант метода sumLast () возвращает значение из предыдущего отчета. Предыдущий отчет – это отчет, период формирования которого меньше текущего отчета.
Parameter: Строка, задаются имена областей (параметров макета) для суммирования. Допускается указание полей через запятую либо двоеточие.
Примеры:
// Сумма строки или колонки
sum ( "C1:C10" );
// Сумма прямоугольной области
sum ( "A1:B15" );
Report: Строка, идентификатор отчета. Если не указан – значение будет взято из области текущего отчета, если указан – значение берется из отчета с соответствующим идентификатором. Идентификатор отчета задается в форме редактирования элемента отчета.
mapField ( Field, KeyField, ParamsList = undefined, Dataset = "Table" )¶
Данная функция позволяет задать для запроса параметры и одновременно с этим, использовать эти параметры для агрегации данных в заданной ячейке отчета.
Эту функцию удобно использовать когда нужно получать данные по разным кодам аналитики, группировать их и выводить в ячейку отчета.
Внимание! данная функция не меняет источник данных, и не группирует записи по ключам автоматически. В тексте запроса нужно самостоятельно позаботиться об уникальности ключей.
В примере на картинке показано, как коды статей затрат мапятся к полям отчета. На картинке видно, что суммы кодов статей 000067 и 000019 будут включены в A7 и B7 (в соответствии с источником данных).
Field: Строка, задает поле отчета, куда выводить результат. В примере ниже, это А7.
KeyFields: Строка, параметры запроса. На примере ниже, это 000067 и 000019 и так далее.
ParamsList: Строка, имя параметра запроса. Значения заданные через запятую – считаются списком значений. В примере, “list”– задает имя параметра запроса, то есть &Expeses8110
Dataset: Строка, задает источник данных внутри запроса, в примере это // ^8110 и // ^8110_LastYear

assignField ( Field, KeyField = undefined, Dataset = "Table" )¶
Задает явную связь полей и значений. В примере ниже указывается, что поле в A21 нужно поместить значение, ключ которого “Current”.
Field: Строка, задает поле отчета, куда выводить результат. В примере ниже, это А21.
KeyField: Строка, значение из результата запроса из обязательного в таких случаях, поля Key. На примере ниже, это “Last”, “Current”.
Dataset: Строка, задает источник данных внутри запроса, в примере это // _1_1_4

FieldValues¶
Ручное заполнение. Принцип ручного заполнения в том, что можно самому заполнить специальное соответствие (FieldsValues), который система будет использовать для вывода в отчет.
На картинке показано, что данное соответствие заполняется значениями запроса, ключами соответствия являются ячейки отчета.

RegulatoryReports.SaveUserValue ( Report, Value, Field, ContainsValue )¶
При помощи данной функции, можно из кода обработчиков рассчитываемых полей, устанавливать значения полям так, как будто их ввел пользователь.
Данная возможность требуется не часто, но в некоторых ситуациях без неё не обойтись.
Например, в отчете есть два связанных поля, которые принимают булевы значения:

При установке мужского пола, женский пол должен принять противоположное значение и наоборот.
Для того, чтобы обеспечить такую взаимосвязь, необходимо использовать такой код:

В данном примере, использовать RegulatoryReports.SaveUserValue нужно обязательно, в противном случае, система будет выводить в рассчитываемые поля те значения, которые до этого ранее вводил пользователь. Строго говоря, в поля, которые рассчитываются, пользователь вводить ничего не должен, но данный случай является исключением, и для его корректной обработки, нужно в обработчике, который рассчитывает толе, “сэмулировать“ ввод рассчитанного значения.
Примечание: в случае, если требуется показывать отличные от стандартных представления булевых полей, можно использовать формат таких полей, например так: BF=' '; BT='V'
Отчеты с параметрами¶
В некоторых случаях, требуется разработать регламентированный отчет, с некоторыми дополнительными входящими параметрами, при этом требуется, чтобы сами параметры в отчет не выводились. Для решения такой задачи, можно воспользоваться свойством PrintArea табличного документа:

Контекст выполнения отчета¶
При построении отчета, можно использовать свойства объекта отчета, и некоторые вспомогательные переменные:
| Calculated |
Булевый реквизит, определяет рассчитан отчет, или еще нет. Реквизит принимает значение Ложь в следующих случаях:
В большинстве случаев, процедура формирования отчета Make () должна анализировать состояние данного флага с целью предотвращения формирования отчета каждый раз, когда пользователь его открывает. Это не столько вопрос оптимизации, сколько вопрос предотвращения потери введенных пользователем данных, уже после того, как отчет был однажды сформирован. |
| CalledBy |
Переменная содержит ссылку на связанный отчет, изменение которого потребовало обновление полей текущего отчета. В остальных случаях значения переменной неопределенно. Например, если значение поля в Отчет1 используются в Отчет2 и Отчёт3, тогда изменение пользователем значение поля в Отчет1, приведет к (неявной) цепочке вызовов процедуры Make (), отчетов Отчет2 и Отчет3. В модуле формирования этих отчетов будет проинициализирована переменная CalledBy ссылкой на Отчет1. Анализируя значение ссылки, разработчик может принять решение по алгоритму обновление отчета. Далеко не всегда изменение отчета должно приводить к автоматическому обновлению всех данных, в связанных с ним отчетах. Решение об обновлении полей может принимать разработчик, пример реализации такой логики см. ниже. |
Пример типовой процедуры Make () учитывающей окружение:
Procedure Make ()
rebuildReport = not Calculated and CalledBy = undefined;
if ( rebuildReport ) then
// Получаем данные и заполняем отчет...
FieldsValues [ "Company" ] = envFields.Company;
FieldsValues [ "CodeFiscal" ] = envFields.CodeFiscal;
endif;
if ( rebuildReport or CalledBy <> undefined ) then
// Здесь мы окажемся если нужно переформировать весь отчет или
// если пользователь поменял значение поля в отчете DefaultValues,
// а наш отчет это поле использует
requestedBy = DF.Pick ( CalledBy, "MasterReport.Name" );
if ( rebuildReport or requestedBy = "DefaultValues" ) then
// Обновим только связанное поле
FieldsValues [ "FiscalCode" ] = get ( "FiscalCode", "DefaultValues" );
endif;
endif;
area = getArea ();
draw ();
EndProcedure
Экспорт данных¶
В регламентированной отчетности предусмотрен механизм экспорта данных в файл(ы).
На пользовательском уровне, для отчетов, поддерживающих выгрузку в файл(ы), становится доступной кнопка Экспортировать:

Модуль, выполняющий процедуру экспорта располагается на специальной вкладке дизайнера:

В модуле экспорта, кроме основного тела программы, могут располагаться процедуры и функции. Весь код модуля выполняется на сервере.
Результатом работы тела программы должно стать определение экспортной переменной ExportData, расположенной в модуле объекта отчета.
Для облегчения работы по формированию одного файла выгрузки, можно использовать готовую процедуру exportFile ( File ); exportFile () выполнит формирование имени файла по шаблону, передаст файл на клиент, и удалит его с сервера.
Если переменная ExportData заполнена не будет, система выдаст пользователю сообщение об отсутствии данных для выгрузки.
При необходимости выгрузки нескольких файлов, ExportData нужно заполнять самостоятельно. ExportData может принимать значение типа TransferableFileDescription (), либо массив таких значений:
ExporterData = new TransferableFileDescription (...);
// или
file1 = new TransferableFileDescription (...);
ExporterData = new Array ();
ExporterData.Add ( file1 );
Пример процедуры выгрузки:
xml = new XMLWriter ();
file = GetTempFileName ( "xml" );
fillXML ( xml, file );
exportFile ( file );
Procedure fillXML ( XML, File )
xml.OpenFile ( File, "UTF-8" );
xml.WriteXMLDeclaration ();
xml.WriteStartElement ( "dec" );
xml.WriteAttribute ( "TypeName", "IPC18" );
xml.WriteEndElement ();
xml.Close ();
EndProcedure
Для получения значений полей экспортируемого отчета, можно использовать регистр сведений ReportFields, пример запроса и обработки:
s = "
|select ReportFields.Field as Field, isnull ( UserFields.Value, ReportFields.Value ) as Value
|from InformationRegister.ReportFields as ReportFields
| //
| // UserFields
| //
| left join InformationRegister.UserFields as UserFields
| on UserFields.Field = ReportFields.Field
| and UserFields.Report = ReportFields.Report
|where ReportFields.Report = &Report
|union
|select UserFields.Field, UserFields.Value
|from InformationRegister.UserFields as UserFields
|where UserFields.Report = &Report
|";
q = new Query ( s );
q.SetParameter ( "Report", Ref );
data = new Map ();
for each row in q.Execute ().Unload () do
data.Insert ( row.Field, row.Value );
enddo;
Таким образом, будут получены автоматически сформированные поля, и поля введенные пользователем вручную. Объединение в запросе нужно для того, чтобы получить пользовательский ввод для тех полей отчёта, для которых данные не были получены в автоматическом режиме: например, есть таблица, но она не заполняется программно, а только пользователем.