Система 1С:Предприятие оперирует разнообразными типами данных, которые определяют структуру информации, правила её хранения и обработки. Понимание этих типов критично для разработчиков, администраторов и даже опытных пользователей, так как от правильного выбора типа зависит корректность расчётов, скорость выполнения операций и устойчивость системы к ошибкам. В этой статье мы детально разберём все основные категории данных в 1С 8.3, их синтаксические особенности и типичные сценарии применения.
В отличие от многих языков программирования, где типы данных жёстко фиксированы, 1С предлагает гибкую систему с динамической типизацией. Это означает, что переменная может изменять свой тип в процессе выполнения кода, но такой подход требует от программиста особой внимательности. Например, попытка сложить строку с числом без явного приведения типов приведёт к ошибке, в то время как в некоторых других языках это могло бы сработать автоматически. Далее мы рассмотрим, как избегать подобных ловушек и эффективно использовать каждый тип данных.
1. Примитивные типы данных
Примитивные (простые) типы — это базовые "кирпичики", из которых строятся все остальные структуры данных в 1С. Они не имеют внутренней структуры и хранят одно значение. К этой категории относятся Число, Строка, Дата, Булево и Null.
Особенность примитивов в том, что они передаются по значению, а не по ссылке. Это означает, что при присваивании переменной нового значения создаётся его копия, а не ссылка на оригинал. Например, если вы присваиваете значение одной числовой переменной другой, изменения в первой не повлияют на вторую.
- 🔢 Число — используется для хранения целых и дробных значений. Поддерживает арифметические операции (
+,-,*,/) и функции округления (Окр(),Цел()). Пример:Сумма = 1000.50. - 📜 Строка — последовательность символов в кодировке Unicode. Операции включают конкатенацию (
+), поиск подстрок (Найти()) и форматирование (СтрШаблон()). Пример:Приветствие = "Добрый день, " + ИмяПользователя. - 📅 Дата — хранит дату и время с точностью до секунды. Поддерживает арифметику дат (добавление дней, месяцев) и форматирование (
Формат()). Пример:СрокИстекает = ТекущаяДата() + 30. - ✅ Булево — логический тип с двумя значениями:
ИстинаилиЛожь. Используется в условиях (Если...) и циклах. Пример:ДокументПроведен = Истина. - ❌ Null — специальное значение, обозначающее "ничего" или "неопределённость". Возвращается, если переменная не инициализирована или функция не вернула результат. Пример:
Если Значение = Null Тогда....
⚠️ Внимание: При сравнении значений типа Null с другими типами всегда возвращаетсяЛожь, даже если сравниваются дваNull. Для проверки наNullиспользуйте конструкциюЗначение = Nullили функциюЗначениеЗаполнено().
2. Сложные типы данных: коллекции и структуры
Сложные типы данных в 1С позволяют хранить наборы значений или организовывать данные в иерархические структуры. Они передаются по ссылке, что означает: если вы присваиваете одну коллекцию другой, обе переменные будут ссылаться на один и тот же объект в памяти. Изменения в одной переменной отразятся на другой.
Наиболее востребованные сложные типы:
- 📋 Массив — упорядоченный список элементов с доступом по индексу (начинается с 0). Пример:
СписокТоваров = Новый Массив(3); СписокТоваров[0] = "Молоко". - 🔗 Структура — набор пар "ключ-значение", где ключом выступает строка. Удобна для хранения настроек или параметров. Пример:
Параметры = Новый Структура("Цвет, Размер", "Красный", 42). - 🔄 Соответствие — аналогично структуре, но ключи могут быть любыми типами (не только строками). Пример:
Сопоставление = Новый Соответствие; Сопоставление.Вставить(1, "Один"). - 📊 СписокЗначений — коллекция с возможностью хранения не только значений, но и их представлений (отображаемых имен). Пример:
Список = Новый СписокЗначений; Список.Добавить(1, "Первый элемент"). - 🔍 ТаблицаЗначений — двумерная структура с колонками и строками, аналогичная таблице в базе данных. Пример:
Таблица = Новый ТаблицаЗначений; Таблица.Колонки.Добавить("Наименование").
Особое внимание заслуживает ТаблицаЗначений — этот тип часто используется для временного хранения данных перед записью в базу или для обработки результатов запросов. Например, вы можете загрузить данные из Excel в таблицу значений, а затем перенести их в документ 1С.
| Тип данных | Пример создания | Типичное использование |
|---|---|---|
| Массив | Новый Массив(5) |
Хранение однотипных данных (например, список ID документов) |
| Структура | Новый Структура("Ключ1, Ключ2", Значение1, Значение2) |
Передача параметров в функции, конфигурационные настройки |
| ТаблицаЗначений | Новый ТаблицаЗначений; Таблица.Колонки.Добавить("Поле1") |
Обработка результатов запросов, импорт/экспорт данных |
Для ускорения работы с большими коллекциями используйте метод Индексировать() для массивов и таблиц значений. Это значительно сокращает время поиска элементов по значению.
3. Ссылочные типы: работа с объектами метаданных
Ссылочные типы данных в 1С представляют собой ссылки на объекты метаданных: документы, справочники, регистры и т.д. Они позволяют манипулировать данными базы без прямого обращения к SQL. Например, переменная типа СправочникСсылка.Номенклатура хранит ссылку на конкретный элемент справочника "Номенклатура".
Ключевые особенности ссылочных типов:
- 🔗 Они всегда ссылаются на существующий объект в базе (или на
Null, если ссылка пустая). - 🔄 Поддерживают методы для получения и изменения данных объекта (например,
ПолучитьОбъект(),Записать()). - 📌 Имеют уникальный идентификатор (
УникальныйИдентификатор()), который не меняется при переносе данных между базами.
Пример работы со ссылочным типом:
// Получаем ссылку на элемент справочника "Контрагенты" по наименованию
СсылкаНаКонтрагента = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
// Проверяем, найден ли элемент
Если СсылкаНаКонтрагента.Пустая() Тогда
Сообщить("Контрагент не найден!");
Иначе
ОбъектКонтрагента = СсылкаНаКонтрагента.ПолучитьОбъект();
ОбъектКонтрагента.Адрес = "ул. Ленина, 10";
ОбъектКонтрагента.Записать();
КонецЕсли;
⚠️ Внимание: При работе со ссылочными типами избегайте "висячих ссылок" — ситуаций, когда в коде остаются ссылки на удалённые объекты. Это может привести к ошибкам при выполнении операций. Всегда проверяйте ссылки на пустоту с помощью метода Пустая().
4. Типы данных для работы с файлами и двоичными данными
Для обработки файлов, изображений и других двоичных данных в 1С предусмотрены специализированные типы:
- 📄 ДвоичныеДанные — хранит произвольные байты (например, содержимое файла). Пример:
Данные = Новый ДвоичныеДанные(ФайлПрочитать("C:\image.png")). - 📎 ХранилищеЗначения — контейнер для хранения любых данных (включая объекты) в двоичном виде. Используется для сериализации. Пример:
Хранилище = Новый ХранилищеЗначения(ОбъектДокумента). - 🖼️ Картинка — специализированный тип для работы с изображениями (JPEG, PNG, BMP). Поддерживает масштабирование и сохранение. Пример:
Логотип = Новый Картинка("C:\logo.jpg").
ДвоичныеДанные и ХранилищеЗначения часто путают, но их назначение принципиально разное: ДвоичныеДанные хранят "сырые" байты (например, PDF-файл), а ХранилищеЗначения предназначено для сериализации объектов 1С (документов, справочников) с возможностью последующего восстановления.
Пример сохранения и восстановления объекта через ХранилищеЗначения:
// Сериализация документа в хранилище
Хранилище = Новый ХранилищеЗначения(ДокументОбъект);
ДвоичныеДанные = Хранилище.ПолучитьДвоичныеДанные();
// Сохранение в файл
ДвоичныеДанные.Записать("C:\backup.doc");
// Восстановление из файла
ВосстановленныеДанные = Новый ДвоичныеДанные("C:\backup.doc");
Хранилище = Новый ХранилищеЗначения(ВосстановленныеДанные);
ВосстановленныйДокумент = Хранилище.Получить();
Как отличить ДвоичныеДанные от ХранилищеЗначения в коде?
Оба типа могут хранить двоичную информацию, но ХранилищеЗначения имеет методы Получить() и Установить() для работы с объектами 1С, тогда как ДвоичныеДанные оперирует только байтами и поддерживает методы Записать()/Прочитать() для файлов.
5. Типы данных для работы с запросами и результатами
При выполнении запросов к базе данных 1С возвращает результаты в виде специализированных типов:
- 📋 РезультатЗапроса — содержит данные, полученные после выполнения запроса. Поддерживает итерацию по строкам. Пример:
Результат = Запрос.Выполнить().Выбрать(). - 🔍 ВыборкаДанных — используется для пострчного чтения больших наборов данных (экономит память). Пример:
Пока Выборка.Следующий() Цикл ... КонецЦикла. - 📊 ТаблицаРезультата — альтернативный формат результата запроса, аналогичный ТаблицаЗначений, но оптимизированный для чтения.
Пример обработки результата запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Товар,
| СУММА(Документ.Количество) КАК Итого
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Документ
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО Документ.Номенклатура = Номенклатура.Ссылка
|ГДЕ
| Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода
|СГРУППИРОВАТЬ ПО
| Номенклатура.Наименование";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(СтрШаблон("Товар: %1, Количество: %2", Выборка.Товар, Выборка.Итого));
КонецЦикла;
⚠️ Внимание: При работе с большими выборками данных (тысячи строк) всегда используйте ВыборкаДанных вместо загрузки всего результата в память через Выгрузить(). Это предотвратит переполнение памяти и зависание системы.
Использовать индексированные поля в условиях (ГДЕ)
Ограничивать период выборки параметрами
Избегать SELECT * — указывать только нужные поля
Применять СГРУППИРОВАТЬ ПО вместо обработки дублей в коде
Для больших данных использовать ПАКЕТНЫЙ режим-->
6. Пользовательские типы данных: перечисления и определения типов
Помимо встроенных типов, в 1С можно создавать собственные типы данных для упрощения кода и повышения его читаемости:
- 🔖 Перечисление — набор предопределённых значений (например, "ВидыОплаты": Наличные, Безналичные, Карта). Пример:
Если ВидОплаты = Перечисления.ВидыОплаты.Наличные Тогда.... - 📌 ОпределениеТипов — позволяет создавать псевдонимы для сложных типов. Пример:
Тип МояСтруктура = Новый ОписаниеТипов("Структура", Новый ОписаниеТипов("Число", "Строка")).
Пример использования Перечисления:
// Создание перечисления в конфигураторе
Перечисление ВидыДоставки
{
Самовывоз,
Курьер,
Почта,
ТранспортнаяКомпания
}
// Использование в коде
Если ВидДоставки = Перечисления.ВидыДоставки.Курьер Тогда
СтоимостьДоставки = 300;
КонецЕсли;
ОпределениеТипов полезно, когда вам нужно гарантировать, что функция принимает параметры строго определённой структуры. Например, вы можете создать тип "ПараметрыОтчета" и использовать его в сигнатуре метода, чтобы избежать ошибок при передаче параметров.
7. Особенности работы с типами данных в разных режимах 1С
Поведение типов данных может отличаться в зависимости от режима работы 1С:Предприятие:
- 🖥️ Толстый клиент — поддерживает все типы данных без ограничений, включая работу с файлами и двоичными данными.
- 🌐 Тонкий клиент — имеет ограничения на работу с файловой системой (например, нельзя прочитать файл с диска без диалога выбора).
- 📱 Веб-клиент — аналогично тонкому клиенту, плюс ограничения на размер передаваемых данных (например, большие двоичные данные могут не передаваться).
- 🤖 Сервер — оптимизирован для работы с базами данных, но не имеет доступа к файловой системе напрямую.
Пример кода, который будет работать по-разному в тонком и толстом клиенте:
// Этот код вызовет ошибку в тонком клиенте
ПутьКФайлу = "C:\temp\data.txt";
Текст = Новый ЧтениеТекста(ПутьКФайлу);
Содержимое = Текст.Прочитать();
// Альтернатива для тонкого клиента (с диалогом выбора файла)
ПутьКФайлу = ОткрытьФайлДиалог("Выберите файл");
Если Не ПутьКФайлу = Неопределено Тогда
Текст = Новый ЧтениеТекста(ПутьКФайлу);
Содержимое = Текст.Прочитать();
КонецЕсли;
⚠️ Внимание: При разработке универсальных решений (например, расширений или внешних обработок) всегда проверяйте текущий режим работы с помощью функцииРежимРаботыСервера()илиТолстыйКлиент(), чтобы избежать ошибок, связанных с ограничениями клиентских приложений.
8. Практические рекомендации по выбору типов данных
Выбор правильного типа данных — залог эффективной и надёжной работы системы. Вот ключевые рекомендации:
- 🔢 Для денежных расчётов всегда используйте Число с указанием точности (например,
Число(10, 2)для рублей и копеек). Избегайте типа Дробь, так как он может приводить к ошибкам округления. - 📅 Для хранения дат без времени используйте формат
Дата(Год, Месяц, День), а не строки. Это позволит корректно сравнивать даты и выполнять арифметические операции. - 📋 Для больших наборов данных отдавайте предпочтение ТаблицаЗначений вместо массивов — она оптимизирована для работы с памятью и поддерживает колонки с разными типами.
- 🔗 При передаче данных между системами (например, через JSON) используйте Структура или Массив, так как они легко сериализуются.
Пример оптимизированного кода для работы с денежными значениями:
// Плохо: использование строк для денежных расчётов
СуммаСтрокой = "1000.50";
Итог = СуммаСтрокой + 10; // Ошибка! Нельзя складывать строку и число
// Правильно: явное приведение к числу с указанием точности
Сумма = Число(1000.50);
Итог = Окр(Сумма + 10, 2); // 1010.50
Всегда проверяйте типы данных на границе систем (при обмене с внешними сервисами, чтении из файлов, работе с API). Неявное приведение типов — частая причина ошибок в интеграционных решениях.
FAQ: Частые вопросы о типах данных в 1С
Как преобразовать строку в число, если строка содержит разделители тысяч?
Используйте функцию Число() с предварительной очисткой строки от лишних символов:
СтрокаСуммы = "1 234 567,89";
ЧистаяСтрока = СтрЗаменить(СтрокаСуммы, " ", "");
ЧислоСуммы = Число(ЧистаяСтрока);
Или используйте СтрЗаменить() для замены запятой на точку, если требуется англоязычный формат:
ЧислоСуммы = Число(СтрЗаменить(СтрокаСуммы, ",", "."));
Почему при сравнении двух дат в 1С получаю неожиданный результат?
Убедитесь, что сравниваемые значения имеют один и тот же тип. Например, Дата(2023, 1, 1) и "01.01.2023" (строка) не будут равны. Всегда приводите строки к типу Дата:
Дата1 = Дата(2023, 1, 1);
Дата2 = Дата(СтрокаДата); // Преобразуем строку в дату
Если Дата1 = Дата2 Тогда...
Как сохранить в 1С данные произвольного типа (например, настройки формы)?
Используйте ХранилищеЗначения для сериализации сложных данных:
// Сохранение
Настройки = Новый Структура("Цвет, РазмерШрифта", "Синий", 12);
Хранилище = Новый ХранилищеЗначения(Настройки);
ДвоичныеДанные = Хранилище.ПолучитьДвоичныеДанные();
ДвоичныеДанные.Записать("C:\settings.dat");
// Восстановление
Данные = Новый ДвоичныеДанные("C:\settings.dat");
Хранилище = Новый ХранилищеЗначения(Данные);
ВосстановленныеНастройки = Хранилище.Получить();
Можно ли в 1С создать свой тип данных, аналогичный классу в OOP?
Полноценных классов, как в объектно-ориентированных языках, в 1С нет. Однако вы можете:
- Использовать Структуру для хранения данных и набор функций для их обработки.
- Создавать Общие модули с процедурами и функциями, имитирующими методы класса.
- В новых версиях платформы (8.3.20+) доступны Классы в языке 1С:Enterprise, но их поддержка ограничена.
Пример имитации класса:
// В общем модуле "МойКласс"
Перем Данные Экспорт;
Процедура Инициализировать(Знач Параметры) Экспорт
Данные = Новый Структура;
Данные.Вставить("Имя", Параметры.Имя);
Данные.Вставить("Возраст", Параметры.Возраст);
КонецПроцедуры
Функция ПолучитьИмя() Экспорт
Возврат Данные.Имя;
КонецФункции
// Использование
МойКласс.Инициализировать(Новый Структура("Имя, Возраст", "Иван", 30));
Имя = МойКласс.ПолучитьИмя();
Как узнать тип переменной в 1С во время выполнения?
Используйте функцию ТипЗнч() или ТипЗначения():
Переменная = 100;
Тип = ТипЗнч(Переменная); // Вернёт "Число"
Если Тип = Тип("Число") Тогда
Сообщить("Это число!");
КонецЕсли;
Для проверки сложных типов (например, ссылок на справочники) используйте конструкцию:
Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Контрагенты") Тогда
Сообщить("Это ссылка на контрагента!");
КонецЕсли;