Оператор присваивания во встроенном языке 1С 8.3: переменные, реквизиты, коллекции
Содержание
Чтобы присвоить значение в 1С, напишите имя переменной, знак =, выражение и точку с запятой: Сумма = 1500;. Отдельного оператора := во встроенном языке 1С:Предприятия нет, сокращений вида += и ++ тоже. Платформа сама понимает по месту в строке, где = означает присваивание, а где сравнение.
Дальше всё зависит от того, куда вы пишете значение. Переменной — достаточно одной строки. Реквизиту справочника или документа — нужно получить объект и записать его. Реквизиту формы — учесть, что код идёт на клиенте или на сервере. Ниже разобраны все три случая и ловушки, на которых спотыкаются даже опытные разработчики.
Синтаксис присваивания: из чего состоит строка
Общая форма одна:
ИмяПеременной = Выражение;
Слева может стоять:
- 🔹 локальная переменная или переменная модуля;
- 🔹 свойство объекта:
Объект.Комментарий; - 🔹 элемент коллекции по индексу:
Массив[0],Соответствие["Код"]; - 🔹 поле строки табличной части:
СтрокаТЧ.Количество.
Справа — любое выражение: литерал, другая переменная, вызов функции, арифметика, тернарный оператор ?().
Количество = 10;
Цена = 125.50;
Сумма = Количество * Цена; // 1255
Текст = "Итого: " + Формат(Сумма, "ЧДЦ=2");
Статус = ?(Сумма > 1000, "Крупный", "Обычный");
Объявлять переменную или нет
Локальную переменную объявлять не обязательно. Она создаётся в момент первого присваивания и живёт до конца процедуры. Явное объявление через Перем нужно в двух случаях:
- Переменная модуля, которая должна жить между вызовами процедур. Её объявляют в начале модуля:
Перем КэшНастроек;. - Переменная модуля объекта, доступная снаружи:
Перем ДополнительныеДанные Экспорт;.
Перем Счетчик; // значение пока Неопределено
Процедура Увеличить()
Если Счетчик = Неопределено Тогда
Счетчик = 0;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецПроцедуры
Объявленная через Перем переменная до первого присваивания содержит Неопределено. Арифметика с ним вызовет ошибку, поэтому начальное значение задавайте явно.
Ловушка двойного знака равенства
Цепочку А = Б = 0; 1С не понимает как «обнулить обе переменные». Первый = — присваивание, второй — сравнение. В А попадёт Истина или Ложь в зависимости от того, равно ли Б нулю. Сама Б не изменится.
Б = 5;
А = Б = 0; // А = Ложь, Б по-прежнему 5
Каждой переменной — своя строка.
Как записать значение каждого типа
Литералы примитивных типов пишутся по-разному. Таблица — для быстрой сверки.
| Тип | Пример присваивания | Что учесть |
|---|---|---|
| Число | Ставка = 0.2; | Разделитель дробной части — точка |
| Строка | Имя = "ООО ""Ромашка"""; | Кавычка внутри строки удваивается |
| Дата | Д = '20261007'; | Одинарные кавычки, формат ГГГГММДД |
| Дата и время | Д = '20261007153000'; | ГГГГММДДччммсс |
| Булево | Флаг = Истина; | Также Ложь |
| Пустое значение | З = Неопределено; | Null приходит из запросов |
| Ссылка | Орг = Справочники.Организации.ПустаяСсылка(); | Через менеджер объекта |
| Перечисление | Вид = Перечисления.ВидыОпераций.Продажа; | Значение из конфигурации |
Многострочный текст записывают с продолжением строки: каждая следующая строка начинается с вертикальной черты.
ТекстЗапроса = "ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Дату из переменных собирают функцией Дата(): Д = Дата(2026, 10, 7); — без времени, Дата(2026, 10, 7, 15, 30, 0) — со временем.
Объекты-коллекции создаются через Новый
Массив, структура, соответствие, таблица значений не имеют литералов. Сначала конструктор, потом заполнение:
Товары = Новый Массив;
Товары.Добавить("Бумага");
Товары[0] = "Бумага А4"; // замена по индексу
Реквизиты = Новый Структура("Код, Наименование", "001", "Склад");
Реквизиты.Наименование = "Основной склад";
Реквизиты.Вставить("Ответственный", "Иванов");
Цены = Новое Соответствие;
Цены["001"] = 125.50; // добавит или заменит ключ
Учтите разницу. В структуре присвоить через точку можно только существующему ключу, новый добавляют методом Вставить(). Соответствие по индексу добавляет ключ само.
Присваивание реквизитам объектов базы
Здесь начинаются вопросы. Ссылка на справочник или документ — это только указатель на данные. Через неё значения читают, но не меняют:
// Так НЕЛЬЗЯ — ошибка «Поле объекта недоступно для записи»
Ссылка.Комментарий = "Проверено";
Правильный порядок: получить объект, изменить, записать.
Объект = Ссылка.ПолучитьОбъект();
Объект.Комментарий = "Проверено";
Объект.Ответственный = Пользователи.ТекущийПользователь();
Объект.Записать();
Для нового элемента вместо ПолучитьОбъект() вызывают конструктор менеджера: Справочники.Номенклатура.СоздатьЭлемент(), Документы.РеализацияТоваровУслуг.СоздатьДокумент(). Если документ проводится, запись делают с режимом: Объект.Записать(РежимЗаписиДокумента.Проведение);.
Методы ПолучитьОбъект() и Записать() работают только на сервере. В клиентском модуле формы их вызов приведёт к ошибке: вынесите код в процедуру с директивой &НаСервере или в общий серверный модуль.
Табличная часть
Строку сначала добавляют, потом заполняют поля:
НоваяСтрока = Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = Номенклатура;
НоваяСтрока.Количество = 3;
НоваяСтрока.Цена = 250;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена; // 750
Константы и регистры сведений
У них свой способ записи:
- 🔹 константа:
Константы.ИмяКонстанты.Установить(Значение);, чтение —Константы.ИмяКонстанты.Получить(); - 🔹 регистр сведений
: менеджер записи
РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи(), заполнение измерений и ресурсов, затемЗаписать().
Реквизиты формы
На форме объекта данные лежат в основном реквизите Объект. Значение присваивают ему, а не элементу формы:
&НаКлиенте
Процедура ЗаполнитьКомментарий(Команда)
Объект.Комментарий = "Заполнено автоматически";
Модифицированность = Истина;
КонецПроцедуры
Элементы.Комментарий — это поле на экране со свойствами вроде Видимость и ТолькоПросмотр. Присвоить ему значение реквизита нельзя.
💡 Строка Модифицированность = Истина; нужна, чтобы форма предложила сохранить изменения при закрытии. Без неё пользователь может закрыть окно, и программное изменение пропадёт.
Если на сервере формы нужен полноценный объект с его методами, используйте пару РеквизитФормыВЗначение("Объект") и ЗначениеВРеквизитФормы(ОбъектДанных, "Объект").
Значения для запроса присваивают параметрами
В тексте запроса переменные модуля не видны. Значение передают через параметр с ампersand-именем в тексте и методом УстановитьПараметр():
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг
|ГДЕ Дата МЕЖДУ &Начало И &Конец";
Запрос.УстановитьПараметр("Начало", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("Конец", КонецМесяца(ТекущаяДатаСеанса()));
Склеивать значение прямо в текст запроса через + не нужно: так ломаются даты и строки с кавычками, а сам запрос хуже кешируется.
Динамическая типизация: что происходит с типом
Переменная во встроенном языке не привязана к типу. Одна и та же переменная может хранить число, потом строку, потом ссылку:
Значение = 10; // Число
Значение = "десять"; // Строка
Значение = Неопределено;
Удобно, но порождает две ловушки.
Сложение разных типов
Тип результата определяет левый операнд. Строка плюс число склеивается в строку, число плюс строка пытается превратить строку в число.
А = "Сумма: " + 1500; // "Сумма: 1 500" — с пробелом-разделителем разрядов
Б = 5 + "3"; // 8
В = 5 + "три"; // ошибка преобразования
Пробел в «1 500» ломает коды, номера и имена файлов. Число к строке приводите явно: Формат(1500, "ЧГ=0") вернёт 1500 без разделителей. Тот же приём нужен для номеров строк и кодов в сообщениях.
Дата плюс число сдвигает дату на секунды: ТекущаяДатаСеанса() + 86400 — сутки вперёд. Разность двух дат — число секунд.
Присваивание типизированному реквизиту
У реквизита в конфигураторе тип задан. Значение другого типа платформа приведёт к типу реквизита, и результат может отличаться от ожидаемого: несовместимое значение превратится в пустое значение типа, лишние символы строки отрежутся по длине, дробная часть подстроится под точность числа. Ошибки при этом не будет, вы просто потеряете данные.
Проверяйте тип перед присваиванием:
Если ТипЗнч(Значение) = Тип("Число") Тогда
Объект.Количество = Значение;
Иначе
ВызватьИсключение "Ожидалось число, получено: " + ТипЗнч(Значение);
КонецЕсли;
Для составного типа проверку делают через описание типа: Метаданные.Справочники.Номенклатура.Реквизиты.Вес.Тип.СодержитТип(Тип("Число")).
Значение или ссылка: копирование коллекций
Примитивные типы (число, строка, дата, булево) копируются по значению. Объекты — массив, структура, таблица значений, объект справочника — по ссылке. Присваивание не создаёт копию, а даёт второе имя тому же объекту:
Исходный = Новый Массив;
Исходный.Добавить(1);
Копия = Исходный;
Копия.Добавить(2);
// Исходный.Количество() = 2 — изменился и исходный массив
Как получить настоящую копию:
| Что копируем | Способ |
|---|---|
| Таблица значений | Копия = Таблица.Скопировать(); |
| Структура (без вложенных) | Цикл Для Каждого КлючИЗначение Из Исходная с Копия.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение) |
| Массив | Цикл с Добавить() |
| Любая вложенная коллекция | В конфигурациях на БСП — ОбщегоНазначения.СкопироватьРекурсивно(Исходная) |
Та же логика у параметров процедур. По умолчанию параметр передаётся по ссылке, и присваивание внутри процедуры меняет переменную вызывающего кода. Чтобы защитить исходник, объявите параметр с ключевым словом Знач:
Процедура Обработать(Знач Количество)
Количество = Количество * 2; // снаружи значение не изменится
КонецПроцедуры
Ошибки при присваивании и как их ловить
Большинство сбоев выдают узнаваемый текст. Сверьтесь с диагностикой:
Ввод из внешних источников — файлов, обменов, HTTP-сервисов — оборачивайте в Попытка:
Попытка
Количество = Число(СтрЗаменить(СтрокаИзФайла, " ", ""));
Исключение
Количество = 0;
ЗаписьЖурналаРегистрации("Загрузка",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Не оставляйте блок Исключение пустым. Ошибка исчезнет из виду, а в базу запишется ноль, и искать причину придётся по расхождениям в отчётах.
Как присваивать быстро и без сюрпризов
Несколько приёмов, которые отличают аккуратный код от «рабочего на моей базе».
Заполняйте свойства пачкой
ЗаполнитьЗначенияСвойств(Приемник, Источник) переносит все одноимённые свойства за один вызов. Вместо десяти строк присваивания — одна:
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВыборкаИзЗапроса);
Третий параметр ограничит список свойств, четвёртый — исключит лишние: ЗаполнитьЗначенияСвойств(Приемник, Источник, , "Ссылка, Код").
Не получайте объект ради чтения
Ссылка.ПолучитьОбъект() читает из базы весь объект с табличными частями. Если нужно одно поле, хватит запроса или функции БСП ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИНН"). В цикле по тысяче документов разница заметна в разы.
Записывайте один раз
Каждый вызов Записать() — это транзакция, проверки и подписки на события. Присвойте все реквизиты и вызовите запись в конце, а не после каждого поля.
Проверяйте заполненность, а не пустоту по типу
ЗначениеЗаполнено(Значение) одинаково работает для нуля, пустой строки, пустой даты, пустой ссылки и Неопределено. Это надёжнее, чем сравнение Значение = "" или Значение = 0, которое ломается при смене типа.
Если Не ЗначениеЗаполнено(Объект.Договор) Тогда
Объект.Договор = ДоговорПоУмолчанию;
КонецЕсли;
Давайте переменным понятные имена
Сумма, СуммаНДС, СтрокаТовара читаются годами. А1, Тмп, Ч превращают сопровождение в расследование. Имена на русском в стиле СуммаСНДС — норма для встроенного языка и общепринятых стандартов разработки.
Частые вопросы
Есть ли в 1С оператор `+=` или инкремент `++`?
Счетчик = Счетчик + 1;. Для строк — Текст = Текст + Символы.ПС + НоваяСтрока;.Как присвоить значение сразу нескольким переменным?
А = Б = 0; сравнит Б с нулём и запишет в А результат сравнения.Чем отличаются Неопределено и Null?
Неопределено — значение по умолчанию у пустых переменных и составных реквизитов. Null приходит из запроса при левом соединении, когда связанной записи нет. В запросе от него избавляются функцией ЕСТЬNULL().Можно ли присвоить значение реквизиту через ссылку без записи объекта?
Записать() у объекта, полученного через ПолучитьОбъект().Почему присвоенное на форме значение не сохраняется?
Объект, или не выставили Модифицированность = Истина, и пользователь закрыл форму без записи.