Как в запросе 1С определить, что тип Субконто — Документ?

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

При работе с регистрами бухгалтерии в 1С:Предприятие 8 часто возникает задача отфильтровать данные по типу субконто. Поскольку поле Субконто имеет составной тип данных (в него могут входить справочники, документы и другие объекты), прямая проверка вроде ТИПЗНАЧЕНИЯ(Субконто) = ТИП(Документ) невозможна, так как Документ сам по себе не является конкретным типом ссылки в языке запросов.

В этой статье мы подробно разберем несколько подходов к решению этой задачи, проанализируем их эффективность и выясним, почему некоторые популярные решения могут привести к значительным тормозам системы.

Способ 1. Использование массива всех типов документов

Это один из самых надежных и правильных с точки зрения типизации способов. Мы заранее подготавливаем список всех типов документов, которые могут встречаться в системе, и передаем его в запрос как параметр. Рассмотрим, как это реализовать программно.

Сначала сформируем массив типов в коде 1С:


// Получаем типы всех документов конфигурации
МассивТиповДокументов = Документы.ТипВсеСсылки().Типы();

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстатки.Счет,
    |   ХозрасчетныйОстатки.Субконто1,
    |   ХозрасчетныйОстатки.СуммаОстаток
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Остатки КАК ХозрасчетныйОстатки
    |ГДЕ
    |   ТИПЗНАЧЕНИЯ(ХозрасчетныйОстатки.Субконто1) В (&МассивТиповДокументов)";

Запрос.УстановитьПараметр("МассивТиповДокументов", МассивТиповДокументов);
Результат = Запрос.Выполнить();

Преимущество: Этот метод работает корректно с точки зрения логики 1С и не требует изменения метаданных. Мы точно определяем, является ли объект документом, вне зависимости от его конкретного вида.

Нюанс: Если в конфигурации сотни видов документов, массив будет очень большим. В некоторых случаях это может незначительно замедлить этап разбора SQL-запроса, но для большинства задач этот способ является стандартным.

Способ 2. Проверка через Вид Субконто (Самый эффективный)

Вместо того чтобы анализировать тип самого значения, которое записано в поле Субконто, мы можем проанализировать Вид Субконто. Вид субконто — это настройка на плане счетов, которая определяет, что именно хранится в данной позиции (например, "Контрагенты" или "Документы расчетов").

Если мы знаем, что нам нужны только те субконто, которые по своей сути являются документами, мы можем проверить настройки в Плане видов характеристик (ПВХ). Рассмотрим ситуацию, когда мы заранее отобрали нужные виды субконто:


// В запросе проверяем конкретный вид субконто
"ГДЕ ХозрасчетныйОстатки.ВидСубконто1 = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.ДокументыРасчетов)"

Если видов субконто-документов много, можно добавить в План видов характеристик ВидыСубконтоХозрасчетные дополнительный реквизит типа Булево (например, ЭтоДокумент). Тогда запрос станет максимально простым и быстрым:


"ВЫБРАТЬ
|   Субконто1
|ИЗ
|   РегистрБухгалтерии.Хозрасчетный.Остатки
|ГДЕ
|   ВидСубконто1.ЭтоДокумент = ИСТИНА"

Почему это лучше? SQL-серверу гораздо проще проверить одно ссылочное поле ВидСубконто, чем выполнять сложную проверку типов в поле составного типа Субконто.

Способ 3. Проверка «через точку» на наличие реквизита (Опасный метод)

Часто разработчики используют «хитрость»: обращаются к реквизиту, который есть только у документов (например, Дата или Проведен), и проверяют результат на NULL. Разберем этот пример:


"ВЫБРАТЬ
|   Субконто3
|ИЗ
|   РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты
|ГДЕ
|   НЕ Субконто3.Проведен ЕСТЬ NULL"

Проанализируем, что происходит "под капотом". Поле Субконто имеет составной тип. Когда вы пишете Субконто3.Проведен, платформа 1С генерирует SQL-запрос, который содержит LEFT OUTER JOIN ко всем таблицам объектов, входящих в этот составной тип. Если в субконто разрешено 50 видов документов и 20 справочников, СУБД попытается соединить 70 таблиц.

Последствия:

  1. Падение производительности: Запрос может выполняться в десятки раз медленнее.
  2. Ограничения СУБД: В MS SQL Server есть лимит на количество таблиц в одном запросе (256). Если ваша конфигурация большая, такой запрос просто не выполнится с ошибкой.
  3. Неточность: У некоторых справочников тоже могут быть реквизиты Дата или Номер, что приведет к ложноположительным результатам.

Вердикт: Используйте этот метод только в небольших, "одноразовых" обработках и никогда — в высоконагруженных отчетах.

Способ 4. Динамическое формирование текста запроса

Если нам нужно отобрать данные по конкретному набору документов, мы можем сформировать условие ССЫЛКА динамически в коде. Это позволяет избежать работы с массивом типов и дает оптимизатору SQL четкое понимание, какие таблицы использовать.


ТекстУсловия = "";
Для Каждого Док Из СписокНужныхДокументов Цикл
    ИмяДокумента = Док.Имя;
    ТекстУсловия = ТекстУсловия + "ИЛИ Субконто1 ССЫЛКА Документ." + ИмяДокумента + " ";
КонецЦикла;

// Убираем первое "ИЛИ" и подставляем в основной запрос
Если ЗначениеЗаполнено(ТекстУсловия) Тогда
    ТекстУсловия = "ГДЕ (" + Сред(ТекстУсловия, 4) + ")";
КонецЕсли;

Этот подход часто используется в типовых решениях (например, в БП 3.0), когда строится сложный отчет по документам расчетов. Рассмотрим подробнее: использование оператора ССЫЛКА работает быстрее, чем проверка ТИПЗНАЧЕНИЯ, так как платформа транслирует это в эффективную проверку по полю _TypeID в базе данных.

Итоги и рекомендации

Для того чтобы эффективно определить тип субконто в запросе, придерживайтесь следующих правил:

  1. Предпочтительный вариант: Проверка через Вид Субконто. Если есть возможность добавить реквизит-флаг в ПВХ ВидыСубконтоХозрасчетные — это идеальный путь.
  2. Стандартный вариант: Передача Документы.ТипВсеСсылки().Типы() в параметр запроса и использование оператора В. Это безопасно и читаемо.
  3. Оптимизированный вариант: Динамическое построение текста запроса с операторами ССЫЛКА, если список документов ограничен.
  4. Запрещенный вариант: Обращение через точку к реквизитам Дата, Проведен, Номер для полей составного типа в больших запросах.

Помните, что работа с составными типами в регистрах бухгалтерии требует особого внимания к производительности. Чем меньше "соединений" (джойнов) создаст платформа при генерации SQL-кода, тем быстрее ваш пользователь получит результат. Для отладки и проверки таких конструкций подойдёт консоль запросов для 1С.

← На главную