При разработке внешних обработок и интеграций в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда на форме документа отображается колонка, которой физически нет в реквизитах табличной части самого объекта. Типичным примером является документ «Отражение зарплаты в бухучете» в конфигурации «1С:Бухгалтерия предприятия 3.0» (БП 3.0).
В этой статье мы подробно разберем, почему возникает такая сложность, как устроена архитектура хранения данных регистрации в налоговом органе и как правильно заполнить эти данные программно из внешней обработки без обращения к контексту формы.
Давайте проанализируем ситуацию. На форме документа «Отражение зарплаты в бухучете» в табличной части НачисленныйНДФЛ пользователи видят колонку РегистрацияВНалоговомОргане (или РегистрНалОрг). Однако, если мы откроем конфигуратор и изучим метаданные документа, мы обнаружим, что такого реквизита у табличной части нет.
Почему так сделано?
Разработчики фирмы 1С применили паттерн разделения (декомпозиции) данных для оптимизации хранения и унификации интерфейса. Элемент справочника РегистрацииВНалоговомОргане содержит в себе несколько ключевых реквизитов:
КППКодПоОКТМОКодПоОКАТОКод (код самого налогового органа)В самой базе данных (в табличной части документа) хранятся именно эти четыре физических реквизита. На форму же выводится виртуальное (динамически создаваемое) поле связи, которое объединяет эти данные для удобства пользователя. Когда бухгалтер выбирает регистрацию на форме, платформа автоматически «расщепляет» выбранный элемент справочника на физические составляющие и записывает их в строки табличной части.
При открытии документа происходит обратный процесс: система считывает физические данные из строк, сопоставляет их по реквизитам со справочником регистраций и отображает нужный элемент в виртуальной колонке формы.
Некоторые начинающие разработчики пытаются решить задачу «в лоб»: программно открыть форму документа, перебрать элементы формы и заполнить их значения. Рассмотрим, почему это плохой путь:
ПолучитьФорму() вызовет критическую ошибку выполнения.Правильный подход заключается в прямой работе с объектом документа на сервере и заполнении физических колонок табличной части.
Рассмотрим подробный алгоритм, как решить эту задачу из внешней обработки.
Шаг 1. Получение объекта документа и поиск нужной регистрации
Для начала нам необходимо получить объект документа для изменения, а также определить, какую именно регистрацию в ИФНС мы хотим сопоставить строкам. Для этого мы можем обратиться к справочнику РегистрацииВНалоговомОргане, сделав отбор по организации документа.
Шаг 2. Чтение физических параметров регистрации
Чтобы заполнить строки табличной части, нам нужно выгрузить из найденного элемента справочника его реквизиты: КПП, ОКТМО, ОКАТО и Код ИФНС. Для быстрой работы на сервере воспользуемся функцией общего модуля ОбщегоНазначения.ЗначенияРеквизитовОбъекта().
Шаг 3. Заполнение строк табличной части документа
Перебираем строки табличной части НачисленныйНДФЛ и записываем полученные физические значения в соответствующие реквизиты строки. После этого записываем и проводим документ.
Посмотрим на практический пример реализации данного алгоритма на встроенном языке 1С:
// Процедура заполняет параметры регистрации в налоговом органе для переданного документа
Процедура ЗаполнитьРегистрациюВДокументе(СсылкаНаДокумент, РегистрацияСсылка) Экспорт
// 1. Получаем объект документа для редактирования
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// Если документ заблокирован другим пользователем, обрабатываем исключение
Попытка
ДокументОбъект.Заблокировать();
Исключение
ЗаписатьЛогОшибки("Не удалось заблокировать документ: " + СсылкаНаДокумент);
Возврат;
КонецПопытки;
// 2. Получаем необходимые физические реквизиты из справочника регистраций
СтруктураРеквизитов = Новый Структура("КПП, КодПоОКТМО, КодПоОКАТО, Код");
ДанныеРегистрации = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(РегистрацияСсылка, СтруктураРеквизитов);
// 3. Обходим табличную часть и заполняем реквизиты напрямую
Для Каждого СтрокаТЧ Из ДокументОбъект.НачисленныйНДФЛ Цикл
// Заполняем физические поля строки значениями из справочника регистрации
СтрокаТЧ.КПП = ДанныеРегистрации.КПП;
СтрокаТЧ.КодПоОКТМО = ДанныеРегистрации.КодПоОКТМО;
СтрокаТЧ.КодПоОКАТО = ДанныеРегистрации.КодПоОКАТО;
СтрокаТЧ.КодНалоговогоОргана = ДанныеРегистрации.Код; // В справочнике код налоговой хранится в стандартном реквизите "Код"
КонецЦикла;
// 4. Записываем объект с проведением
Попытка
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
ДокументОбъект.Разблокировать();
Исключение
ДокументОбъект.Разблокировать();
ВызватьИсключение; // Передаем ошибку выше для анализа
КонецПопытки;
КонецПроцедуры
Важно понимать, что произойдет после того, как наша внешняя обработка успешно выполнит транзакцию записи. Когда конечный пользователь откроет данный документ в режиме предприятия, платформа выполнит стандартный код инициализации формы на сервере.
В конфигурации «1С:Бухгалтерия предприятия 3.0» за сборку этих данных отвечает специализированный общий модуль ОтражениеЗарплатыВБухучете. При создании формы на сервере вызывается экспортный метод:
ОтражениеЗарплатыВБухучете.ЗаполнитьРегистрациюВНалоговомОрганеВКоллекцииСтрок(Организация, Период, КоллекцияНачисленныйНДФЛ)
Эта процедура делает следующее:
КПП, КодПоОКТМО и КодНалоговогоОргана.РегистрацияВНалоговомОргане.Таким образом, заполнив базовые физические реквизиты строки табличной части документа из внешней обработки, мы гарантируем полную совместимость со стандартными механизмами конфигурации 1С. Пользователь увидит корректно заполненную форму с выбранной регистрацией в ИФНС, а при формировании регламентированной отчетности по НДФЛ данные будут собраны без ошибок.