К статье
Практический материал

Разработка и Конфигурация · 11 мин

Какие типы данных существуют в 1С

Какие типы данных существуют в 1С: примитивные, ссылочные, составные и универсальные. Таблицы, примеры кода, проверка типов и типичные ошибки разработчиков.

Система типов — фундамент платформы 1С:Предприятие. Каждый реквизит справочника, поле документа, параметр запроса и переменная встроенного языка имеют определённый тип, и от правильного выбора типа зависят корректность хранения данных, скорость запросов и отсутствие ошибок преобразования.

Типы в 1С принято делить на несколько больших групп: примитивные (число, строка, дата, булево), ссылочные (ссылки на объекты базы данных), универсальные (значения коллекций и специальные типы вроде УникальныйИдентификатор), а также типы, формируемые конфигурацией — перечисления, объекты, наборы записей. Понимание этой классификации нужно и разработчику, пишущему код, и консультанту, который настраивает реквизиты в конфигураторе.

Отдельная особенность платформы — составные типы: один реквизит может хранить значения нескольких типов, например ссылку на любой справочник или документ. Это удобно для универсальных механизмов, но требует аккуратности при написании запросов и проверке значений.

Примитивные типы: Число, Строка, Дата, Булево

Примитивные типы — базовые строительные блоки. Число используется для количеств, сумм, коэффициентов. При определении реквизита в конфигураторе задаются длина числа и точность (количество знаков после запятой), а также признак неотрицательности. Для денежных сумм принято задавать точность 2 знака, для количеств товаров — обычно 3, для курсов валют и коэффициентов — больше, чтобы не терять точность при пересчётах.

Строка бывает фиксированной и переменной длины. Строка переменной длины с ограничением (например, 150 символов) — стандартный выбор для наименований. Строка неограниченной длины хранится иначе: в запросах по такому полю нельзя выполнять сравнение и соединение без приведения типа через ВЫРАЗИТЬ, поэтому неограниченную длину назначают только там, где она действительно нужна (многострочные комментарии, описания).

Дата может содержать только дату, только время или дату со временем с точностью до секунды. Для документов используется состав «дата и время», что позволяет упорядочивать документы внутри дня. Тип Булево принимает значения Истина или Ложь и применяется для флагов: «Проведён», «Активен», «ИспользоватьСкидку».

Ссылочные типы: ссылки на объекты базы данных

Ссылочные типы обеспечивают связность данных: реквизит хранит не текст или число, а ссылку на конкретный объект. К ним относятся СправочникСсылка, ДокументСсылка, ПеречислениеСсылка, ПланВидовХарактеристикСсылка, ПланСчетовСсылка, ПланВидовРасчетаСсылка, БизнесПроцессСсылка, ЗадачаСсылка и ссылки на планы обмена.

Ключевое свойство ссылочных типов — контроль целостности. Пока на объект ссылаются другие данные, удалить его окончательно нельзя без специальной обработки удаления помеченных объектов. Ссылка однозначно идентифицирует объект за счёт внутреннего уникального идентификатора, поэтому переименование элемента справочника не ломает связи в документах.

Для каждого ссылочного типа существуют парные объектные типы: СправочникОбъект, ДокументОбъект и т.д. Ссылка — это лёгкий идентификатор, объект — полноценная структура данных, загруженная в память для чтения и изменения. Частая ошибка начинающих — вызывать ПолучитьОбъект() в цикле там, где достаточно обратиться к реквизитам через точку от ссылки или выбрать данные запросом.

Универсальные и специальные типы

К универсальным относятся значения, которые не привязаны к конкретным данным конфигурации. Неопределено — значение переменной, которой ничего не присвоено, или результат функции без возврата значения. Null приходит из запросов при левом соединении, когда соответствия не найдено: сравнивать его нужно через ЕСТЬ NULL в запросе или проверку Значение = Null в коде, причём Null не равен ни пустой ссылке, ни Неопределено.

Тип и ОписаниеТипов позволяют работать с типами как со значениями: проверять тип переменной (ТипЗнч(Значение) = Тип("Число")), динамически строить описания реквизитов для программно создаваемых таблиц значений и форм. УникальныйИдентификатор — 128-битный идентификатор объекта, используется для синхронизации данных между базами и обмена с внешними системами.

Коллекции значений — Массив, Структура, Соответствие, СписокЗначений, ТаблицаЗначений, ДеревоЗначений — формально тоже типы, хотя и не назначаются реквизитам объектов. Они применяются для промежуточной обработки данных в памяти: таблица значений — стандартный инструмент для выгрузки результатов запроса и передачи табличных данных между процедурами.

Типы объектов конфигурации и работы с данными

Помимо ссылок и объектов, платформа предоставляет типы для непосредственной работы с данными: РегистрСведенийНаборЗаписей, РегистрНакопленияМенеджерЗаписи, Запрос, ПостроительЗапроса, СхемаКомпоновкиДанных и другие. Эти типы не хранятся в реквизитах, но постоянно встречаются в коде модулей.

Отдельно стоит упомянуть ХранилищеЗначения — тип реквизита для хранения произвольных данных в сжатом виде: картинок, файлов, сериализованных таблиц значений. Данные из хранилища извлекаются методом Получить() и помещаются конструктором Новый ХранилищеЗначения(Значение). Злоупотреблять этим типом не стоит: содержимое хранилища недоступно для запросов и отчётов.

Для обмена и интеграции используются типы ДвоичныеДанные, Картинка, ФорматированныйДокумент, ТабличныйДокумент. Табличный документ — универсальный тип печатных форм и макетов, с ним работают практически все механизмы вывода отчётов на печать.

Составные типы реквизитов

В конфигураторе реквизиту можно назначить несколько типов одновременно — например, «Партия» в документе списания может быть ссылкой на документ поступления или на документ производства. Это и есть составной тип. Предельный случай — тип «ЛюбаяСсылка», объединяющий ссылки на все объекты конфигурации; он применяется в универсальных механизмах вроде подсистемы присоединённых файлов.

Платформа также поддерживает определяемые типы — объекты метаданных, задающие составной тип один раз для переиспользования в разных объектах. Если позже потребуется расширить состав (например, добавить новый вид документа-основания), достаточно изменить определяемый тип, а не десятки реквизитов.

Цена гибкости — усложнение запросов. Поле составного типа нельзя напрямую соединять с таблицей конкретного справочника без приведения типа, а обращение к реквизиту «через точку» по составному полю порождает неявные соединения со всеми таблицами состава и резко замедляет запрос.

bsl
// Приведение составного типа в запросе
ВЫБРАТЬ
	ВЫРАЗИТЬ(Реализация.Партия КАК Документ.ПоступлениеТоваров).Номер КАК НомерПартии
ИЗ
	Документ.РеализацияТоваров КАК Реализация

Как выбрать тип реквизита и проверить тип в коде

Выбор типа начинается с вопроса: что будет храниться и как значение будет использоваться. Если значение выбирается из фиксированного короткого списка, который редко меняется, — подходит перечисление. Если список ведёт пользователь и он растёт — справочник. Если нужны только отображение и фильтрация по тексту — строка ограниченной длины. Суммы и количества — число с продуманной точностью, флаги — булево.

Порядок выбора типа реквизита
  1. 1
    Определите природу значения: примитив, ссылка на объект или произвольные данные
  2. 2
    Для числа задайте длину и точность с запасом под будущие расчёты
  3. 3
    Для строки выберите ограниченную длину, если не нужен неограниченный текст
  4. 4
    Для ссылочного типа проверьте, не нужен ли составной тип или определяемый тип
  5. 5
    Обновите конфигурацию базы данных и проверьте реструктуризацию на копии

В коде тип проверяется функцией ТипЗнч() в паре с функцией Тип():

Если ТипЗнч(Значение) = Тип("СправочникСсылка.Номенклатура") Тогда

// работаем как с номенклатурой

КонецЕсли;

Для проверки заполненности используйте ЗначениеЗаполнено() — она корректно обрабатывает пустые ссылки, пустые строки, нули, Неопределено и Null, избавляя от громоздких цепочек сравнений.

Типичные ошибки
01
Сравнение значения из запроса с Неопределено вместо проверки на Null — условие никогда не сработает
02
Обращение через точку к реквизиту составного поля в запросе — неявные соединения и падение производительности
03
Неограниченная длина строки у реквизита, по которому нужны отборы — невозможность сравнения в запросе без ВЫРАЗИТЬ
04
Недостаточная точность числа для курсов и коэффициентов — накопление ошибок округления в суммах
05
Вызов ПолучитьОбъект() ради чтения одного реквизита — лишняя загрузка всего объекта из базы

Проверка результата и ограничения

Контрольные точки

Как проверить результат

Реструктуризация после смены типа
Норма

Обновление проходит без ошибок, данные на месте

Тревожный признак

Предупреждения о потере данных, обрезанные строки или числа

Запрос по составному полю
Норма

Используется ВЫРАЗИТЬ, время выполнения приемлемое

Тревожный признак

Соединения со всеми таблицами состава, заметные задержки

Обработка Null из левого соединения
Норма

Есть проверка ЕСТЬ NULL или ЗначениеЗаполнено

Тревожный признак

Сравнение с пустой ссылкой или Неопределено

После изменения типов реквизитов всегда прогоняйте типовые операции на тестовой копии: создание и проведение документов, формирование ключевых отчётов, обмены. Особое внимание — местам, где значение реквизита участвует в запросах с приведением типа: при смене состава типов конструкция ВЫРАЗИТЬ(... КАК Документ.УдаленныйВид) начнёт выдавать ошибку.

Помните про ограничения платформы: тип реквизита нельзя менять «на лету» в пользовательском режиме, длина кода и номера объектов влияет на формат представления ссылок, а хранение файлов в реквизитах типа ХранилищеЗначения быстро раздувает размер базы — для объёмных файлов предпочтительны тома хранения.

Итог

Что важно запомнить

Типы в 1С делятся на примитивные, ссылочные, универсальные и типы объектов данных. Реквизит может иметь составной тип, но это усложняет запросы и требует ВЫРАЗИТЬ. Проверяйте тип через ТипЗнч(), заполненность — через ЗначениеЗаполнено(), а Null из запросов — отдельно от Неопределено. Любую смену типов в рабочей базе выполняйте только после резервного копирования.

Частые вопросы о типах данных в 1С

Чем отличается СправочникСсылка от СправочникОбъект?

Ссылка — это лёгкий идентификатор объекта, через который доступны реквизиты только для чтения. Объект — полная копия данных в памяти, которую можно изменять и записывать. Для чтения данных в циклах и отчётах используйте ссылки и запросы, объект получайте только когда нужно изменить данные.

Чем Null отличается от Неопределено?

Null возникает только в результатах запросов при отсутствии соответствия в соединении таблиц. Неопределено — значение переменной, которой ничего не присвоено, или признак отсутствия результата функции. Они не равны друг другу, и проверять их нужно разными способами: Null — через ЕСТЬ NULL или сравнение с Null, Неопределено — обычным сравнением.

Когда использовать составной тип реквизита?

Когда один и тот же реквизит по смыслу может ссылаться на объекты разных видов: например, «Документ-основание» или «Владелец файла». Если состав типов используется в нескольких объектах, оформите его как определяемый тип — так проще расширять конфигурацию.

Почему нельзя сравнивать строку неограниченной длины в запросе?

Такие строки хранятся в базе данных как текстовые поля большого размера, для которых СУБД не поддерживает обычные операции сравнения и соединения. Обходной путь — привести поле к строке фиксированной длины через ВЫРАЗИТЬ(Поле КАК Строка(200)), но лучше изначально задавать ограниченную длину там, где нужны отборы.

Как программно узнать тип значения переменной?

Функцией ТипЗнч(Значение), которая возвращает объект типа Тип. Результат сравнивают с Тип("ИмяТипа"), например Тип("Число") или Тип("ДокументСсылка.РеализацияТоваров"). Для проверки на ссылочность в целом удобен метод Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)).

Что произойдёт с данными при уменьшении длины строки или числа?

При реструктуризации значения, не помещающиеся в новые границы, будут обрезаны, а конфигуратор выдаст предупреждения. Это необратимая потеря данных, поэтому перед сужением типа сделайте копию базы и сначала проверьте фактические длины значений запросом.