В процессе разработки сложных конфигураций на платформе 1С:Предприятие часто возникает задача фильтрации данных по множественному набору значений, который динамически формируется в памяти. Обычное перечисление условий через И или ИЛИ становится неэффективным, когда список содержит сотни или тысячи элементов.
Передача таблицы значений прямо в параметр запроса позволяет решить эту проблему элегантно, используя мощь встроенного языка и движка базы данных. Это не только ускоряет выполнение кода, но и существенно облегчает его поддержку.
Ниже мы подробно разберем механизмы работы с такими параметрами, типы данных, которые можно использовать, и конкретные примеры синтаксиса для различных версий платформы.
Основы работы с табличными параметрами
В ранних версиях платформы передача массива данных в запрос была затруднена и требовала сложной обработки строк. Современный механизм позволяет передавать объект ТаблицаЗначений или Структуру непосредственно в качестве параметра. При этом система автоматически сопоставляет поля передаваемой таблицы с полями временной таблицы в теле запроса.
Важно понимать, что при использовании этого подхода данные не выгружаются в текстовый вид, а передаются как бинарный поток или специфическая структура данных СУБД. Это обеспечивает высокую производительность даже при работе с большими объемами информации.
Для корректной работы необходимо, чтобы имена полей в передаваемом объекте совпадали с именами полей, используемых в запросе. Регистр символов в именах полей имеет значение, если платформа настроена на чувствительность к регистру, однако в большинстве стандартных конфигураций рекомендуется придерживаться единого стиля написания.
Используйте типизированные параметры, чтобы избежать ошибок приведения типов на уровне компиляции кода.
Формирование таблицы значений для передачи
Перед тем как выполнить запрос, необходимо подготовить данные. Чаще всего для этих целей используется объект ТаблицаЗначений. Вы можете создать его программно, добавляя колонки и строки в цикле, либо скопировать данные из существующей выборки.
Рассмотрим пример создания таблицы с двумя колонками: "Номенклатура" и "Количество". Такой подход часто используется при проведении документов партии или сверке остатков.
ТаблицаПараметров = Новый ТаблицаЗначений;
ТаблицаПараметров.Колонки.Добавить("Номенклатура", ТипОписанияТипов("СправочникСсылка.Номенклатура"));
ТаблицаПараметров.Колонки.Добавить("Количество", ТипОписанияТипов("Число"));
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Товар А");
НоваяСтрока.Количество = 100;
Обратите внимание на явное указание типов колонок. Хотя платформа часто может определить тип автоматически, явная типизация ТаблицаЗначений предотвращает ошибки при вставке данных несовместимых типов.
⚠️ Внимание: Если вы передаете таблицу, созданную методом
СкопироватьКолонки, убедитесь, что в ней не осталось лишних служебных полей, которые могут конфликтовать с параметрами запроса.
Синтаксис запроса с табличным параметром
В тексте запроса параметр, принимающий таблицу, используется как источник данных в операторе ИЗ. Синтаксически это выглядит как обращение к виртуальной таблице, имя которой совпадает с именем параметра.
Вы можете соединять эту виртуальную таблицу с реальными таблицами базы данных через оператор ЛЕВОЕ СОЕДИНЕНИЕ или использовать её в условии ГДЕ через вложенный запрос. Это позволяет фильтровать основные выборки по списку из параметра.
Пример использования параметра ПараметрТаблица для выборки документов, относящихся к переданному списку контрагентов:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Документы.РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| Документы.РеализацияТоваровУслуг.Дата КАК Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Документы
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ &ПараметрТаблица КАК ТаблицаФильтра
| ПО Документы.Контрагент = ТаблицаФильтра.Контрагент";
Запрос.УстановитьПараметр("ПараметрТаблица", ТаблицаПараметров);
Результат = Запрос.Выполнить();
Использование ВНУТРЕННЕЕ СОЕДИНЕНИЕ гарантирует, что в результат попадут только те записи, которые присутствуют в обоих наборах данных. Если нужно получить все документы и пометить те, что есть в списке, используйте ЛЕВОЕ СОЕДИНЕНИЕ.
Использование Структуры вместо Таблицы
В некоторых случаях, когда требуется передать список простых значений (например, список GUID или строк), удобнее использовать объект Структура. Однако механизм работы здесь немного отличается: структура передается как параметр, но в запросе она часто раскрывается через специальные функции или требует предварительной конвертации.
Начиная с определенных версий платформы, появилась возможность передавать структуру непосредственно в параметр типа СписокЗначений или использовать её в сочетании с функцией ЗНАЧЕНИЕ. Но наиболее универсальным способом остается преобразование структуры в таблицу значений перед передачей.
Если вы работаете со списком уникальных идентификаторов, создание одноколоночной ТаблицаЗначений займет минимум ресурсов памяти и обеспечит максимальную совместимость с различными версиями сервера 1С.
Оптимизация производительности при больших объемах
При передаче десятков тысяч строк в параметр запроса важно учитывать нагрузку на сервер. Хотя механизм оптимизирован, существуют ограничения на размер пакета данных, передаваемого за один раз.
Для минимизации влияния на производительность рекомендуется:
- 🚀 Передавать только необходимые колонки, избегая включения в таблицу параметров полей с большими текстовыми данными или двоичными объектами.
- 🚀 Использовать индексацию по полям соединения, если временная таблица параметров участвует в сложных джойнах.
- 🚀 Разбивать очень большие массивы данных на пакеты, если количество строк превышает 50-100 тысяч.
Сервер 1С автоматически создает временную таблицу в базе данных для хранения переданного параметра. Если этот процесс происходит слишком часто в высоконагруженной системе, это может привести к фрагментации или росту временных файлов СУБД.
☑️ Оптимизация передачи данных
Обработка ошибок и типы данных
Одной из частых проблем является несоответствие типов данных в колонках передаваемой таблицы и полях основной выборки. Например, попытка соединить поле типа Число с полем типа Строка приведет к ошибке выполнения запроса.
Платформа 1С строго следит за типизацией. Если в параметр передается таблица, где колонка "Код" имеет тип Строка(10), а в основной таблице базы данных это поле имеет тип Строка(25), соединение все равно пройдет успешно, так как типы совместимы. Однако обратная ситуация или несовместимые примитивы вызовут сбой.
Для отладки таких ситуаций полезно выводить структуру параметра перед выполнением запроса с помощью метода ПолучитьКолонки(). Это поможет убедиться, что имена и типы совпадают с ожиданиями текста запроса.
⚠️ Внимание: Пустая таблица значений, переданная в параметр, не вызовет ошибку синтаксиса, но результат запроса может оказаться пустым при использовании внутреннего соединения. Всегда проверяйте заполненность таблицы перед вызовом
Выполнить().
Сравнение методов передачи данных
Выбор способа передачи данных зависит от конкретной задачи. Ниже приведена таблица, сравнивающая основные подходы к передаче множественных значений в запрос.
| Метод | Объем данных | Производительность | Сложность реализации |
|---|---|---|---|
| Таблица значений | Высокий (тысячи строк) | Высокая | Низкая |
| Список значений (через В) | Низкий (сотни элементов) | Средняя | Низкая |
| Временная таблица | Очень высокий | Максимальная | Высокая |
| Конкатенация строк | Средний | Низкая | Средняя |
Как видно из сравнения, Таблица значений является золотой серединой для большинства задач обработки данных в 1С. Она сочетает простоту кода и высокую скорость работы движка запросов.
Почему не стоит использовать конкатенацию строк?
Конкатенация строк для формирования списка в операторе IN приводит к переполнению буфера запроса при большом количестве элементов и уязвима для SQL-инъекций в некоторых сценариях внешней интеграции.
FAQ: Часто задаваемые вопросы
Можно ли передать таблицу значений из формы в модуль объекта?
Да, вы можете передать таблицу значений как аргумент процедуры или функции. Тип параметра должен быть объявлен как ТаблицаЗначений или Неопределено, если требуется универсальность.
Что делать, если имена полей в таблице и запросе не совпадают?
В тексте запроса вы можете использовать псевдонимы. Обращайтесь к полям параметра через алиас таблицы параметров, например: ТаблицаПараметров.СтароеИмяПоля КАК НовоеИмя.
Есть ли ограничение на количество строк в передаваемой таблице?
Технического жесткого ограничения в языке нет, однако рекомендуется не превышать 100 000 строк в одном параметре для сохранения стабильности работы сервера. Для больших объемов используйте временные таблицы на диске.
Как очистить таблицу параметров перед повторным использованием?
Используйте метод Очистить() у объекта ТаблицаЗначений. Это быстрее, чем создавать новый объект, особенно в циклах с большим количеством итераций.
Использование табличных параметров — это стандартный паттерн для эффективной пакетной обработки данных в экосистеме 1С.