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