В современной разработке конфигураций на платформе 1С:Предприятие 8 работа с большими массивами данных требует не только грамотной архитектуры, но и оптимизации запросов. Часто возникает ситуация, когда необходимо передать в запрос или хранимую процедуру сложный набор данных, который уже был отобран или сформирован программно. Именно здесь на сцену выходит механизм передачи временной таблицы как параметра.
Использование этого подхода позволяет существенно сократить количество обращений к базе данных и избежать дублирования логики фильтрации. Вместо того чтобы передавать сотни отдельных значений или формировать громоздкие условия «ИЛИ», разработчик может упаковать данные в структуру и передать их одним аргументом. Это становится особенно актуальным при работе с отчетами сложной аналитики или при реализации механизмов массовых обработок.
Однако, несмотря на очевидные преимущества, синтаксис и особенности работы с такими параметрами часто вызывают вопросы у начинающих и даже опытных программистов. Непонимание типов данных или ошибок в объявлении параметров запроса может привести к неработоспособности кода или, что хуже, к падению производительности системы. В этой статье мы детально разберем, как корректно объявить, инициализировать и использовать временную таблицу в контексте языка запросов 1С.
Основы синтаксиса и объявление параметров
Прежде чем передавать данные, необходимо правильно описать структуру ожидаемого входа. В языке запросов 1С параметр типа «Временная таблица» объявляется с указанием конкретного типа данных, который эта таблица содержит. Это может быть примитивный тип, ссылочный тип или даже составной тип. Если тип не указан или указан неверно, платформа не сможет сопоставить переданные данные с ожидаемой структурой.
Синтаксически объявление выглядит как часть текста запроса перед ключевым словом ВЫБРАТЬ. Вы должны явно указать имя параметра и его тип. Например, если вы планируете передавать список номенклатуры, типом будет СправочникСсылка.Номенклатура.
Рассмотрим базовый пример объявления. Допустим, нам нужно отобрать документы, где контрагент входит в переданный список. Мы объявляем параметр &СписокКонтрагентов как временную таблицу, содержащую ссылки на справочник.
ВЫБРАТЬ
Документ.РеализацияТоваровУслуг.Ссылка КАК Ссылка,
Документ.РеализацияТоваровУслуг.Дата КАК Дата
ИЗ
Документ.РеализацияТоваровУслуг
ГДЕ
Документ.РеализацияТоваровУслуг.Контрагент В (&СписокКонтрагентов)
Здесь ключевым моментом является конструкция В (&СписокКонтрагентов). Платформа автоматически понимает, что параметр является набором данных, и выполняет проверку вхождения значений из временной таблицы в поле запроса. Это работает аналогично оператору IN в стандартном SQL, но с учетом специфики типизации 1С.
⚠️ Внимание: Тип данных в объявлении параметра должен строго совпадать с типом данных в колонке временной таблицы, которую вы передаете из кода. Если в запросе указано
Число, а вы передаете таблицу со строками, выполнение запроса завершится ошибкой типизации.
Формирование временной таблицы в коде 1С
После того как текст запроса подготовлен, следующим шагом является создание самой структуры данных в программном коде. Для этого используется объект ТаблицаЗначений. Именно этот объект выступает в роли контейнера, который затем передается в параметр запроса. Процесс создания включает два основных этапа: определение колонок и заполнение строк.
Сначала вы создаете объект таблицы значений и добавляете в него колонки. Имя колонки в таблице значений не обязательно должно совпадать с именем поля в запросе, но тип данных должен быть совместим. Часто разработчики дают колонке имя, соответствующее типу, например, «Значение» или «Элемент», чтобы код был более читаемым.
Далее следует цикл заполнения. Вы можете наполнять таблицу данными, полученными из другого запроса, из интерфейса пользователя (например, выбранные строки в списке) или сформировать их программно. Важно следить за тем, чтобы не добавлять в таблицу значения несовместимых типов, если колонка строго типизирована.
- 📊 Создайте объект
Новый ТаблицаЗначенийдля хранения списка. - ➕ Добавьте колонку с помощью метода
Колонки.Добавить, указав имя и тип данных. - 🔄 В цикле создавайте новые строки через
ТЗ.Добавитьи заполняйте их значениями. - 🚀 Передайте заполненную таблицу значений в параметр запроса через метод
УстановитьПараметр.
Пример кода формирования параметра выглядит следующим образом. Мы создаем таблицу, добавляем колонку типа «СправочникСсылка.Контрагенты» и заполняем её конкретными элементами.
ТЗКонтрагенты = Новый ТаблицаЗначений;
ТЗКонтрагенты.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
Строка = ТЗКонтрагенты.Добавить;
Строка.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
Строка = ТЗКонтрагенты.Добавить;
Строка.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ИП Иванов");
Запрос.УстановитьПараметр("СписокКонтрагентов", ТЗКонтрагенты);
Если вы передаете пустую таблицу значений в параметр запроса с оператором В, результат выборки будет пустым. Это ожидаемое поведение логики множеств.
Использование в хранимых процедурах
Хранимые процедуры в 1С позволяют выносить сложную логику запросов на сторону сервера базы данных, что может дать прирост производительности. Однако работа с временными таблицами как параметрами в хранимых процедурах имеет свои особенности. В отличие от обычных запросов в коде, здесь требуется явное описание структуры параметра в метаданных или в тексте определения процедуры.
При создании хранимой процедуры через конфигуратор, в списке параметров необходимо выбрать тип «Временная таблица». Платформа потребует указать состав колонок этой таблицы прямо в настройках параметра. Это делает интерфейс хранимой процедуры строго типизированным и безопасным.
Внутри тела хранимой процедуры вы обращаетесь к параметру так же, как к обычной временной таблице. Вы можете использовать её в операторах ВЫБРАТЬ, ПОМЕСТИТЬ или для соединений (JOIN). Главное преимущество здесь в том, что данные не передаются туда-обратно между клиентом и сервером, а обрабатываются в одном контексте выполнения.
Однако стоит учитывать ограничения. Не все СУБД одинаково эффективно работают с передачей табличных параметров, хотя платформа 1С старается абстрагировать эти различия. При отладке хранимой процедуры с такими параметрами убедитесь, что тестовые данные соответствуют declared структуре.
Особенности компиляции хранимых процедур
При изменении структуры параметра хранимой процедуры может потребоваться полная перерегистрация объектов базы данных. Будьте осторожны при рефакторинге.
Оптимизация производительности и индексы
Использование временной таблицы в условии ГДЕ обычно является эффективным решением, но при работе с огромными объемами данных (миллионы строк) могут возникнуть нюансы. Платформа 1С при формировании плана выполнения запроса старается оптимально использовать индексы основной таблицы, по которой идет выборка.
Если временная таблица небольшая (десятки или сотни строк), оптимизатор СУБД обычно выбирает план, где основная таблица сканируется с использованием индекса, а значения из временной таблицы подставляются как константы для поиска. Это быстрый путь. Проблемы могут начаться, если временная таблица сама по себе становится большой.
В таких случаях иногда выгоднее сначала поместить временную таблицу в реальную временную таблицу базы данных (через оператор ПОМЕСТИТЬ), создать на ней индекс, и затем делать соединение. Но для стандартных сценариев передачи параметра из кода 1С дополнительная оптимизация обычно не требуется.
| Сценарий использования | Рекомендуемый подход | Ожидаемая производительность |
|---|---|---|
| Список до 100 элементов | Прямая передача в параметр | Высокая |
| Список 100 - 1000 элементов | Прямая передача в параметр | Средняя/Высокая |
| Список более 5000 элементов | Поместить во временную таблицу БД + Индекс | Зависит от индексов |
Важно также помнить о сетевом трафике. Передача большой таблицы значений от клиента к серверу занимает время. Если логика позволяет, формируйте временную таблицу непосредственно на сервере, внутри серверного вызова, чтобы минимизировать сетевые задержки.
Для списков менее 1000 элементов прямая передача Таблицы Значений как параметра является наиболее сбалансированным решением по скорости разработки и производительности.
Типичные ошибки разработчиков
При работе с этим механизмом разработчики часто наступают на одни и те же грабли. Самая распространенная ошибка — несоответствие типов. Например, попытка передать таблицу со строковыми значениями в параметр, ожидающий числа или ссылки. Платформа выдаст ошибку выполнения, которая иногда бывает неочевидной для новичка.
Другая частая проблема — использование несовместимых операторов. Временную таблицу нельзя просто так «приплюсовать» к строке или использовать в арифметических операциях без явного приведения или выбора конкретного поля. Вы должны обращаться к конкретной колонке временной таблицы, если используете её в выражениях.
Также стоит упомянуть ошибку инициализации. Если вы забыли вызвать метод УстановитьПараметр или передали туда Неопределено вместо таблицы значений, запрос не выполнится. Всегда проверяйте, что параметр действительно установлен перед вызовом Выполнить.
- ❌ Ошибка типов: Передача
СтрокавместоЧислов колонке параметра. - ❌ Отсутствие данных: Передача пустой таблицы там, где ожидается наличие записей для логики работы.
- ❌ Синтаксис: Попытка использовать имя временной таблицы без символа
&в тексте запроса.
⚠️ Внимание: Интерфейс и возможности работы с запросами могут незначительно отличаться в разных версиях платформы 1С и разных СУБД (PostgreSQL, MS SQL, Oracle). Всегда проверяйте документацию для вашей конкретной конфигурации и версии платформы.
Сравнение с альтернативными методами
Почему стоит использовать временную таблицу, а не другие методы? Давайте сравним этот подход с передачей списка значений через строку или с использованием нескольких отдельных параметров. Передача списка через строку (например, разделенного запятыми) требует последующего разбора этой строки внутри запроса или кода, что является ресурсоемкой операцией и нарушает типобезопасность.
Использование множества отдельных параметров (Параметр1, Параметр2.. ПараметрN) ограничивает количество передаваемых значений и делает код запроса громоздким и трудно поддерживаемым. Временная таблица лишена этих недостатков: она динамична по размеру и сохраняет строгую типизацию.
Единственный случай, когда временная таблица может быть избыточной — это передача одного-двух фиксированных значений. В таких случаях проще использовать обычные скалярные параметры. Но как только количество значений становится переменным, таблица становится безальтернативным лидером.
☑️ Контрольный список перед запуском
FAQ: Часто задаваемые вопросы
Можно ли передать временную таблицу в отчет через СКД?
Да, это возможно. В схеме компоновки данных вы можете создать параметр типа «Таблица значений» и связать его с набором данных. Однако настройка такого отчета требует более глубокого понимания работы СКД, чем обычный запрос.
Как передать таблицу значений из внешней обработки?
При вызове внешней обработки или печатной формы вы можете передать параметры в массиве значений. Убедитесь, что принимающая сторона ожидает именно объект ТаблицаЗначений, а не просто массив.
Влияет ли тип СУБД на скорость работы с такими параметрами?
Да, влияет. Различные СУБД по-разному реализуют передачу табличных параметров. Например, в PostgreSQL это может работать немного иначе, чем в MS SQL Server, но платформа 1С нивелирует эти различия на уровне драйверов.
Можно ли использовать временную таблицу для обновления данных?
Да, вы можете использовать временную таблицу в операторе ОБНОВИТЬ, соединяя её с целевой таблицей. Это эффективный способ массового обновления реквизитов по списку объектов.