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