При работе с подсистемой бухгалтерского учета в 1С:Предприятии часто возникает задача получения списка аналитики (например, контрагентов), по которой за определенный период были движения или остались сальдо. Начинающие разработчики часто сталкиваются с тем, что запрос к виртуальной таблице Хозрасчетный.ОстаткиИОбороты возвращает странные результаты при попытке выбрать Субконто1, Субконто2 или Субконто3. Давайте подробно разберем, как устроены эти поля и как правильно использовать параметры виртуальных таблиц для получения точных данных.
Первое и самое важное, что нам необходимо понять: поля Субконто1, Субконто2 и далее в виртуальных таблицах — это не просто ссылки на физические колонки в базе данных. Их содержимое напрямую зависит от того, передали ли мы что-то в параметр Виды субконто (шестой по счету параметр таблицы ОстаткиИОбороты).
Рассмотрим две ситуации:
Контрагенты стоят на первом месте, они попадут в поле Субконто1. Если на каком-то другом счете они стоят на второй позиции, то в результате запроса по этому счету они окажутся в Субконто2. Обращение к Субконто3 может вернуть результат, если в конфигурации есть счета, где контрагент назначен третьим видом субконто, или если в базе остались "хвосты" от старых проводок.ПВХ.ВидыСубконтоХозрасчетные.Контрагенты, то платформа принудительно "сдвигает" данные. Для всех счетов, где есть этот вид субконто, значение контрагента всегда будет находиться в поле Субконто1, независимо от его реального положения в плане счетов.Проанализируем ситуацию, когда разработчик пытается собрать контрагентов через ОБЪЕДИНИТЬ, проверяя тип значения через ССЫЛКА Справочник.Контрагенты. Рассмотрим пример такого кода:
ВЫБРАТЬ
ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Справочник.Контрагенты) КАК Контрагент
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , , , ) КАК ХозрасчетныйОстаткиИОбороты
ГДЕ
ХозрасчетныйОстаткиИОбороты.Субконто1 ССЫЛКА Справочник.Контрагенты
Такой подход кажется логичным, но он скрывает две серьезные проблемы:
Во-первых, производительность. Когда мы не указываем конкретные виды субконто в параметрах виртуальной таблицы, СУБД вынуждена анализировать все записи регистра. Использование ГДЕ ... ССЫЛКА заставляет систему выполнять дополнительные соединения с таблицами типов, что значительно замедляет запрос на больших базах.
Во-вторых, чистота данных. В типовых конфигурациях (например, Бухгалтерия предприятия 3.0) один и тот же справочник Контрагенты может использоваться в разных видах субконто. Например, это могут быть "Лизингодатели" или "Грузоотправители". Если мы просто проверяем ссылку на справочник, мы получим "лишних" контрагентов, которые проходят по учету не как основные контрагенты, а как вспомогательная аналитика. Если ваша задача — получить именно тех, по кому ведется расчет на 60 или 62 счетах, этот метод даст избыточный результат.
Для того чтобы получить максимально быстрый и точный список контрагентов, нам нужно использовать фильтрацию на уровне самой виртуальной таблицы. Проанализируем правильный шаблон запроса:
ВЫБРАТЬ РАЗЛИЧНЫЕ
ЕСТЬNULL(ХозрасчетныйОстаткиИОбороты.Субконто1, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) КАК Контрагент
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , , &ВидыСубконто, ) КАК ХозрасчетныйОстаткиИОбороты
ГДЕ
НЕ ХозрасчетныйОстаткиИОбороты.Субконто1 IS NULL
В параметре &ВидыСубконто мы должны передать конкретную ссылку на предопределенный элемент плана видов характеристик. Рассмотрим, как подготовить этот параметр в коде 1С:
Запрос = Новый Запрос;
Запрос.Текст = "...(текст запроса выше)...";
Запрос.УстановитьПараметр("НачалоПериода", НачалоГода(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецГода(ТекущаяДата()));
// Указываем конкретный вид аналитики
Запрос.УстановитьПараметр("ВидыСубконто", ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
Результат = Запрос.Выполнить();
Выясним основные преимущества использования параметра Виды субконто:
Субконто1, потому что это единственный переданный вид субконто в параметре.ОБЪЕДИНИТЬ и ручным перебором полей Субконто1...3.Важное примечание: Если вам нужно получить контрагентов только по определенным счетам (например, только расчеты с поставщиками и покупателями), всегда добавляйте фильтр в параметр Условие счета. Это еще сильнее ускорит выполнение запроса, так как система не будет просматривать счета учета денежных средств или производственные счета, даже если на них случайно затесалось субконто контрагентов.
Используя этот подход, мы получаем чистый программный код, который легко поддерживать и который работает максимально эффективно на любых объемах данных.