При доработке отчетов в платформе 1С 7.7 часто возникает необходимость наложить дополнительное условие отбора на данные. В стандартной ситуации фильтрация выполняется по видам субконто с использованием методов объекта БухгалтерскиеИтоги. Однако задача усложняется, когда требуемый фильтр (например, перечисление ТипыРабот) является реквизитом справочника (в данном случае ВидыРабот), а не отдельным видом субконто на счете.
Рассмотрим подробно причины возникновения этой проблемы и разберем проверенные способы реализации отбора по реквизиту-перечислению в 1С 7.7.
Выясним причину, почему прямой вызов метода ИспользоватьСубконто() не позволяет указать условие по реквизиту справочника. Объект БухгалтерскиеИтоги в платформе 1С 7.7 работает напрямую с видами субконто. В метод ИспользоватьСубконто() можно передать либо отдельный элемент справочника, либо объект СписокЗначений конкретных элементов, а также указать режим отбора (значение 2).
Прямой отбор по реквизитам элементов справочника внутри механизмов вычисления бухгалтерских итогов не предусмотрен синтаксисом метода. Для решения этой задачи проанализируем три основных подхода.
Рассмотрим наилучший по производительности метод. Перед выполнением расчета бухгалтерских итогов сформируем СписокЗначений, состоящий только из тех элементов справочника ВидыРабот, у которых реквизит ТипРабот совпадает с выбранным пользователем значением перечисления.
Проанализируем пошаговый алгоритм реализации:
ВыбрТипРабот).СписокЗначений и обходим справочник ВидыРабот.ИспользоватьСубконто() с флагом отбора 2.Разберем пример кода реализации данного способа:
СписокВидов = СоздатьОбъект("СписокЗначений");
Если ПустоеЗначение(ВыбрТипРабот) = 0 Тогда
СпрВР = СоздатьОбъект("Справочник.ВидыРабот");
СпрВР.ВыбратьЭлементы();
Пока СпрВР.ПолучитьЭлемент() = 1 Цикл
Если СпрВР.ТекущийЭлемент().ТипРабот = ВыбрТипРабот Тогда
СписокВидов.ДобавитьЗначение(СпрВР.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;
КонецЕсли;
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьПланСчетов(ПланыСчетов.Рабочий);
Если СписокВидов.РазмерСписка() > 0 Тогда
// Режим 2 означает отбор по переданному списку значений
Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, СписокВидов, 2);
ИначеЕсли ПустоеЗначение(ВыбрВидРаботы) = 0 Тогда
Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, ВыбрВидРаботы, 2);
Иначе
Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, , 1);
КонецЕсли;
Ит.ИспользоватьСубконто(ВидыСубконто.Материалы, , 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, Контр, 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Объекты, Об, 1);
Ит.ВыполнитьЗапрос(ВыбНачПериода, ВыбКонПериода, "1", , , 1, , "СК");
Преимущество метода: Бухгалтерский запрос рассчитывается базой данных только по фильтрованным элементам справочника, что существенно повышает скорость формирования отчета.
Разберем альтернативный вариант реализации, при котором выборка из базы производится без ограничения по реквизиту, а проверка отбора происходит непосредственно в цикле обхода результатов метода ПолучитьСубконто().
Посмотрим на пример кода обработки полученных результатов:
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьПланСчетов(ПланыСчетов.Рабочий);
Ит.ИспользоватьСубконто(ВидыСубконто.ВидыРабот, видр, 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Материалы, , 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, Контр, 1);
Ит.ИспользоватьСубконто(ВидыСубконто.Объекты, Об, 1);
Ит.ВыполнитьЗапрос(ВыбНачПериода, ВыбКонПериода, "1", , , 1, , "СК");
Ит.ВыбратьСубконто(ВидыСубконто.ВидыРабот, , , , , "Код");
Пока Ит.ПолучитьСубконто(ВидыСубконто.ВидыРабот) = 1 Цикл
// Получаем элемент справочника ВидыРабот из текущей итерации
ТекВидРабот = Ит.Субконто(ВидыСубконто.ВидыРабот);
// Проверяем фильтр по реквизиту-перечислению
Если ПустоеЗначение(ВыбрТипРабот) = 0 Тогда
Если ТекВидРабот.ТипРабот <> ВыбрТипРабот Тогда
Продолжить; // Пропускаем виды работ, не соответствующие фильтру
КонецЕсли;
КонецЕсли;
// Далее следует основной код вывода секций отчета
// ...
КонецЦикла;
Особенность метода: Прост в написании и не требует дополнительных выборок до выполнения основного запроса, однако при огромных объемах проводок может уступать первому способу по скорости вычислений.
Посмотрим на решение ситуации "с нуля", если учетная политика допускает изменение структуры плана счетов:
Перечисление.ТипыРабот.Ит.ИспользоватьСубконто(ВидыСубконто.ТипыРабот, ВыбрТипРабот, 2);.Этот способ требует перепроведения документов за прошлые периоды для корректного формирования итогов по новому субконто.
Мы проанализировали особенности фильтрации данных по реквизиту справочника типа перечисление в 1С 7.7. Для существующих конфигураций без изменения структуры проводок оптимальным решением является Способ 1 с использованием СписокЗначений, так как он обеспечивает максимальную скорость работы отчета на базе объекта БухгалтерскиеИтоги.