Как взять данные из регистра бухгалтерии и вывести параметры в печатную форму

Программист 1C:Бухгалтерия Бухгалтерский учет
← На главную

При разработке печатных форм в 1С часто возникает задача вывода данных, которых нет непосредственно в реквизитах документа, но которые отражены в учете. Типичный пример — получение суммы проводок, сформированных документом или его основанием, из регистра бухгалтерии. В этой статье мы подробно разберем, как правильно построить запрос к регистру Хозрасчетный, как передать параметры и избежать распространенных ошибок при работе со ссылками.

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

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

Обход движений через выборку (как в сообщении 0) заставляет систему считывать все записи регистра по документу, что замедляет работу. Использование механизма запросов к виртуальным таблицам позволяет сразу получить агрегированные данные (например, сумму) и отфильтровать их на уровне СУБД. Проанализируем, как это реализовать.

Шаг 1. Создание запроса к виртуальной таблице регистра бухгалтерии

Для получения данных о проводках лучше всего использовать виртуальную таблицу ДвиженияССубконто или Обороты. Если нам нужна просто сумма между счетами без аналитики, таблица Обороты будет работать быстрее. Однако для получения детальной информации чаще используется ДвиженияССубконто.

Рассмотрим структуру запроса, который выбирает сумму по конкретному документу-регистратору:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйДвиженияССубконто.Сумма КАК Сумма
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(&НачалоПериода, &КонецПериода, Регистратор = &Ссылка, , ) КАК ХозрасчетныйДвиженияССубконто";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
РезультатЗапроса = Запрос.Выполнить();

Важный момент: фильтр по регистратору Регистратор = &Ссылка следует передавать именно в параметры виртуальной таблицы (третий параметр в скобках после имени таблицы), а не в секцию ГДЕ. Это критически важно для производительности в высоконагруженных базах.

Шаг 2. Решение проблемы «Несовместимые типы» в запросе

В процессе разработки (сообщение 5) может возникнуть ошибка: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». Это происходит потому, что поле Регистратор имеет составной тип данных. Если в параметр &Ссылка попадает значение, тип которого система не может однозначно сопоставить с типами регистраторов, возникает конфликт.

Чтобы избежать этого, разберем более надежный способ написания условия в запросе с использованием оператора ССЫЛКА:


Запрос.Текст = 
    "ВЫБРАТЬ
    |   СУММА(ХозрасчетныйДвиженияССубконто.Сумма) КАК Сумма
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
    |       , 
    |       , 
    |       Регистратор ССЫЛКА Документ.ПередачаТоваров И Регистратор = &Ссылка, 
    |       , 
    |       ) КАК ХозрасчетныйДвиженияССубконто";

Здесь мы явно указываем системе, что нас интересуют движения конкретного вида документа. Это снимает неопределенность типов и предотвращает ошибку.

Шаг 3. Правильный поиск связанного документа-основания

Выясним причину, по которой поиск через НайтиПоНомеру() является плохой практикой (как в сообщении 12). Номера документов могут повторяться в разных годах, а структура номера может измениться. Если печатная форма строится для документа «Дефект», а данные нужны из «Передачи товаров», правильно будет обратиться к реквизиту-основанию.

Если в вашем документе настроена связь «ведущий-ведомый», используем следующий подход:


// Ссылка — это ссылка на текущий документ (Дефект)
Если ЗначениеЗаполнено(Ссылка.ДокументОснование) Тогда
    СсылкаТов = Ссылка.ДокументОснование;
Иначе
    // Если основание не заполнено, обрабатываем ошибку или ищем иным способом
    Возврат;
КонецЕсли;

Если же прямой ссылки нет, можно воспользоваться критерием отбора СвязанныеДокументы, но это более сложный путь. В большинстве типовых конфигураций ссылка на родительский документ хранится в реквизите ДокументОснование или Основание.

Шаг 4. Вывод данных в макет печатной формы

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

Проанализируем пример кода для функции печати:


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

    // 2. Выводим шапку
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьШапка.Параметры.Номер = Ссылка.Номер;
    ОбластьШапка.Параметры.Дата = Ссылка.Дата;
    ОбластьШапка.Параметры.ОбщаяСумма = СуммаИзРегистра; // Параметр из регистра
    ТабДок.Вывести(ОбластьШапка);
    
    // 3. Выводим строки
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    Для Каждого Стр Из Ссылка.Товары Цикл
        ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Стр);
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;
    
    Возврат ТабДок;
КонецФункции

Рекомендации по оптимизации

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

  1. Используйте индексированные поля: Поле Регистратор в регистре бухгалтерии всегда индексировано, поэтому поиск по нему выполняется мгновенно.
  2. Уточняйте счета: Если вам нужна сумма не по всем движениям документа, а только по конкретной проводке (например, Дт 10.07 — Кт 10.05), обязательно добавьте параметры СчетДт и СчетКт в условия виртуальной таблицы.
  3. Консоль запросов: Перед написанием кода в конфигураторе всегда проверяйте запрос в «Консоли запросов». Это позволит сразу увидеть, возвращает ли запрос данные по конкретной ссылке и нет ли ошибок в типах данных.
  4. Проверка на пустые значения: Всегда проверяйте результат выполнения запроса методом Пустой() или проверяйте результат Выборка.Следующий(), чтобы избежать ошибок обращения к несуществующим записям.

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

← На главную