Работа с регистром бухгалтерии в 1С — одна из самых ресурсоемких задач для системы. Часто программисты сталкиваются с ситуацией, когда фильтрация в параметрах виртуальной таблицы ДвиженияССубконто работает некорректно или запрос выполняется слишком долго. Разберем на конкретном примере, как правильно исключить определенную номенклатуру из результатов запроса и почему стандартные подходы могут "тормозить" систему.
Рассмотрим ситуацию: нам нужно вывести документы списания и суммы, исключив при этом определенные позиции номенклатуры (например, "Дизтопливо" и "Регуляр-92"). Начинающий разработчик может написать условие прямо в параметрах виртуальной таблицы, используя обращение к наименованию через точку:
РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
&НачалоПериода,
&КонецПериода,
СубконтоКт1.Наименование <> "Дизтопливо" И СубконтоКт1.Наименование <> "Регуляр-92",
,
) КАК ХозрасчетныйДвиженияССубконто
Такой подход содержит сразу две критические ошибки. Во-первых, сравнение по строковому наименованию в запросах крайне неэффективно. Во-вторых, обращение через точку к полю составного типа (которым является Субконто) заставляет СУБД выполнять множественные соединения (LEFT JOIN) со всеми таблицами, которые могут входить в этот вид субконто. Если в вашем плане видов характеристик десятки типов, SQL-запрос превращается в "монстра", который обрабатывается крайне медленно.
Первое правило оптимизации: никогда не сравнивайте данные по наименованию, если можно использовать ссылку. Проанализируем, как это сделать правильно. Сначала необходимо найти нужные элементы справочника в коде 1С, поместить их в массив или параметры, и уже их передавать в запрос.
Важный момент: если вы используете отрицание <>, убедитесь, что логика учитывает пустые значения. Но самое главное — передавайте ссылки.
// В коде 1С:
СписокИсключений = Новый Массив;
СписокИсключений.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Дизтопливо"));
СписокИсключений.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Регуляр-92"));
Запрос.УстановитьПараметр("СписокИсключений", СписокИсключений);
Это самый важный шаг для ускорения работы виртуальной таблицы ДвиженияССубконто. Поскольку поле Субконто составное, платформе нужно подсказать, данные какого именно типа мы ищем. Если мы добавим условие по ВидСубконто, система поймет, что обращаться нужно только к таблице справочника Номенклатура, игнорируя контрагентов, статьи затрат и прочее.
Посмотрим, как изменится условие в параметрах виртуальной таблицы:
(ВидСубконтоКт1 = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура)
И НЕ СубконтоКт1 В (&СписокИсключений))
Проанализируем ситуацию: когда мы указываем ВидСубконтоКт1, SQL-оптимизатор может эффективно использовать индексы. Без этого условия запрос может сканировать огромные объемы данных, что и вызывает долгое "раздумье", о котором упоминалось в обсуждении.
Выясним причину, по которой фильтрация в секции ГДЕ работает медленнее, чем в параметрах самой таблицы. Разберем механизм работы платформы:
Рекомендация: Всегда старайтесь максимально ограничивать выборку именно в параметрах виртуальной таблицы (первый параметр — условие счета, третий параметр — условие субконто).
Рассмотрим еще несколько профессиональных приемов, которые помогут сделать ваш запрос "неубиваемым":
СубконтоКт1 НЕ В (ВЫБРАТЬ Ссылка ИЗ ВТ_Исключения).Субконто1, Субконто2 и т.д. — это порядковые номера на конкретном счете. Если на одном счете номенклатура — это первое субконто, а на другом — второе, ваш запрос по СубконтоКт1 пропустит данные по второму счету. В таких случаях нужно либо жестко ограничивать список счетов в первом параметре таблицы, либо использовать более сложную логику проверки вида субконто.Соберем все рекомендации вместе. Наш запрос должен выглядеть примерно так:
ВЫБРАТЬ
ХозрасчетныйДвиженияССубконто.Регистратор КАК ДокументСписания,
ХозрасчетныйДвиженияССубконто.Сумма КАК СуммаСписания
ИЗ
РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
&НачалоПериода,
&КонецПериода,
ВидСубконтоКт1 = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура)
И НЕ СубконтоКт1 В (&СписокИсключений),
,
) КАК ХозрасчетныйДвиженияССубконто
Важные моменты: мы использовали ЗНАЧЕНИЕ(...) для указания типа, передали список ссылок через параметр и поместили всё это внутрь параметров виртуальной таблицы. Это обеспечит максимальную скорость выполнения и корректность результата даже на очень больших базах данных.