Разработка и Конфигурация · 11 мин
Как объявить переменную в модуле 1С
Как объявить переменную в модуле 1С: ключевое слово Перем, область видимости, разница между модулем формы, общим модулем и модулем объекта. Примеры кода.
Во встроенном языке 1С переменные работают в двух режимах: их можно объявить явно через ключевое слово Перем или использовать неявно — просто присвоив значение новому имени внутри процедуры. Понимание разницы между этими подходами критично, потому что от способа объявления зависит область видимости переменной: будет ли она доступна только внутри одной процедуры, во всём модуле или вообще из других объектов конфигурации.
Ошибки с переменными — одна из самых частых причин сообщений «Переменная не определена» при проверке модуля. Чаще всего проблема не в самой переменной, а в том, где она объявлена: локальная переменная процедуры недоступна снаружи, а переменная общего модуля может быть недоступна из-за настроек привилегированного режима или флага «Клиент/Сервер».
Ниже разобран синтаксис объявления, области видимости в разных типах модулей, экспортные переменные, типичные ошибки и способы проверки результата. Примеры приведены для управляемых форм и обычного приложения — синтаксис объявления одинаков, отличается контекст исполнения.
Базовый синтаксис объявления переменной
Явное объявление выполняется оператором Перем, после которого указывается имя переменной. Объявление завершается точкой с запятой. Одновременно можно объявить несколько переменных через запятую:
Перем Счетчик;
Перем ИмяКлиента, СуммаДокумента, ДатаОбработки;
Тип переменной при объявлении не указывается — встроенный язык 1С использует динамическую типизацию. Одна и та же переменная может сначала хранить строку, а затем число или ссылку на объект. Тип определяется значением в момент присваивания:
Перем Значение;
Значение = "Текст"; // строка
Значение = 100; // теперь число
Значение = Истина; // теперь булево
Имя переменной должно начинаться с буквы (русской или латинской) либо символа подчёркивания и может содержать цифры. Пробелы и спецсимволы запрещены. Регистр букв не имеет значения: Счетчик и СЧЕТЧИК — одна и та же переменная.
Локальные переменные внутри процедуры или функции
Внутри тела процедуры или функции переменные можно вообще не объявлять: при первом присваивании значения новому имени интерпретатор создаст локальную переменную автоматически. Она существует только во время выполнения этой процедуры и уничтожается при выходе из неё.
Процедура РассчитатьСкидку()
ПроцентСкидки = 10; // переменная создана неявно
ИтоговаяСумма = 1000 * (1 - ПроцентСкидки / 100);
КонецПроцедуры
Явное объявление через Перем внутри процедуры даёт тот же эффект, но делает код читаемее и защищает от опечаток: если включена проверка модулей, опечатка в имени неявной переменной не создаст новую переменную, а вызовет ошибку компиляции, если имя объявлено явно, но используется с ошибкой.
Важное ограничение: локальная переменная недоступна за пределами своей процедуры. Попытка обратиться к ней из другой процедуры того же модуля вызовет ошибку «Переменная не определена».
Переменные уровня модуля
Если переменная нужна нескольким процедурам одного модуля, её объявляют в разделе описания переменных — в самом начале модуля, до первого оператора Процедура или Функция. Такая переменная хранит значение между вызовами процедур внутри этого модуля.
Перем ТекущийПользователь;
Перем КоличествоОбработанных;
Процедура Инициализировать()
ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
КоличествоОбработанных = 0;
КонецПроцедуры
Процедура ОбработатьСтроку()
КоличествоОбработанных = КоличествоОбработанных + 1;
КонецПроцедуры
Область видимости такой переменной зависит от типа модуля. В модуле формы она живёт, пока открыта форма. В модуле объекта (например, документа) — пока существует объект. В общем модуле — в рамках сеанса вызова, причём поведение зависит от того, серверный это модуль или клиентский.
Экспортные переменные и доступ извне
Ключевое слово Экспорт после имени переменной делает её доступной из других модулей конфигурации. Это применяется в основном в общих модулях и модулях объектов:
Перем ТекущиеНастройки Экспорт;
Обращение к такой переменной извне выполняется через имя общего модуля: МойОбщийМодуль.ТекущиеНастройки. Для переменных модуля объекта — через ссылку на объект, если обращение идёт из его модуля формы или извне.
Экспортные переменные следует использовать осознанно: они создают жёсткую связь между модулями, и изменение имени или логики такой переменной может сломать код в других местах конфигурации. Во многих случаях вместо экспортной переменной лучше подходит экспортная функция, возвращающая нужное значение, — так проще контролировать доступ и кэшировать данные.
Сравнение вариантов
Подходит для промежуточных вычислений внутри одной процедуры. Не доступна снаружи.
Подходит для данных, общих для нескольких процедур одного модуля. Не видна из других модулей без Экспорт.
Подходит для общих модулей, когда значение нужно извне. Минус — жёсткая связность кода.
Подходит для управляемых форм, когда значение должно переживать серверные вызовы и отображаться или использоваться на клиенте.
Объявление переменных в разных типах модулей
Модуль формы
В управляемой форме переменные объявляются в начале модуля формы. Директивы компиляции (&НаКлиенте, &НаСервере) применяются к процедурам, но не к разделу переменных — переменные модуля формы доступны в обоих контекстах, однако их значения не синхронизируются между клиентом и сервером автоматически.
Общий модуль
В общем модуле переменные объявляются так же, но важны свойства модуля: «Сервер», «Клиент (управляемое приложение)», «Вызов сервера». Если модуль не помечен как клиентский, обращение к его переменной из клиентского кода вызовет ошибку компиляции. Также учитывайте, что значения переменных серверного общего модуля могут сбрасываться между вызовами, поэтому не храните в них состояние, критичное для бизнес-логики.
Модуль объекта и модуль менеджера
В модуле объекта (справочника, документа) переменные модуля живут вместе с экземпляром объекта. В модуле менеджера переменные общие для менеджера объекта в целом. Для обработок логика аналогична модулю объекта.
- 1Откройте нужный модуль в конфигураторе (модуль формы, общий модуль или модуль объекта).
- 2Если переменная нужна нескольким процедурам — перейдите в начало модуля, до первой процедуры.
- 3Напишите: Перем ИмяПеременной; — при необходимости добавьте Экспорт.
- 4Если переменная нужна только внутри одной процедуры — объявите её внутри процедуры или просто присвойте значение.
- 5Выполните проверку модуля (Ctrl+F7 или через меню Конфигурация — Проверка конфигурации) и убедитесь в отсутствии ошибок.
Типичные ошибки и как их исправить
Самая распространённая ошибка — «Переменная не определена». Она возникает, когда код обращается к имени, которое не объявлено через Перем на уровне модуля и не является параметром или локальной переменной текущей процедуры. Проверьте, в том ли модуле объявлена переменная и не опечатались ли вы в имени.
Вторая частая ситуация — переменная объявлена в общем модуле, но недоступна из клиентского кода. Причина в свойствах общего модуля: проверьте флаги «Клиент (управляемое приложение)» и «Сервер» в палитре свойств модуля.
Третья ошибка — ожидание, что переменная модуля формы сохранит значение после серверного вызова. В управляемых формах контекст сервера пересоздаётся, и переменные модуля на сервере не хранят состояние между вызовами. Для таких данных используйте реквизиты формы.
Как проверить результат
После объявления переменной выполните синтаксическую проверку модуля: в конфигураторе откройте модуль и нажмите Ctrl+F7, либо запустите полную проверку конфигурации. Ошибки объявления переменных выявляются именно на этом этапе, до запуска.
Для проверки значений в рантайме используйте отладчик: поставьте точку останова на строке присваивания, запустите отладку (F5) и посмотрите значение переменной в табло или через «Вычислить выражение» (Shift+F9). Это надёжнее, чем вывод через Сообщить(), особенно в серверном коде.
Как проверить результат
Ошибок «Переменная не определена» нет
Ошибка компиляции с указанием строки и имени переменной
Переменная содержит ожидаемое значение после присваивания
Значение Неопределено или не того типа
Обращение Модуль.Переменная компилируется и возвращает значение
Ошибка компиляции — переменная не экспортная или модуль недоступен в данном контексте
Часто задаваемые вопросы
Обязательно ли объявлять переменную через Перем?
Нет, внутри процедуры переменная создаётся автоматически при первом присваивании. Однако явное объявление улучшает читаемость и помогает выявлять опечатки на этапе проверки модуля. На уровне модуля объявление через Перем обязательно — неявных переменных модуля не существует.
Можно ли указать тип переменной при объявлении?
Нет, встроенный язык 1С не поддерживает статическую типизацию переменных. Тип определяется присвоенным значением и может меняться в ходе выполнения. Для самоконтроля типа используйте функцию ТипЗнч() в отладке или проверках.
Почему переменная общего модуля «обнуляется»?
Серверные общие модули не гарантируют сохранение значений переменных между вызовами: контекст может пересоздаваться. Для хранения данных между вызовами используйте параметры сеанса, константы, регистры сведений или механизм повторного использования возвращаемых значений у функций.
Чем переменная модуля формы отличается от реквизита формы?
Реквизит формы передаётся между клиентом и сервером и сохраняется при серверных вызовах, а переменная модуля формы существует только в рамках одного контекста исполнения. Если данные нужны и на клиенте, и на сервере — используйте реквизит формы.
Можно ли объявить переменную с начальным значением сразу?
Нет, оператор Перем не поддерживает инициализацию при объявлении. Значение присваивается отдельным оператором. Для переменных модуля инициализацию удобно выполнять в обработчиках (например, ПриСозданииНаСервере для формы) или в отдельной процедуре инициализации.
Что делать с ошибкой «Переменная не определена» после обновления конфигурации?
Проверьте, не переименован ли общий модуль или переменная, не снят ли флаг Экспорт, не изменились ли свойства клиент/сервер у общего модуля. Выполните полную проверку конфигурации — она покажет все места с проблемой.
Что важно запомнить
Переменная объявляется оператором Перем: внутри процедуры — локальная, в начале модуля — переменная модуля, с ключевым словом Экспорт — доступная извне. Тип не указывается. Для управляемых форм помните о разнице между переменными модуля и реквизитами формы, а для общих модулей — о свойствах клиент/сервер. Результат всегда проверяйте синтаксической проверкой модуля и отладчиком.