К статье
Практический материал

Разработка и Конфигурация · 10 мин

Что такое кортеж в 1С и как его использовать

Кортеж в 1С: что это такое, где применяется в запросах, синтаксис конструкции В (&Параметр), сравнение с массивом и типичные ошибки разработчиков.

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

Чаще всего кортежи встречаются в операторе В при фильтрации данных по составному ключу — например, когда нужно отобрать строки по паре «Номенклатура + Характеристика» или по комбинации «Организация + Склад». Без кортежей такое условие приходилось бы разворачивать в длинную цепочку логических связок И и ИЛИ, что ухудшает читаемость и производительность запроса.

Термин пришёл из теории реляционных баз данных, где кортеж означает строку таблицы — упорядоченный набор значений атрибутов. В 1С понятие сужено: кортеж здесь — именно список выражений в скобках внутри запроса, а не универсальная структура данных, как в Python или SQL-сервере.

Где именно в 1С применяются кортежи

Основная область применения — язык запросов 1С. Кортежи поддерживаются в условии В, в том числе с вложенными запросами и временными таблицами. Типовой сценарий: есть таблица значений с двумя колонками (например, товар и склад), и нужно отобрать из регистра только те строки, где совпадают оба поля одновременно.

Вторая область — виртуальные таблицы регистров. Параметры виртуальных таблиц, такие как условие отбора, также принимают выражения с кортежами, что позволяет сократить объём выбираемых данных ещё на стороне СУБД.

Во встроенном языке 1С (в модуле, вне запроса) кортежей нет. Там аналогичные задачи решаются структурой, массивом или таблицей значений. Путаница между этими понятиями — частая ошибка начинающих разработчиков, поэтому важно сразу разграничить контексты.

Синтаксис кортежа в запросе

Базовая форма записи выглядит так: слева от оператора В указывается кортеж из полей выборки, справа — вложенный запрос или параметр, возвращающий набор кортежей с таким же числом элементов.

ВЫБРАТЬ

Остатки.Номенклатура,

Остатки.Склад,

Остатки.КоличествоОстаток

ИЗ

РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ГДЕ

(Остатки.Номенклатура, Остатки.Склад) В (&ТаблицаОтбора)

Параметр &ТаблицаОтбора в этом примере — таблица значений с двумя колонками соответствующих типов. Порядок колонок должен совпадать с порядком полей в кортеже слева, иначе сравнение будет некорректным или запрос завершится ошибкой.

Допустим и вариант с вложенным запросом вместо параметра: ГДЕ (Товары.Номенклатура, Товары.Склад) В (ВЫБРАТЬ Т.Номенклатура, Т.Склад ИЗ ...). Это удобно, когда набор ключей формируется динамически из других данных базы.

bsl
ГДЕ (Остатки.Номенклатура, Остатки.Склад) В (&ТаблицаОтбора)

Как передать кортежи через параметр запроса

Пошаговая передача отбора по составному ключу из кода выглядит следующим образом. Сначала создаётся таблица значений, в неё добавляются колонки с типами, совместимыми с типами полей запроса. Затем таблица заполняется строками — каждая строка это один кортеж-ключ. После этого таблица передаётся в параметр запроса.

ТаблицаОтбора = Новый ТаблицаЗначений;

ТаблицаОтбора.Колонки.Добавить("Номенклатура");

ТаблицаОтбора.Колонки.Добавить("Склад");

НоваяСтрока = ТаблицаОтбора.Добавить();

НоваяСтрока.Номенклатура = Товар;

НоваяСтрока.Склад = Склад;

Запрос = Новый Запрос;

Запрос.Текст = "..."; // текст с условием В (&ТаблицаОтбора)

Запрос.УстановитьПараметр("ТаблицаОтбора", ТаблицаОтбора);

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

Порядок действий
  1. 1
    Создайте таблицу значений с колонками под каждый элемент кортежа
  2. 2
    Заполните таблицу строками — каждая строка это один набор ключей
  3. 3
    Напишите запрос с условием (Поле1, Поле2) В (&Параметр)
  4. 4
    Передайте таблицу через УстановитьПараметр
  5. 5
    Выполните запрос и проверьте, что отобраны только нужные комбинации

Кортеж против соединения и условий И/ИЛИ

Одну и ту же задачу отбора по составному ключу можно решить тремя способами: кортежем, соединением с временной таблицей и развёрнутым условием через И/ИЛИ. У каждого варианта есть границы применимости.

ПодходКогда подходитОграничения
Кортеж в условии ВНебольшое число полей ключа, отбор по готовой таблице значенийНе все СУБД одинаково оптимизируют такое условие
Соединение с временной таблицейБольшие объёмы ключей, нужны дополнительные поля из таблицы отбораБольше кода, нужно явно помещать таблицу во временную
Цепочка И/ИЛИДва-три фиксированных значения, известных заранееНечитаемо при росте числа комбинаций, нельзя передать параметром

На практике при большом числе строк в таблице отбора соединение с временной таблицей часто работает стабильнее, потому что планировщик СУБД получает больше информации для построения плана. Кортеж удобнее для компактных запросов и умеренных объёмов данных.

Сравнение вариантов

Кортеж в условии В

Короткий и читаемый код; подходит для отбора по составному ключу из таблицы значений. Ограничение — оптимизация зависит от СУБД.

Соединение с временной таблицей

Предсказуемая производительность на больших объёмах; требует больше кода и явного индексирования временной таблицы.

Условия И/ИЛИ

Просто для пары фиксированных значений; не масштабируется и не принимает параметры-таблицы.

Типичные ошибки при работе с кортежами

Самая распространённая ошибка — несовпадение числа или порядка элементов в левом и правом кортежах. Если слева указано (Номенклатура, Склад), а таблица отбора содержит колонки в порядке (Склад, Номенклатура), запрос либо не выполнится из-за несовместимости типов, либо, что опаснее, вернёт пустой или неверный результат без явной ошибки.

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

Третья проблема — NULL в элементах кортежа. Если одно из полей содержит NULL, сравнение кортежей может дать неочевидный результат: строка не попадёт в выборку, хотя визуально значения кажутся совпадающими. Перед отбором стоит исключить NULL через ЕСТЬNULL или явно обработать такие случаи.

Типичные ошибки
01
Разный порядок полей в кортеже и колонок в таблице отбора — запрос возвращает неверный результат без ошибки
02
Попытка использовать кортеж в коде модуля вне запроса — синтаксическая ошибка, кортеж существует только в языке запросов
03
Игнорирование NULL в полях ключа — строки теряются из выборки
04
Передача в параметр массива вместо таблицы значений — условие с кортежем не сработает

Производительность и ограничения

Кортежное сравнение транслируется платформой в SQL-выражение, и качество этого преобразования зависит от используемой СУБД. На одних базах условие вида (a, b) IN (...) эффективно использует составной индекс, на других планировщик может выбрать полное сканирование. Поэтому для критичных по скорости запросов результат стоит проверять на реальных объёмах данных.

Если поля кортежа входят в составной индекс таблицы в том же порядке, вероятность использования индекса выше. При проектировании собственных регистров имеет смысл учитывать, по каким комбинациям измерений чаще всего строятся отборы.

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

Как проверить корректность отбора

После написания запроса с кортежем полезно выполнить контрольную проверку: выбрать те же данные альтернативным способом (например, соединением) и сравнить число строк и итоговые суммы. Совпадение результатов — признак того, что порядок полей и типы заданы верно.

Дополнительно стоит проверить крайние случаи: пустая таблица отбора (запрос должен вернуть ноль строк, а не все строки), строки с NULL в ключевых полях, дубли в таблице отбора (они не должны задваивать результат при использовании В).

Контрольные точки

Как проверить результат

Число строк результата
Норма

Совпадает с результатом альтернативного запроса через соединение

Тревожный признак

Строк больше или меньше — проверяйте порядок полей и типы колонок

Пустая таблица отбора
Норма

Запрос возвращает ноль строк

Тревожный признак

Возвращаются все строки или ошибка выполнения

Поля с NULL
Норма

Строки обработаны осознанно через ЕСТЬNULL или исключены

Тревожный признак

Строки молча пропадают из выборки

FAQ: частые вопросы о кортежах в 1С

Кортеж — это отдельный тип данных в 1С?

Нет. Во встроенном языке 1С типа «кортеж» не существует. Это синтаксическая конструкция языка запросов — список выражений в круглых скобках. Для составных значений в коде используются структура, массив или таблица значений.

Чем кортеж отличается от массива в запросе?

Массив в условии В проверяет вхождение одного поля в список значений. Кортеж сравнивает сразу несколько полей с наборами значений: совпадение засчитывается только когда совпали все элементы пары одновременно.

Можно ли передать кортежи массивом, а не таблицей значений?

Нет. Для условия с кортежем параметр должен содержать набор многоколоночных строк — то есть таблицу значений или вложенный запрос. Массив подходит только для отбора по одному полю.

Работают ли кортежи в СКД и динамических списках?

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

Почему запрос с кортежем возвращает пустой результат?

Чаще всего причины три: перепутан порядок колонок в таблице отбора относительно полей кортежа, типы колонок не совместимы с типами полей, либо в ключевых данных присутствует NULL. Проверяйте по одному фактору, начиная с порядка полей.

Что выбрать для большого объёма ключей — кортеж или соединение?

При большом числе строк отбора надёжнее соединение с проиндексированной временной таблицей: планировщик СУБД получает больше информации для оптимизации. Кортеж оставьте для компактных запросов и умеренных объёмов.

Итог

Что важно запомнить

Кортеж в 1С — конструкция языка запросов для сравнения нескольких полей с наборами значений через оператор В. Порядок полей и колонок должен совпадать, NULL требует явной обработки, а для больших объёмов отбора альтернативой служит соединение с временной таблицей.