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