Разработка и Конфигурация · 10 мин
Что такое кортеж в 1С и как его использовать
Кортеж в 1С: что это такое, где применяется в запросах, синтаксис конструкции В (&Параметр), сравнение с массивом и типичные ошибки разработчиков.
Кортеж в 1С — это упорядоченный набор значений, перечисленных в круглых скобках и используемый преимущественно в языке запросов. В отличие от массива или структуры, кортеж не является самостоятельным типом данных встроенного языка: это синтаксическая конструкция, которая позволяет сравнивать сразу несколько полей с несколькими значениями одним условием.
Чаще всего кортежи встречаются в операторе В при фильтрации данных по составному ключу — например, когда нужно отобрать строки по паре «Номенклатура + Характеристика» или по комбинации «Организация + Склад». Без кортежей такое условие приходилось бы разворачивать в длинную цепочку логических связок И и ИЛИ, что ухудшает читаемость и производительность запроса.
Термин пришёл из теории реляционных баз данных, где кортеж означает строку таблицы — упорядоченный набор значений атрибутов. В 1С понятие сужено: кортеж здесь — именно список выражений в скобках внутри запроса, а не универсальная структура данных, как в Python или SQL-сервере.
Где именно в 1С применяются кортежи
Основная область применения — язык запросов 1С. Кортежи поддерживаются в условии В, в том числе с вложенными запросами и временными таблицами. Типовой сценарий: есть таблица значений с двумя колонками (например, товар и склад), и нужно отобрать из регистра только те строки, где совпадают оба поля одновременно.
Вторая область — виртуальные таблицы регистров. Параметры виртуальных таблиц, такие как условие отбора, также принимают выражения с кортежами, что позволяет сократить объём выбираемых данных ещё на стороне СУБД.
Во встроенном языке 1С (в модуле, вне запроса) кортежей нет. Там аналогичные задачи решаются структурой, массивом или таблицей значений. Путаница между этими понятиями — частая ошибка начинающих разработчиков, поэтому важно сразу разграничить контексты.
Синтаксис кортежа в запросе
Базовая форма записи выглядит так: слева от оператора В указывается кортеж из полей выборки, справа — вложенный запрос или параметр, возвращающий набор кортежей с таким же числом элементов.
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.Склад,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ГДЕ
(Остатки.Номенклатура, Остатки.Склад) В (&ТаблицаОтбора)
Параметр &ТаблицаОтбора в этом примере — таблица значений с двумя колонками соответствующих типов. Порядок колонок должен совпадать с порядком полей в кортеже слева, иначе сравнение будет некорректным или запрос завершится ошибкой.
Допустим и вариант с вложенным запросом вместо параметра: ГДЕ (Товары.Номенклатура, Товары.Склад) В (ВЫБРАТЬ Т.Номенклатура, Т.Склад ИЗ ...). Это удобно, когда набор ключей формируется динамически из других данных базы.
ГДЕ (Остатки.Номенклатура, Остатки.Склад) В (&ТаблицаОтбора)Как передать кортежи через параметр запроса
Пошаговая передача отбора по составному ключу из кода выглядит следующим образом. Сначала создаётся таблица значений, в неё добавляются колонки с типами, совместимыми с типами полей запроса. Затем таблица заполняется строками — каждая строка это один кортеж-ключ. После этого таблица передаётся в параметр запроса.
ТаблицаОтбора = Новый ТаблицаЗначений;
ТаблицаОтбора.Колонки.Добавить("Номенклатура");
ТаблицаОтбора.Колонки.Добавить("Склад");
НоваяСтрока = ТаблицаОтбора.Добавить();
НоваяСтрока.Номенклатура = Товар;
НоваяСтрока.Склад = Склад;
Запрос = Новый Запрос;
Запрос.Текст = "..."; // текст с условием В (&ТаблицаОтбора)
Запрос.УстановитьПараметр("ТаблицаОтбора", ТаблицаОтбора);
Важный нюанс: имена колонок таблицы значений не обязаны совпадать с именами полей в кортеже — платформа сопоставляет их по позиции. Однако для сопровождения кода лучше давать колонкам те же имена, что и полям запроса: это снижает риск ошибки при доработках.
- 1Создайте таблицу значений с колонками под каждый элемент кортежа
- 2Заполните таблицу строками — каждая строка это один набор ключей
- 3Напишите запрос с условием (Поле1, Поле2) В (&Параметр)
- 4Передайте таблицу через УстановитьПараметр
- 5Выполните запрос и проверьте, что отобраны только нужные комбинации
Кортеж против соединения и условий И/ИЛИ
Одну и ту же задачу отбора по составному ключу можно решить тремя способами: кортежем, соединением с временной таблицей и развёрнутым условием через И/ИЛИ. У каждого варианта есть границы применимости.
| Подход | Когда подходит | Ограничения |
|---|---|---|
| Кортеж в условии В | Небольшое число полей ключа, отбор по готовой таблице значений | Не все СУБД одинаково оптимизируют такое условие |
| Соединение с временной таблицей | Большие объёмы ключей, нужны дополнительные поля из таблицы отбора | Больше кода, нужно явно помещать таблицу во временную |
| Цепочка И/ИЛИ | Два-три фиксированных значения, известных заранее | Нечитаемо при росте числа комбинаций, нельзя передать параметром |
На практике при большом числе строк в таблице отбора соединение с временной таблицей часто работает стабильнее, потому что планировщик СУБД получает больше информации для построения плана. Кортеж удобнее для компактных запросов и умеренных объёмов данных.
Сравнение вариантов
Короткий и читаемый код; подходит для отбора по составному ключу из таблицы значений. Ограничение — оптимизация зависит от СУБД.
Предсказуемая производительность на больших объёмах; требует больше кода и явного индексирования временной таблицы.
Просто для пары фиксированных значений; не масштабируется и не принимает параметры-таблицы.
Типичные ошибки при работе с кортежами
Самая распространённая ошибка — несовпадение числа или порядка элементов в левом и правом кортежах. Если слева указано (Номенклатура, Склад), а таблица отбора содержит колонки в порядке (Склад, Номенклатура), запрос либо не выполнится из-за несовместимости типов, либо, что опаснее, вернёт пустой или неверный результат без явной ошибки.
Вторая ошибка — попытка использовать кортеж вне запроса, во встроенном языке. Конструкция вида Ключ = (Товар, Склад) в модуле не скомпилируется: в языке нет такого типа. Для составных ключей в коде используют структуру или конкатенацию строковых представлений значений.
Третья проблема — NULL в элементах кортежа. Если одно из полей содержит NULL, сравнение кортежей может дать неочевидный результат: строка не попадёт в выборку, хотя визуально значения кажутся совпадающими. Перед отбором стоит исключить NULL через ЕСТЬNULL или явно обработать такие случаи.
Производительность и ограничения
Кортежное сравнение транслируется платформой в SQL-выражение, и качество этого преобразования зависит от используемой СУБД. На одних базах условие вида (a, b) IN (...) эффективно использует составной индекс, на других планировщик может выбрать полное сканирование. Поэтому для критичных по скорости запросов результат стоит проверять на реальных объёмах данных.
Если поля кортежа входят в составной индекс таблицы в том же порядке, вероятность использования индекса выше. При проектировании собственных регистров имеет смысл учитывать, по каким комбинациям измерений чаще всего строятся отборы.
Ограничение по числу элементов кортежа платформа формально не афиширует, но на практике кортежи длиннее трёх-четырёх полей встречаются редко: с ростом длины ключа читаемость падает, и задача естественнее решается соединением с временной таблицей.
Как проверить корректность отбора
После написания запроса с кортежем полезно выполнить контрольную проверку: выбрать те же данные альтернативным способом (например, соединением) и сравнить число строк и итоговые суммы. Совпадение результатов — признак того, что порядок полей и типы заданы верно.
Дополнительно стоит проверить крайние случаи: пустая таблица отбора (запрос должен вернуть ноль строк, а не все строки), строки с NULL в ключевых полях, дубли в таблице отбора (они не должны задваивать результат при использовании В).
Как проверить результат
Совпадает с результатом альтернативного запроса через соединение
Строк больше или меньше — проверяйте порядок полей и типы колонок
Запрос возвращает ноль строк
Возвращаются все строки или ошибка выполнения
Строки обработаны осознанно через ЕСТЬNULL или исключены
Строки молча пропадают из выборки
FAQ: частые вопросы о кортежах в 1С
Кортеж — это отдельный тип данных в 1С?
Нет. Во встроенном языке 1С типа «кортеж» не существует. Это синтаксическая конструкция языка запросов — список выражений в круглых скобках. Для составных значений в коде используются структура, массив или таблица значений.
Чем кортеж отличается от массива в запросе?
Массив в условии В проверяет вхождение одного поля в список значений. Кортеж сравнивает сразу несколько полей с наборами значений: совпадение засчитывается только когда совпали все элементы пары одновременно.
Можно ли передать кортежи массивом, а не таблицей значений?
Нет. Для условия с кортежем параметр должен содержать набор многоколоночных строк — то есть таблицу значений или вложенный запрос. Массив подходит только для отбора по одному полю.
Работают ли кортежи в СКД и динамических списках?
Да, поскольку СКД и динамические списки построены на том же языке запросов, конструкция с кортежем в тексте запроса поддерживается. В отборах СКД через пользовательские настройки кортежи напрямую не задаются — там потребуется правка текста запроса.
Почему запрос с кортежем возвращает пустой результат?
Чаще всего причины три: перепутан порядок колонок в таблице отбора относительно полей кортежа, типы колонок не совместимы с типами полей, либо в ключевых данных присутствует NULL. Проверяйте по одному фактору, начиная с порядка полей.
Что выбрать для большого объёма ключей — кортеж или соединение?
При большом числе строк отбора надёжнее соединение с проиндексированной временной таблицей: планировщик СУБД получает больше информации для оптимизации. Кортеж оставьте для компактных запросов и умеренных объёмов.
Что важно запомнить
Кортеж в 1С — конструкция языка запросов для сравнения нескольких полей с наборами значений через оператор В. Порядок полей и колонок должен совпадать, NULL требует явной обработки, а для больших объёмов отбора альтернативой служит соединение с временной таблицей.