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