Как исправить ошибку «Поле агрегатного объекта не обнаружено (Договоры)» и настроить расчет сроков долга в 1С 7.7?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Причина 1. Обращение к несуществующему виду субконто

Ошибка времени выполнения Поле агрегатного объекта не обнаружено (Договоры) возникает в строке инициализации фильтра субконто:

БИ.ИспользоватьСубконто(ВидыСубконто.Договоры,, 1);

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

Способы решения:

  1. Уточнение идентификатора в конфигураторе: откройте дерево метаданных (ветку «Планы счетов» -> «Виды субконто») и проверьте точное наименование идентификатора. Если вид субконто называется, например, Договора, код следует изменить на: БИ.ИспользоватьСубконто(ВидыСубконто.Договора,, 1);
  2. Универсальное получение вида субконто из плана счетов: чтобы отчет не зависел от конкретных идентификаторов метаданных и корректно работал в разных редакциях типовых конфигураций, безопаснее считывать вид субконто непосредственно со счета учета:
    
    СчетУчета = СчетПоКоду("62.1");
    ВидСубк1 = СчетУчета.ВидСубконто(1); // Контрагенты
    ВидСубк2 = СчетУчета.ВидСубконто(2); // Договоры
    
    Если ВыбКонтрагент.Выбран() = 1 Тогда 
        БИ.ИспользоватьСубконто(ВидСубк1, ВыбКонтрагент, 1);
    Иначе 
        БИ.ИспользоватьСубконто(ВидСубк1,, 1);
    КонецЕсли;
    
    БИ.ИспользоватьСубконто(ВидСубк2,, 1);
    

Причина 2. Ошибочный уровень обращения к реквизитам субконто в цикле

Вторая частая ошибка связана с нарушением иерархии обхода итогов. В исходном коде получение реквизита срока оплаты и вычисление расчетных дат интервалов производилось на уровне выборки первого субконто (Контрагента):


БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
    // ...
    Попытка 
        СрокОплаты = БИ.Субконто(1).СрокОплаты;
    Исключение 
        СрокОплаты = ВыбДнейПросрочки;
    КонецПопытки;
    
    Дата2 = Дата1 - 60 + 1 - СрокОплаты;
    Дата4 = Дата1 - 120 + 1 - СрокОплаты;
    // ...
    БИ.ВыбратьСубконто(2);
    Пока БИ.ПолучитьСубконто(2) = 1 Цикл
        // Обработка договоров
    КонецЦикла;
КонецЦикла;

Проанализируем, почему этот код работает некорректно:

  1. Субконто уровня 1 — это элемент справочника Контрагенты. У контрагента нет реквизита СрокОплаты (или ЧерезДней), так как кредитные условия задаются в договоре.
  2. Поскольку обращение к БИ.Субконто(1).СрокОплаты всегда вызывает исключение, код переходит в блок Исключение, где переменной присваивается значение по умолчанию или 0.
  3. Затем условие Если СрокОплаты = 0 Тогда СрокОплаты = 30; КонецЕсли; принудительно устанавливает срок 30 дней для абсолютно всех договоров, игнорируя реальные условия из справочника договоров.
  4. Значения дат (Дата2, Дата4, Дата6) рассчитываются до того, как проверяется равенство срока нулю, что дополнительно искажает интервалы.

Пошаговый алгоритм исправления выборки

Разберем правильный порядок действий:

  1. Обход по первому субконто (Контрагент) используется только для группировки и вывода данных по контрагенту.
  2. Выборка и расчет реквизитов договора (СрокОплаты, ЧерезДней, дата заключения) должны производиться внутри цикла второго субконто (Пока БИ.ПолучитьСубконто(2) = 1 Цикл).
  3. Перед обращением к реквизитам справочника обязательно проверяем, выбрано ли значение субконто.
  4. Расчет граничных дат периодов просрочки выполняется только после того, как срок оплаты определен и проверен.

Посмотрим на исправленный фрагмент модуля отчета:


БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
    КонтрагентОбъект = БИ.Субконто(1);
    Состояние("Обработка: " + СокрЛП(КонтрагентОбъект));
    
    // Проверяем наличие общего сальдо по контрагенту
    Если Дебит1 = 1 Тогда 
        СуммаКонтр = БИ.СКД();
    Иначе 
        СуммаКонтр = БИ.СКК();
    КонецЕсли;
    
    Если СуммаКонтр <= 0 Тогда 
        Продолжить;
    КонецЕсли;
    
    // Переходим к детализации по договорам
    БИ.ВыбратьСубконто(2);
    Пока БИ.ПолучитьСубконто(2) = 1 Цикл
        ДоговорОбъект = БИ.Субконто(2);
        
        Если Дебит1 = 1 Тогда 
            Сумма = БИ.СКД() - БИ.СКК();
        Иначе 
            Сумма = БИ.СКК() - БИ.СКД();
        КонецЕсли;
        
        Если Сумма <= 0 Тогда 
            Продолжить;
        КонецЕсли;
        
        // Получаем срок оплаты из реквизита договора
        СрокОплаты = 0;
        Если ПустоеЗначение(ДоговорОбъект) = 0 Тогда
            // Проверяем наличие нужного реквизита (ЧерезДней или СрокОплаты)
            Попытка
                СрокОплаты = ДоговорОбъект.ЧерезДней;
            Исключение
                Попытка
                    СрокОплаты = ДоговорОбъект.СрокОплаты;
                Исключение
                    СрокОплаты = ВыбДнейПросрочки;
                КонецПопытки;
            КонецПопытки;
        КонецЕсли;
        
        // Если срок не заполнен в договоре, берем значение по умолчанию
        Если (Число(СрокОплаты) <= 0) Тогда
            СрокОплаты = 30;
        КонецЕсли;
        
        // Рассчитываем интервалы дат с учетом полученного срока
        Дата2  = Дата1 - 60  + 1 - СрокОплаты;
        Дата4  = Дата1 - 120 + 1 - СрокОплаты;
        Дата6  = Дата1 - 180 + 1 - СрокОплаты;
        Дата12 = Дата1 - 365 + 1 - СрокОплаты;
        
        // Далее следует алгоритм анализа проводок и распределения сумм по периодам...
        
    КонецЦикла; // Цикл по договорам
КонецЦикла; // Цикл по контрагентам

Рекомендации по оптимизации отчетов по задолженности

При построении отчетов по дебиторской задолженности в 1С 7.7 рекомендуем учитывать следующие правила:

  1. Разделение субсчетов расчетов и авансов: выполнение запроса по счету верхнего уровня "62" сворачивает остатки по счету 62.1 (расчеты) и 62.2 (авансы). Для корректного анализа дебиторской задолженности покупателей запрос следует строить строго по счету "62.1".
  2. Ограничение глубины выборки проводок: конструкция БИ.ВыполнитьЗапрос("01.01.01", Дата1, ...) с детализацией "Проводка" считывает все движения за всю историю базы. На больших базах это приводит к критическому замедлению. Ограничивайте начальную дату запроса разумным интервалом (например, текущая дата минус 1–2 года).
  3. Проверка типов перед обращением: всегда оборачивайте обращения к реквизитам субконто в проверку ПустоеЗначение() или блоки Попытка ... Исключение, так как в реальной базе проводки могут содержать незаполненные субконто или объекты непредусмотренных типов.
← На главную