При разработке и доработке внешних отчетов по дебиторской и кредиторской задолженности в среде 1С:Предприятие 7.7 разработчики часто сталкиваются с ошибками обращения к объектам метаданных и нарушениями логики выборки бухгалтерских итогов. Разберем типичные ошибки в коде отчета, выясним причины их возникновения и рассмотрим правильную реализацию алгоритма распределения задолженности по интервалам просрочки.
Ошибка времени выполнения Поле агрегатного объекта не обнаружено (Договоры) возникает в строке инициализации фильтра субконто:
БИ.ИспользоватьСубконто(ВидыСубконто.Договоры,, 1);
Причина: системный агрегатный объект ВидыСубконто предоставляет доступ к видам субконто только по их точным идентификаторам, заданным в конфигураторе. Если в конкретной конфигурации вид субконто называется иначе (например, ДоговорКомитента, ДоговорКомиссионера, Договора или Основание), прямое обращение через точку вызывает критическую ошибку.
Способы решения:
Договора, код следует изменить на:
БИ.ИспользоватьСубконто(ВидыСубконто.Договора,, 1);
СчетУчета = СчетПоКоду("62.1");
ВидСубк1 = СчетУчета.ВидСубконто(1); // Контрагенты
ВидСубк2 = СчетУчета.ВидСубконто(2); // Договоры
Если ВыбКонтрагент.Выбран() = 1 Тогда
БИ.ИспользоватьСубконто(ВидСубк1, ВыбКонтрагент, 1);
Иначе
БИ.ИспользоватьСубконто(ВидСубк1,, 1);
КонецЕсли;
БИ.ИспользоватьСубконто(ВидСубк2,, 1);
Вторая частая ошибка связана с нарушением иерархии обхода итогов. В исходном коде получение реквизита срока оплаты и вычисление расчетных дат интервалов производилось на уровне выборки первого субконто (Контрагента):
БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
// ...
Попытка
СрокОплаты = БИ.Субконто(1).СрокОплаты;
Исключение
СрокОплаты = ВыбДнейПросрочки;
КонецПопытки;
Дата2 = Дата1 - 60 + 1 - СрокОплаты;
Дата4 = Дата1 - 120 + 1 - СрокОплаты;
// ...
БИ.ВыбратьСубконто(2);
Пока БИ.ПолучитьСубконто(2) = 1 Цикл
// Обработка договоров
КонецЦикла;
КонецЦикла;
Проанализируем, почему этот код работает некорректно:
СрокОплаты (или ЧерезДней), так как кредитные условия задаются в договоре.БИ.Субконто(1).СрокОплаты всегда вызывает исключение, код переходит в блок Исключение, где переменной присваивается значение по умолчанию или 0.Если СрокОплаты = 0 Тогда СрокОплаты = 30; КонецЕсли; принудительно устанавливает срок 30 дней для абсолютно всех договоров, игнорируя реальные условия из справочника договоров.Дата2, Дата4, Дата6) рассчитываются до того, как проверяется равенство срока нулю, что дополнительно искажает интервалы.Разберем правильный порядок действий:
СрокОплаты, ЧерезДней, дата заключения) должны производиться внутри цикла второго субконто (Пока БИ.ПолучитьСубконто(2) = 1 Цикл).Посмотрим на исправленный фрагмент модуля отчета:
БИ.ВыбратьСубконто(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 рекомендуем учитывать следующие правила:
"62" сворачивает остатки по счету 62.1 (расчеты) и 62.2 (авансы). Для корректного анализа дебиторской задолженности покупателей запрос следует строить строго по счету "62.1".БИ.ВыполнитьЗапрос("01.01.01", Дата1, ...) с детализацией "Проводка" считывает все движения за всю историю базы. На больших базах это приводит к критическому замедлению. Ограничивайте начальную дату запроса разумным интервалом (например, текущая дата минус 1–2 года).ПустоеЗначение() или блоки Попытка ... Исключение, так как в реальной базе проводки могут содержать незаполненные субконто или объекты непредусмотренных типов.