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

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

Соответствие в 1С: как создавать, заполнять и использовать

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

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

Главное преимущество соответствия перед массивом или таблицей значений — скорость поиска. Поиск по ключу выполняется за почти постоянное время независимо от числа элементов, тогда как перебор массива в поисках нужного значения замедляется пропорционально его размеру. На больших объёмах данных разница критична: обработка, которая ищет тысячи ссылок в массиве, может работать в десятки раз дольше, чем та же логика на соответствии.

Ключом соответствия может быть значение практически любого типа: строка, число, дата, ссылка на объект базы, даже другая коллекция. Значением — тоже что угодно, включая массивы, структуры и другие соответствия, что позволяет строить многоуровневые индексы. Ниже разобраны создание коллекции, основные операции, обход в цикле, отличия от структуры и типичные ошибки.

Как создать соответствие и добавить элементы

Соответствие создаётся конструктором Новый Соответствие. Коллекция изначально пустая, количество элементов ограничено только доступной памятью. Заполнение выполняется методом Вставить(Ключ, Значение) или оператором присваивания через квадратные скобки.

Кэш = Новый Соответствие;

Кэш.Вставить("АдресСервера", "srv-01.local");

Кэш.Вставить("Таймаут", 30);

// То же самое через квадратные скобки

Кэш["Активен"] = Истина;

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

Ключи регистрозависимы: "Код" и "код" — два разных ключа. Если данные приходят из внешних источников с непредсказуемым регистром, нормализуйте ключ перед записью и чтением, например через ВРег() или НРег().

Чтение значений и проверка существования ключа

Получить значение можно двумя способами: через квадратные скобки Соответствие[Ключ] или методом Получить(Ключ). Оба возвращают Неопределено, если ключ отсутствует. Разницы в поведении между ними нет — выбор вопрос стиля, хотя Получить() часто читается нагляднее в сложных выражениях.

Таймаут = Кэш.Получить("Таймаут");

Если Таймаут = Неопределено Тогда

Таймаут = 60; // значение по умолчанию

КонецЕсли;

Главное правило безопасной работы: никогда не используйте результат чтения без проверки, если не уверены, что ключ точно существует. Обращение к свойству или методу у Неопределено вызывает исключение и прерывает выполнение кода. Типичная защита — сравнение с Неопределено сразу после чтения.

Накопление значений по ключу

Частый сценарий — подсчёт количества или суммы по категориям. Паттерн выглядит так: прочитать текущее значение, заменить Неопределено нулём, прибавить, записать обратно.

КоличествоПоСкладам = Новый Соответствие;

Для Каждого Строка Из ТаблицаТоваров Цикл

Текущее = КоличествоПоСкладам[Строка.Склад];

Если Текущее = Неопределено Тогда

Текущее = 0;

КонецЕсли;

КоличествоПоСкладам[Строка.Склад] = Текущее + Строка.Количество;

КонецЦикла;

Обход соответствия в цикле

Соответствие обходится конструкцией Для Каждого ... Из ... Цикл. Переменная цикла имеет тип КлючИЗначение и содержит два свойства: Ключ и Значение. Это единственный способ получить одновременно и ключ, и значение при переборе.

Для Каждого Элемент Из Кэш Цикл

Сообщить(Строка(Элемент.Ключ) + " = " + Строка(Элемент.Значение));

КонецЦикла;

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

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

Основные методы соответствия

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

МетодНазначениеОсобенность
Вставить(Ключ, Значение)Добавить или перезаписать паруВозвращает Истина при успехе
Получить(Ключ)Прочитать значение по ключуВернёт Неопределено, если ключа нет
Удалить(Ключ)Удалить пару по ключуНе ошибка, если ключа нет
Очистить()Удалить все элементыКоллекция остаётся рабочей
Количество()Число элементовДля пустой коллекции — 0

Метод Удалить() безопасен: попытка удалить несуществующий ключ не вызывает исключения. Это упрощает код очистки — проверка существования перед удалением не нужна.

Как организовать кэш ссылок по коду
  1. 1
    Создайте соответствие: КэшСсылок = Новый Соответствие
  2. 2
    При первом обращении к коду проверьте: Ссылка = КэшСсылок[Код]
  3. 3
    Если Ссылка = Неопределено — найдите элемент запросом или методом НайтиПоКоду()
  4. 4
    Сохраните результат: КэшСсылок[Код] = Ссылка
  5. 5
    При повторном обращении ссылка вернётся из кэша без обращения к базе

Соответствие или структура: что выбрать

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

Ключи структуры должны быть допустимыми идентификаторами: начинаться с буквы, не содержать пробелов и спецсимволов. Ключ соответствия — произвольное значение любого типа, включая ссылки и строки с пробелами. Если ключи приходят извне (коды контрагентов, артикулы, GUID из другой системы), подходит только соответствие.

Структура имеет метод Свойство("Имя", Значение), который проверяет наличие ключа и заодно читает значение — у соответствия такого аналога нет. Зато соответствие хранит любое число элементов, а структура ограничена по количеству свойств при создании через конструктор с перечислением ключей. Структура удобна как аналог «записи» с фиксированным набором полей, соответствие — как динамический словарь.

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

Соответствие

Произвольные ключи любого типа, динамическое наполнение, быстрый поиск. Нет метода проверки ключа с чтением значения за один вызов.

Структура

Ключи-идентификаторы, метод Свойство() с проверкой, удобна для фиксированного набора полей. Не подходит для ключей из внешних данных.

Таблица значений

Нужна, когда по каждому ключу хранится несколько полей или требуется сортировка и отбор. Тяжелее и медленнее для простого поиска.

Типичные сценарии применения

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

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

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

Типичные ошибки
01
Чтение без проверки на Неопределено — обращение к реквизиту несуществующего значения роняет код исключением
02
Опечатка в строковом ключе — создаётся новый элемент вместо обновления, логика молча работает неверно
03
Игнорирование регистра строковых ключей — «Код» и «код» считаются разными ключами
04
Расчёт на порядок обхода — порядок элементов в цикле не гарантирован
05
Удаление элементов внутри цикла Для Каждого — поведение перебора становится непредсказуемым

Проверка результата и отладка

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

В программной проверке опирайтесь на контрольные точки: количество элементов после заполнения должно совпадать с ожидаемым числом уникальных ключей; чтение по известному ключу должно вернуть записанное значение; чтение по заведомо отсутствующему ключу должно вернуть Неопределено, а не вызвать ошибку.

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

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

Количество() после заполнения
Норма

Равно числу уникальных ключей

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

Больше ожидаемого — вероятны дубли ключей из-за регистра или опечаток

Чтение по известному ключу
Норма

Возвращается записанное значение

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

Неопределено — ключ записан иначе или не записан вовсе

Чтение по отсутствующему ключу
Норма

Возвращается Неопределено, код продолжает работу

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

Исключение при обращении к значению — нет проверки после чтения

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

Итог

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

Соответствие — коллекция «ключ-значение» с быстрым поиском и произвольным типом ключа. Создаётся через Новый Соответствие, заполняется методом Вставить или присваиванием, читается через Получить() или скобки. Отсутствующий ключ возвращает Неопределено — всегда проверяйте результат перед использованием. Порядок обхода не гарантирован, удалять элементы внутри цикла нельзя. Для ключей из внешних данных соответствие предпочтительнее структуры.

Частые вопросы о соответствии в 1С

Можно ли использовать ссылку на объект базы как ключ соответствия?

Да, ссылки — один из самых практичных типов ключа. Сравнение ключей выполняется по значению, поэтому две переменные, содержащие ссылку на один и тот же объект, считаются одним ключом. Это удобно для накопления данных по контрагентам, складам или номенклатуре без преобразования ссылки в строку.

Чем Получить() отличается от чтения через квадратные скобки?

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

Как проверить, существует ли ключ, не читая значение?

Отдельного метода «СодержитКлюч» у соответствия нет. Стандартный приём — прочитать значение через Получить(Ключ) и сравнить с Неопределено. Ограничение подхода: если вы намеренно храните Неопределено как значение, отличить «ключа нет» от «значение равно Неопределено» невозможно — в таких случаях храните вместо Неопределено специальный маркер.

Сохраняется ли соответствие между вызовами на сервере?

Нет, если коллекция создана локально в процедуре — она живёт только в пределах вызова. Для хранения между вызовами соответствие помещают в реквизит формы (с поддержкой сериализации), в параметры сеанса через дополнительные механизмы либо пересоздают при каждом обращении. В фоновых заданиях коллекцию можно передать через параметры, если все значения сериализуемы.

Что быстрее для поиска: соответствие или таблица значений с индексом?

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

Можно ли отсортировать соответствие по ключам?

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