При работе с механизмом БухгалтерскиеИтоги в версии 1С 7.7 программисты часто сталкиваются с неприятной особенностью: как только мы пытаемся наложить фильтр или просто использовать аналитику по корреспонденции, система начинает отсекать «лишние» данные. Рассмотрим ситуацию: нам нужно получить все обороты по счету, при этом для определенных корсчетов (например, для 10-го счета «Материалы») нам нужно видеть детализацию по конкретной номенклатуре. Однако стандартный вызов метода ИспользоватьКорСубконто приводит к тому, что в выборку попадают только те счета, которые имеют этот вид субконто, а все остальные корреспонденции просто исчезают.
В этой статье мы подробно разберем, как «подружить» корсчет и корсубконто в одном запросе, научимся обходить ограничения фильтров и правильно использовать индексацию аналитики в 1С 7.7.
Разберем, почему возникает такая ситуация. Когда мы вызываем метод БИ.ИспользоватьКорСубконто(ВидыСубконто.Номенклатура), объект БухгалтерскиеИтоги модифицирует внутренний SQL-запрос (или внутренний механизм выборки в DBF-версии). Система начинает интерпретировать это как условие обязательного наличия данной аналитики. Те корсчета, у которых в плане счетов не задан вид субконто «Номенклатура», не удовлетворяют условию и исключаются из результирующего набора данных.
Проанализируем типичный ошибочный код:
БИ = СоздатьОбъект("БухгалтерскиеИтоги");
БИ.ИспользоватьСубконто(ВидыСубконто.Номенклатура, ВыбНоменклатура, 2);
// Ошибка здесь: этот вызов отфильтрует все корсчета без Номенклатуры
БИ.ИспользоватьКорСубконто(ВидыСубконто.Номенклатура);
БИ.ВыполнитьЗапрос(НачДата, КонДата, ВыбСчет, , , 2);
В результате такого запроса вы никогда не увидите в выборке корсчета, например, 51 или 50 (если на них нет номенклатуры), хотя обороты по ним могли быть.
Чтобы получить все корсчета без исключения, нам нужно отказаться от указания конкретного вида субконто в методе ИспользоватьКорСубконто перед выполнением запроса. Вместо этого мы должны зарезервировать «слоты» под аналитику. Рассмотрим, как это сделать правильно.
Для того чтобы система подтягивала данные по всем субконто корреспонденций, мы вызываем метод ИспользоватьКорСубконто() без параметров столько раз, сколько максимально возможно субконто в нашей конфигурации (обычно 3). Это сообщает системе: «нам нужны данные по всем разрезам, какие бы там ни были».
После выполнения запроса мы будем обращаться к данным не по имени вида субконто, а по его порядковому номеру на конкретном счете. Разберем этот алгоритм по шагам:
ИспользоватьКорСубконто() в цикле перед ВыполнитьЗапрос.Посмотрим на пример кода, который решает задачу универсально. Этот подход позволяет выводить обороты по любым счетам и детально расшифровывать те, которые нам интересны.
Процедура Сформировать()
БИ = СоздатьОбъект("БухгалтерскиеИтоги");
// Резервируем слоты под все возможные корсубконто (обычно до 3-х)
Для Ном = 1 По Метаданные.МаксимальноеКоличествоСубконто Цикл
БИ.ИспользоватьКорСубконто();
КонецЦикла;
// Включаем субсчета и выполняем запрос
// Обратите внимание на флаг "КС" в конце - он важен для работы с корреспонденциями
БИ.ВыполнитьЗапрос(НачДата, КонДата, "20", , , 3, "Проводка", "КС");
БИ.ВыбратьСчета();
Пока БИ.ПолучитьСчет() = 1 Цикл
БИ.ВыбратьКорСчета();
Пока БИ.ПолучитьКорСчет() = 1 Цикл
СтрИнфо = "" + БИ.Счет + " -> " + БИ.КорСчет + " Сумма: " + БИ.КорДО();
Сообщить(СтрИнфо);
// Если это нужный нам корсчет (например, 10), разворачиваем его
Если БИ.КорСчет.ПринадлежитГруппе(СчетПоКоду("10")) = 1 Тогда
// Выясняем, под каким номером идет Номенклатура на этом корсчете
Для НомСуб = 1 По БИ.КорСчет.КоличествоСубконто() Цикл
Если БИ.КорСчет.ВидСубконто(НомСуб) = ВидыСубконто.Номенклатура Тогда
// Теперь выбираем и получаем данные именно по этому номеру
БИ.ВыбратьКорСубконто(НомСуб);
Пока БИ.ПолучитьКорСубконто(НомСуб) = 1 Цикл
ТекНоменклатура = БИ.КорСубконто(НомСуб);
Сообщить(" --- Детализация: " + ТекНоменклатура + " Сумма: " + БИ.КорДО());
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Проанализируем несколько критических моментов, без которых запрос может работать некорректно:
1. Ошибка «Число фильтров субконто превысило допустимое значение»
Эта ошибка возникает, если вы вызываете ИспользоватьКорСубконто() более раз, чем указано в свойствах плана счетов в конфигураторе. Всегда ориентируйтесь на значение Метаданные.МаксимальноеКоличествоСубконто. Не вызывайте этот метод внутри циклов выборки — только один раз перед ВыполнитьЗапрос.
2. Параметр «ТипОтбора» и индекс
В методе ИспользоватьКорСубконто(Вид, Значение, ТипОтбора, Позиция) четвертый параметр Позиция позволяет явно указать, в какой «канал» аналитики поместить данные. Некоторые разработчики используют значение -1 для автоматического распределения, но наиболее надежным считается последовательный вызов без параметров для создания универсальной выборки.
3. Использование флага «КС» (Корреспонденция)
В методе ВыполнитьЗапрос последний параметр управляет составом выбираемых данных. Для того чтобы успешно работали методы ВыбратьКорСчета и ВыбратьКорСубконто, рекомендуется использовать строковый параметр, содержащий символ "К" (например, "СК" для счетов и корсчетов).
Выясним причину возможного замедления. При выполнении универсального запроса (без фильтров по конкретным значениям субконто) 1С 7.7 строит очень сложный SQL-запрос с множеством LEFT JOIN к таблицам _1SBKTTL и _1SENTRY. Если ваша база данных имеет огромный объем проводок, такой запрос может выполняться долго.
В этом случае рассмотрим альтернативный вариант:
Разбиение на два этапа. Сначала мы получаем общие итоги по корсчетам без аналитики. Затем, если в коде мы понимаем, что встретили корсчет, требующий детализации, мы выполняем второй (локальный) запрос БухгалтерскиеИтоги только по этому счету с установленным фильтром. В некоторых случаях (особенно на SQL) два простых запроса отрабатывают быстрее, чем один сверхсложный.
Мы проанализировали механизм работы бухгалтерских запросов в 1С 7.7 и нашли способ избежать потери данных при использовании корсубконто. Основной вывод: не накладывайте фильтр по виду субконто в настройках запроса, если хотите видеть все корсчета. Используйте универсальную инициализацию аналитики и обращайтесь к субконто по их индексам в процессе обхода выборки. Это сделает ваши отчеты точными, а код — гибким и устойчивым к изменениям в плане счетов.