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