Программное заполнение или редактирование регламентированной отчетности в 1С:Бухгалтерия предприятия 3.0 — это задача, которую опытные разработчики часто называют «сильным колдунством». Сложность заключается в том, что в отличие от обычных документов, данные отчета не лежат в прозрачных реквизитах или табличных частях. Они упакованы в сложные структуры и хранятся в бинарном виде. В этой статье мы подробно разберем, как устроены эти механизмы и как научиться управлять ими программно.
Для начала проанализируем, где именно хранятся цифры, которые мы видим на экране при открытии декларации или расчета. Основным объектом является документ РегламентированныйОтчет. Если мы заглянем в его состав через конфигуратор, то обнаружим ключевой реквизит — ДанныеОтчета с типом ХранилищеЗначений.
Внутри этого хранилища находится объект типа Соответствие (или реже Структура). Особенность этой структуры заключается в следующем:
Соответствия, где ключом выступает имя конкретной ячейки (показателя), а значением — собственно данные (число, строка или дата).Рассмотрим подробнее именование ячеек. Разберем ситуацию на примере: показатель может называться П000010000101. Это не случайный набор символов, а жестко заданный идентификатор в макете отчета. Чтобы программно заполнить конкретное поле, нам сначала необходимо открыть макет отчета в конфигураторе (обычно это XML или табличный документ) и найти имя нужного показателя. Без точного совпадения имени данные в форму не попадут.
Если штатный механизм автозаполнения в отчете отсутствует или не подходит под ваши задачи, нам придется имитировать работу системы. Рассмотрим пошагово, как создать и заполнить отчет «с нуля» через код.
Шаг 1. Создание объекта и инициализация структуры. Сначала мы создаем новый документ и подготавливаем контейнер для данных.
НовыйОтчет = Документы.РегламентированныйОтчет.СоздатьДокумент();
НовыйОтчет.Дата = ТекущаяДата();
НовыйОтчет.Организация = ВыбраннаяОрганизация;
// Установка периода и типа отчета
НовыйОтчет.ИсточникОтчета = "НалоговаяДекларацияПоНалогуНаПрибыль";
// Создаем структуру данных
ДанныеДляХранилища = Новый Соответствие;
ДанныеРаздела1 = Новый Соответствие;
// Заполняем конкретный показатель
ДанныеРаздела1.Вставить("П000010000101", 1500.50);
ДанныеДляХранилища.Вставить("Раздел1", ДанныеРаздела1);
Шаг 2. Сериализация и сохранение. После того как мы сформировали дерево показателей, его нужно упаковать обратно в хранилище значений документа.
НовыйОтчет.ДанныеОтчета = Новый ХранилищеЗначений(ДанныеДляХранилища);
НовыйОтчет.Записать();
Важно помнить, что при таком подходе «автоматические» итоги (суммирующие строки) могут не пересчитаться сами. Выясним причину: механизм расчета итогов часто зашит в модуле формы или модуля объекта отчета и срабатывает при интерактивном взаимодействии. При программном заполнении нам может потребоваться вызвать экспортные процедуры пересчета из общего модуля РегламентированнаяОтчетность.
Если задача стоит иначе — например, пользователь открыл отчет, и мы хотим по нажатию кнопки в нашей обработке заполнить ячейки текущего окна, — подход будет другим. В этом случае мы работаем не с документом в базе, а с данными формы.
Проанализируем коллекцию ЭтаФорма.Отчет.ДанныеОтчета. Это динамическая структура, которая напрямую связана с тем, что отображается на экране. Для программного изменения значений в открытой форме можно использовать следующий пример кода:
// Пример кода для вызова внутри контекста формы отчета
СтруктураДанных = Отчет.ДанныеОтчета; // Тип: ДанныеФормыСтруктура
Если СтруктураДанных.Свойство("Раздел1") Тогда
Раздел1 = СтруктураДанных.Раздел1;
Раздел1.УстановитьЗначение("П000010000101", 5000);
КонецЕсли;
// Обязательно оповещаем форму об изменении, чтобы обновить экран
ЭтаФорма.ОбновитьОтображениеДанных();
В современных конфигурациях БП 3.0 большая часть логики вынесена в общий модуль РегламентированнаяОтчетность. Проанализируем полезные функции этого модуля. Например, процедура СохранитьДанныеОтчета отвечает за кэширование и запись данных в регистры сведений (так называемые «черновики»).
Если вы работаете с внешним отчетом (файл .erf), алгоритм усложняется. Нам нужно:
ВнешниеОтчеты.Создать().ЗаполнитьОтчет() (если она предусмотрена разработчиком).Однако, как справедливо замечено в обсуждении, если в самом отчете процедура Автозаполнение пуста, то вызов этого метода ничего не даст. В этом случае вам придется вручную формировать дерево показателей, основываясь на макете XML-схемы отчета.
Главная трудность, с которой мы столкнемся при программном редактировании, — это постоянная изменчивость форм. ФНС и другие контролирующие органы регулярно обновляют форматы отчетности. В системе 1С это реализуется через создание новых версий макетов внутри одного и того же объекта.
Рассмотрим риски: программный код, который вы написали для заполнения декларации за 1 квартал, может перестать работать во 2 квартале. Почему? Потому что разработчики 1С могут изменить имя показателя (например, был П000010000101, а стал П000010000102) или изменить структуру вложенности разделов в Соответствии.
Чтобы минимизировать эти риски, рекомендуется:
П...), попробуйте реализовать механизм поиска нужного поля по его коду строки в XML-описании макета.ДанныеОтчета, код не должен «падать» с ошибкой, он должен фиксировать пропуск поля для последующего анализа разработчиком.Таким образом, хотя программное заполнение регламентированной отчетности и является трудоемким процессом, понимание внутренней структуры ХранилищаЗначений и умение работать с именами показателей из макетов позволяют автоматизировать даже те отчеты, для которых фирма 1С не предусмотрела штатного механизма автозаполнения.