Определение типа переменной в 1С:Предприятие — одна из базовых задач, с которой сталкивается любой разработчик. Без этого невозможно корректно обработать данные, избежать ошибок выполнения или написать универсальный код. Но если в классических языках программирования для этого есть оператор typeof, то в 1С всё работает иначе.
Проблема усложняется тем, что переменные в 1С могут динамически менять тип (например, после присваивания нового значения), а некоторые объекты платформы ведут себя неочевидным образом. Эта статья поможет разобраться, как точно определить тип переменной в разных версиях 1С 8.3 и 1С 8.2, включая нюансы работы с Неопределено, Null и сложными типами.
Почему важно знать тип переменной в 1С
На первый взгляд, определение типа может показаться тривиальной задачей. Однако в 1С это критично по нескольким причинам:
- 🔹 Ошибки выполнения: попытка вызвать метод несуществующего типа (например,
Строка.Количество()для строки) приведёт к падению программы. - 🔹 Условная логика: часто код ветвится в зависимости от типа данных (например, обработка массива vs. одиночного значения).
- 🔹 Отладка: при поиске багов знание реального типа переменной помогает быстрее локализовать проблему.
- 🔹 Работа с API: многие методы платформы (например,
ЗначениеВСтрокуВнутреннее()) ведут себя по-разному для разных типов.
Особенно актуально это для динамически типизированных переменных, когда одна и та же переменная может хранить то число, то строку, то объект справочника. Без проверки типа такие конструкции становятся источником трудноуловимых багов.
Способ 1: Функция ТипЗнч() — базовый метод
Самый простой и универсальный способ — использование встроенной функции ТипЗнч(). Она возвращает строку с именем типа переменной на русском языке. Синтаксис:
ТипПеременной = ТипЗнч(Переменная);
Примеры работы:
| Переменная | Результат ТипЗнч() |
|---|---|
123 | "Число" |
"Привет" | "Строка" |
Истина | "Булево" |
Неопределено | "Неопределено" |
Объект СправочникСсылка.Номенклатура | "СправочникСсылка.Номенклатура" |
⚠️ Внимание: Функция ТипЗнч() возвращает локализованные названия типов. Это означает, что на английской версии платформы вместо "Строка" вы получите "String". Если ваш код должен работать в разных языковых конфигурациях, используйте сравнение через НСтр():
Если НСтр("ru = 'Строка'") = ТипЗнч(Переменная) Тогда
// Обработка строки
КонецЕсли;
Для проверки типа объекта метаданных (справочников, документов) удобнее использовать конструкцию ТипЗнч(Переменная) LIKE "%СправочникСсылка%" — это покрывает все виды справочников без привязки к конкретному имени.
Способ 2: Оператор Вид() для сложных типов
Функция ТипЗнч() хорошо работает с примитивными типами, но для объектов платформы (справочников, документов, регистров) часто требуется более детальная информация. Здесь помогает метод Вид(), который возвращает метод-конструктор объекта.
Примеры:
Ссылка = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1");
Сообщить(Ссылка.Вид()); // Выведет: СправочникСсылка.Номенклатура
- 📌 Для документов:
ДокументСсылка.ЗаказПокупателя - 📌 Для регистров накопления:
РегистрНакопленияМенеджер.ОстаткиТоваров - 📌 Для перечислений:
ПеречислениеСсылка.ВидыНоменклатуры
🔹 Ключевое отличие от ТипЗнч(): Вид() возвращает не просто строку с типом, а полное имя конструктора, что позволяет точно идентифицировать объект даже в наследственных иерархиях.
Чем отличается ТипЗнч() от Вид()?
ТипЗнч() возвращает обобщённое название типа (например, "СправочникСсылка"), тогда как Вид() — конкретный конструктор (например, "СправочникСсылка.Номенклатура"). Это важно для объектов с одинаковой базовой природой, но разным назначением (например, разные справочники).
Способ 3: Проверка через конструкции Тип() и ЭтотОбъект.Тип()
Для объектов конфигурации (форм, отчётов, обработок) и динамических списков удобно использовать свойство Тип() или ЭтотОбъект.Тип(). Это актуально, когда вы работаете с:
- 🖥️ Элементами управления формы (поле ввода, таблица, дерево)
- 📊 Динамическими списками и отчётами
- 📄 Объектами модуля (например,
ЭтотОбъектв модуле формы)
Примеры:
// В модуле формы
Если ЭтотОбъект.Тип() = Тип("ФормаДокумента") Тогда
Сообщить("Это форма документа!");
КонецЕсли;
// Для элемента управления
Элемент = ЭлементыФормы.ТаблицаТоваров;
Если Элемент.Тип() = Тип("ПолеТаблицы") Тогда
Элемент.ТолькоПросмотр = Истина;
КонецЕсли;
⚠️ Внимание: Свойство Тип() работает только для объектов платформы, но не для примитивных типов (чисел, строк). Для них по-прежнему нужен ТипЗнч().
Способ 4: Использование Попытка…Исключение для неявной проверки
Иногда прямой проверки типа недостаточно — например, когда переменная может быть Null или Неопределено, а вам нужно узнать, мог ли бы объект иметь определённый тип при нормальных условиях. В таких случаях помогает конструкция Попытка…Исключение.
Пример: проверка, является ли переменная документом, даже если она пустая:
Функция ЭтоДокумент(Значение)
Попытка
Возврат Значение.Выбран() <> Неопределено; // Метод существует только у документов
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции;
Преимущества метода:
- ✅ Работает для
NullиНеопределено. - ✅ Проверяет не только тип, но и наличие методов (полезно для интерфейсов).
- ✅ Обходит ограничения
ТипЗнч()для сложных объектов.
🔹 Минус: такой подход замедляет выполнение кода, поэтому не рекомендуется использовать его в циклах с большим количеством итераций.
✔ Переменная может быть Null/Неопределено
✔ Нужно проверить наличие метода, а не только тип
✔ Работаете с внешними COM-объектами или API
✔ Альтернативные методы не дают точного результата-->
Способ 5: Отладчик 1С — визуальный анализ
Если вы работаете в конфигураторе, самый надёжный способ узнать тип переменной — использовать отладчик. Это особенно полезно для:
- 🐞 Сложных выражений, где тип неочевиден.
- 🔄 Динамически изменяемых переменных.
- 📦 Объектов, возвращаемых из функций (например, результаты запросов).
Как это сделать:
- Установите точку останова на строке, где нужно проверить переменную.
- Запустите отладку (
F5или кнопка "Отладка"). - Наведите курсор на переменную — во всплывающей подсказке отобразится её текущий тип и значение.
- Или добавьте переменную в окно "Выражения" (меню "Отладка → Окна → Выражения").
🔹 Совет: В окне "Выражения" можно в реальном времени менять значения переменных и сразу видеть, как это влияет на их тип.
Отладчик — единственный способ точно узнать тип переменной в динамически изменяемом коде, где статические методы вроде ТипЗнч() могут давать неактуальные результаты.
Особенности работы с Null и Неопределено
Два самых "коварных" типа в 1С — это Null и Неопределено. Они часто становятся источником ошибок, потому что ведут себя неинтуитивно:
| Тип | ТипЗнч() | Поведение в выражениях |
|---|---|---|
Null | "Null" | Возникает при обращении к несуществующему свойству объекта или неинициализированной колонке запроса. |
Неопределено | "Неопределено" | Значение по умолчанию для неинициализированных переменных. |
🔹 Как отличить Null от Неопределено:
Если Значение = Неопределено Тогда
Сообщить("Переменная не инициализирована!");
ИначеЕсли ТипЗнч(Значение) = Тип("Null") Тогда
Сообщить("Это Null (например, отсутствует поле в запросе)!");
КонецЕсли;
⚠️ Внимание: Оператор = срабатывает для Неопределено, но не работает для Null! Чтобы проверить Null, нужно использовать ТипЗнч() или Значение Заполнено():
Если НЕ Значение Заполнено(Переменная) Тогда
// Переменная либо Null, либо Неопределено
КонецЕсли;
FAQ: Частые вопросы о типах переменных в 1С
Можно ли в 1С создать переменную с фиксированным типом, как в других языках?
Нет, 1С:Предприятие использует динамическую типизацию. Переменная может менять тип в процессе выполнения. Однако в модулях объектов (например, в модуле документа) можно объявить переменную с указанием типа через ключевое слово Перем:
Перем МояПеременная Тип Число;
Но это лишь подсказка для конфигуратора и не препятствует присваиванию значений других типов.
Почему ТипЗнч(Массив) возвращает "Массив", а не "ДинамическийМассив"?
В 1С 8.3 есть два типа массивов:
- Обычный массив (фиксированный, создаётся через
Новый Массив) —ТипЗнч()вернёт"Массив". - Динамический массив (из коллекции
Соответствиеили результата запроса) — его тип может отображаться как"ДинамическийМассив"или"Массив"в зависимости от контекста.
Чтобы точно определить, используйте:
Если ТипЗнч(Массив) = Тип("Массив") И Массив.Количество() = 0 Тогда
// Это пустой массив (возможно, динамический)
КонецЕсли;
Как узнать тип колонки в результате запроса?
Для колонок запроса ТипЗнч() вернёт "КолонкаРезультатаЗапроса", что неинформативно. Чтобы узнать реальный тип данных, используйте:
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
ТипДанных = ТипЗнч(РезультатЗапроса[0][0]); // Тип первого значения первой колонки
Если колонка может содержать Null, предварительно проверьте её на заполненность.
Почему ТипЗнч() для объекта документа возвращает "ДокументОбъект.ЗаказПокупателя", а не "ДокументСсылка"?
Это зависит от того, какой объект вы проверяете:
ДокументОбъект.XXX— это объект документа (с методамиЗаписать(),Провести()).ДокументСсылка.XXX— это ссылка на документ (с методамиПолучитьОбъект(),Выбран()).
Чтобы получить ссылку из объекта, используйте:
СсылкаНаДокумент = ДокументОбъект.Ссылка;
Можно ли сравнивать типы переменных через оператор "="?
Нет! Оператор = сравнивает значения, а не типы. Например:
Если ТипЗнч(Переменная) = "Строка" Тогда // ❌ ОШИБКА!
// Этот код не сработает, потому что "Строка" — это значение, а не тип
КонецЕсли;
Правильный вариант:
Если ТипЗнч(Переменная) = Тип("Строка") Тогда // ✅ Правильно
// ...
КонецЕсли;