Разработка и Конфигурация · 12 мин
Как обратиться к соответствию в 1С: практическое руководство
Как создать соответствие в 1С, обратиться к элементу по ключу, обойти коллекцию в цикле, проверить наличие ключа. Примеры кода, типичные ошибки и отличия от структуры.
Соответствие в 1С — это универсальная коллекция пар «ключ — значение», где каждый ключ уникален. Разработчики используют её для кэширования данных, быстрого поиска элементов по произвольному ключу, передачи параметров между процедурами и построения сложных структур данных. В отличие от массива, доступ к элементу соответствия не требует перебора: значение извлекается напрямую по ключу.
Обращение к соответствию выполняется через квадратные скобки или метод Получить(), а создание — через конструктор Новый Соответствие. Главная тонкость: при обращении к несуществующему ключу коллекция не вызывает ошибку, а возвращает Неопределено. Это одновременно удобно и опасно: логическая ошибка может долго оставаться незамеченной.
Материал рассчитан на разработчиков и продвинутых пользователей, которые дорабатывают конфигурации или пишут внешние обработки. Разобраны создание коллекции, чтение и запись значений, обход в цикле, проверка наличия ключа, сравнение со структурой и типичные ошибки. Примеры кода работают на любой типовой конфигурации на управляемых формах.
Что такое соответствие и когда его применять
Соответствие — объект встроенного языка 1С, хранящий пары «ключ — значение». Ключом может быть значение любого типа: строка, число, ссылка на справочник или документ, дата. Значением — тоже любой тип, включая другие коллекции, что позволяет строить вложенные структуры данных.
Типичные сценарии применения: кэш уже найденных ссылок, чтобы не выполнять повторные запросы к базе; накопление итогов по контрагентам или номенклатуре в цикле; передача набора именованных параметров между функциями; сопоставление кодов из внешней системы со ссылками 1С при обмене данными.
Выбирать соответствие стоит, когда поиск идёт по произвольному ключу, а не по числовому индексу, и когда важна уникальность ключей. Если нужен просто упорядоченный список значений — достаточно массива, если набор полей с фиксированными именами — удобнее структура.
Создание соответствия и добавление элементов
Коллекция создаётся конструктором без параметров. Заполнение выполняется методом Вставить() или присваиванием через квадратные скобки — оба способа равнозначны:
КэшКонтрагентов = Новый Соответствие;
// Два равнозначных способа добавить элемент
КэшКонтрагентов.Вставить("ИНН7701234567", КонтрагентСсылка);
КэшКонтрагентов["ИНН7701234567"] = КонтрагентСсылка;
При повторной вставке существующего ключа старое значение без предупреждения заменяется новым. Это стандартное поведение, но оно становится источником ошибок, если ключ формируется динамически и случайно совпадает с уже добавленным. Перед вставкой в ответственных местах проверяйте наличие ключа.
Для удаления элемента используется метод Удалить(Ключ), для полной очистки — Очистить(). Количество элементов возвращает метод Количество():
КэшКонтрагентов.Удалить("ИНН7701234567");
Если КэшКонтрагентов.Количество() = 0 Тогда
// кэш пуст
КонецЕсли;
Как обратиться к элементу по ключу
Основная операция — чтение значения по ключу. Есть два синтаксиса, и они ведут себя одинаково при отсутствующем ключе: оба возвращают Неопределено, ошибки не возникает:
// Вариант 1: квадратные скобки
Ссылка = КэшКонтрагентов["ИНН7701234567"];
// Вариант 2: метод Получить()
Ссылка = КэшКонтрагентов.Получить("ИНН7701234567");
// Обязательная проверка результата
Если Ссылка = Неопределено Тогда
// ключа в соответствии нет — ищем в базе или обрабатываем иначе
КонецЕсли;
Метод Получить() предпочтительнее в двух случаях. Первый — когда ключ хранится в переменной и код должен читаться однозначно. Второй — когда соответствие вложено в другую коллекцию и цепочка обращений через скобки становится громоздкой. Функциональной разницы между способами нет, выбор — вопрос читаемости кода.
Критически важно: результат обращения всегда проверяйте на Неопределено до использования. Вызов метода или обращение к свойству у Неопределено вызовет ошибку выполнения и прервёт обработку. Это самая частая причина падения кода, работающего с соответствиями.
Проверка наличия ключа перед обращением
Явной проверки «существует ли ключ» в соответствии нет — отдельного метода Найти() или ЕстьКлюч() у этой коллекции не предусмотрено. Проверка выполняется через получение значения и сравнение с Неопределено:
Значение = КэшКонтрагентов.Получить(ИскомыйКлюч);
Если Значение = Неопределено Тогда
// ключа нет, либо по ключу записано Неопределено
Иначе
// ключ найден, работаем со значением
КонецЕсли;
У подхода есть ограничение: невозможно отличить отсутствующий ключ от ключа, по которому записано Неопределено. Если для логики это различие принципиально, не храните Неопределено в качестве значений — используйте признак-структуру или пустую строку с отдельной обработкой.
Для ключей-ссылок полезен приём с типизацией результата: после получения значения проверяйте его тип через ТипЗнч(), если в соответствии могут оказаться данные разных видов. Это защищает от ошибок при последующих обращениях к реквизитам.
Обход соответствия в цикле
Перебор всех элементов выполняется циклом Для Каждого. Каждая итерация возвращает объект типа КлючИЗначение с двумя свойствами — Ключ и Значение:
Для Каждого Элемент Из КэшКонтрагентов Цикл
Сообщить("Ключ: " + Элемент.Ключ
+ ", значение: " + Элемент.Значение);
КонецЦикла;
Порядок обхода соответствия не гарантирован: не стройте логику на предположении, что элементы вернутся в порядке добавления. Если порядок важен, дополнительно ведите массив ключей в нужной последовательности или используйте другую коллекцию.
Удалять элементы внутри цикла обхода нельзя — это приводит к ошибке. Если нужно очистить коллекцию по условию, сначала соберите ключи кандидатов в отдельный массив, завершите цикл, затем удаляйте по собранным ключам.
Соответствие или структура: что выбрать
Структура — близкая по смыслу коллекция, но с ограничением: ключи должны быть допустимыми идентификаторами (без пробелов, не начинаться с цифры). Зато к элементам структуры можно обращаться через точку, как к свойствам объекта, а проверка ключа выполняется методом Свойство().
| Критерий | Соответствие | Структура |
|---|---|---|
| Тип ключа | Любой, включая ссылки | Только строка-идентификатор |
| Обращение к элементу | Скобки или Получить() | Через точку или скобки |
| Проверка ключа | Сравнение с Неопределено | Метод Свойство() |
| Отсутствующий ключ | Возвращает Неопределено | Ошибка при обращении через точку |
| Типичное применение | Кэш, поиск по ссылкам и кодам | Параметры, наборы полей |
Практическое правило: если ключи — ссылки, ИНН, артикулы или любые строки произвольного формата, берите соответствие. Если это фиксированный набор именованных параметров вроде «Организация», «Период», «Склад» — структура читается лучше и защищает от опечаток в ключах на этапе выполнения.
Выбор коллекции
Ключи произвольного типа — ссылки, строки с любыми символами. Подходит для кэша и поиска. Обращение к отсутствующему ключу безопасно
Ключи — допустимые идентификаторы. Удобна для передачи параметров, обращение через точку. Обращение к отсутствующему ключу вызывает ошибку
Ключи не нужны, важен порядок и числовой индекс. Поиск значения требует перебора
Практический пример: кэш ссылок при загрузке данных
Показательная задача — загрузка файла, где контрагенты указаны ИНН, а в базе нужно найти или создать ссылки. Без кэша каждый ИНН дёргал бы запрос к базе; с соответствием поиск выполняется один раз на уникальное значение:
Кэш = Новый Соответствие;
Для Каждого СтрокаФайла Из ДанныеФайла Цикл
ИНН = СтрокаФайла.ИНН;
Контрагент = Кэш.Получить(ИНН);
Если Контрагент = Неопределено Тогда
Контрагент = НайтиКонтрагентаПоИНН(ИНН); // запрос к базе
Кэш.Вставить(ИНН, Контрагент);
КонецЕсли;
// дальше Контрагент используется в документе
КонецЦикла;
Тонкость примера: если контрагент по ИНН не найден, функция вернёт пустую ссылку, и она тоже попадёт в кэш. Это корректно — повторный поиск заведомо отсутствующего ИНН не выполняется. Но если вместо пустой ссылки возвращается Неопределено, кэш перестанет работать: каждая итерация снова пойдёт в базу, потому что проверка = Неопределено не отличит «нет в кэше» от «закэшировано Неопределено».
В кэше никогда не храните Неопределено как значение. Если результат поиска может отсутствовать, кладите в соответствие пустую ссылку или специальное значение-признак — иначе проверка на Неопределено будет считать такой ключ отсутствующим, и кэш потеряет смысл.
После отладки подобного кода полезно проверить результат: количество элементов в кэше должно совпадать с количеством уникальных ключей в исходных данных. Расхождение — признак того, что ключ формируется нестабильно, например содержит лишние пробелы или разный регистр символов.
Как проверить корректность работы
Равно числу уникальных ключей в исходных данных
Больше ожидаемого — ключи дублируются из-за пробелов или регистра
Возвращается записанное значение
Неопределено — ключ при записи и чтении формируется по-разному
Возвращается Неопределено, код обрабатывает ситуацию
Ошибка выполнения — результат не проверяется перед использованием
Ограничения и границы применения
Соответствие не сериализуется в хранилище значений напрямую во всех сценариях и не передаётся между клиентом и сервером в ряде контекстов тонкого клиента без ограничений — при передаче с сервера на клиент учитывайте требования платформы к сериализуемым типам. Для передачи между сеансами или сохранения в базу коллекцию обычно преобразуют в таблицу значений или JSON.
Ключи сравниваются по значению, но для ссылочных типов сравнение идёт по ссылке, а не по реквизитам: два разных способа получения одной ссылки дадут одинаковый ключ, а две разные ссылки на похожие объекты — разные ключи. При использовании строк в качестве ключей помните про регистр и пробелы: «А001» и «а001» — разные ключи.
В запросах соответствие использовать нельзя — туда передаются таблицы значений и массивы. Если данные накоплены в соответствии и нужны в запросе, сначала выгрузите их в таблицу значений и передайте как параметр временной таблицы.
Что важно запомнить
Обращение к соответствию — через Соответствие[Ключ] или Получить(Ключ), отсутствующий ключ возвращает Неопределено без ошибки. Результат всегда проверяйте перед использованием, не храните Неопределено как значение, не удаляйте элементы внутри цикла обхода. Для ключей-идентификаторов рассмотрите структуру, для упорядоченных списков — массив.
Частые вопросы
Что вернёт соответствие, если обратиться к несуществующему ключу?
Значение Неопределено, без ошибки выполнения. Это относится и к обращению через квадратные скобки, и к методу Получить(). Поэтому результат всегда нужно проверять перед обращением к его свойствам или методам.
Чем отличается Соответствие[Ключ] от Соответствие.Получить(Ключ)?
Функционально — ничем, оба способа возвращают значение по ключу или Неопределено. Метод Получить() часто читается лучше, когда ключ — переменная или когда соответствие вложено в другую коллекцию. Выбор определяется стилем кода.
Можно ли использовать ссылку на справочник как ключ соответствия?
Да, ссылки любых типов — допустимые ключи, это одно из главных преимуществ соответствия перед структурой. Сравнение ключей идёт по ссылке: одинаковые ссылки дают одинаковый ключ независимо от того, как они были получены.
Почему поиск по ключу-строке не находит записанное значение?
Чаще всего ключ при записи и чтении отличается: лишние пробелы, другой регистр букв, неразрывные пробелы из загруженного файла. Нормализуйте ключ перед вставкой и поиском — применяйте СокрЛП() и при необходимости ВРег() или НРег().
Как удалить часть элементов соответствия по условию?
Прямое удаление внутри цикла Для Каждого вызовет ошибку. Сначала в цикле соберите ключи кандидатов в массив, затем после завершения цикла пройдите по массиву и вызовите Удалить() для каждого ключа.
Можно ли передать соответствие с сервера на клиент?
В большинстве сценариев управляемых форм соответствие сериализуется платформой и передаётся между клиентом и сервером, но для отдельных контекстов действуют ограничения на типы значений внутри коллекции. Если возникают ошибки сериализации, преобразуйте данные в массив структур или таблицу значений.