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

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

Как определить переменную в модуле 1С

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

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

В этой статье разобраны все способы объявления переменных во встроенном языке 1С: синтаксис, различия между видами модулей, типичные ошибки компиляции и способы проверить, что переменная работает так, как задумано.

Где в модуле можно объявить переменную

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

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

Раздел основной программы (код после всех процедур и функций) выполняется при инициализации модуля. В нём можно присваивать значения уже объявленным переменным, но объявлять новые через Перем там нельзя.

Локальные переменные внутри процедуры или функции

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

// Пример объявления локальной переменной

Процедура РассчитатьСкидку(СуммаДокумента)

Перем ПроцентСкидки, РазмерСкидки;

ПроцентСкидки = 10;

РазмерСкидки = СуммаДокумента * ПроцентСкидки / 100;

КонецПроцедуры

Через запятую можно объявить сразу несколько переменных одной строкой. Тип переменной не указывается: встроенный язык 1С — слабо типизированный, и одна переменная может последовательно хранить число, строку или ссылку на объект. Тип определяется значением, которое присвоено в данный момент.

Имена локальных переменных могут совпадать с именами переменных модуля — в этом случае внутри процедуры будет использоваться локальная, «перекрывая» модульную. Такое совпадение имён затрудняет отладку, поэтому его лучше избегать.

Переменные модуля: объявление и срок жизни

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

// Раздел объявления переменных модуля

Перем КэшНастроек;

Перем ТекущийПользователь;

Процедура Инициализировать() Экспорт

ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();

КонецПроцедуры

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

Экспортные переменные и доступ из других модулей

Ключевое слово Экспорт после имени переменной делает её видимой снаружи модуля. Обращение происходит через имя модуля: ИмяОбщегоМодуля.ИмяПеременной — для общих модулей, либо через объект формы или объекта для соответствующих модулей.

// В общем модуле РаботаСКурсами

Перем ПоследнийКурсОбновления Экспорт;

// В другом модуле

ДатаКурса = РаботаСКурсами.ПоследнийКурсОбновления;

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

Исключение, где экспортные переменные встречаются осознанно, — устаревший код и отдельные сценарии совместимости. В новых разработках их стоит избегать.

Неявное объявление и почему на него нельзя полагаться

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

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

Типичные ошибки
01
Опечатка в имени при неявном объявлении — создаётся вторая переменная, значение теряется без всякой ошибки
02
Объявление Перем после процедуры — модуль не проходит синтаксическую проверку
03
Использование переменной модуля там, где достаточно локальной, — затрудняет отладку и повышает риск случайного изменения
04
Ожидание, что переменная серверного общего модуля сохранится между вызовами, — значение сбрасывается
05
Объявление переменной в модуле формы и попытка обратиться к ней из другой формы — контексты форм изолированы

Как проверить, что переменная объявлена правильно

Первый уровень проверки — синтаксический контроль модуля: в конфигураторе меню «Текст → Синтаксический контроль модуля» или сочетание клавиш. Ошибки вида «Переменная не определена» и «Ожидается символ ';'» выводятся в окне сообщений с указанием строки.

Второй уровень — отладка. Поставьте точку останова на строке присваивания, запустите отладку и посмотрите значение переменной через «Вычислить выражение» (Shift+F9) или табло. Если переменная не видна в списке локальных — она объявлена в другой области видимости или не объявлена вовсе.

Третий способ — функция встроенного языка для проверки заполненности: ЗначениеЗаполнено(Переменная) покажет, присвоено ли осмысленное значение. Для явной инициализации «пустым» значением используют Неопределено.

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

Особенности разных видов модулей

Правила объявления одинаковы, но контексты исполнения различаются. В модуле формы переменные модуля привязаны к экземпляру формы; кроме того, данные формы часто выносят в реквизиты формы, которые видны пользователю, — переменные модуля, наоборот, чисто служебные.

В модулях с директивами компиляции (&НаКлиенте, &НаСервере) переменная модуля доступна в обоих контекстах, но её значение не передаётся между клиентом и сервером автоматически. Каждый вызов сервера работает со своей копией контекста.

В общих модулях с признаком «Сервер» экспортные переменные инициализируются заново при каждом обращении, если не включено повторное использование возвращаемых значений. Это нужно учитывать при проектировании кэшей.

Сравнение вариантов

Локальная переменная

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

Переменная модуля

Подходит для состояния, общего для нескольких процедур модуля; требует дисциплины, чтобы не читать устаревшее значение

Экспортная переменная

Видна из других модулей, но нарушает инкапсуляцию; почти всегда лучше заменить экспортной функцией

Неявное объявление

Работает без Перем, но опечатки не ловятся компилятором; допустимо только в коротких одноразовых фрагментах

Часто задаваемые вопросы

Можно ли объявить переменную с указанием типа, как в других языках?

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

Чем отличается Перем в модуле от реквизита формы?

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

Почему возникает ошибка «Переменная не определена», хотя Перем написан?

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

Как объявить несколько переменных одной строкой?

Перечислите имена через запятую: «Перем А, Б, В;». Все они будут иметь одинаковую область видимости. Для читаемости в больших модулях часто объявляют каждую переменную отдельной строкой с комментарием.

Нужно ли инициализировать переменную сразу после объявления?

Формально нет — необъявленной значением считается Неопределено. Но явное присваивание начального значения делает код предсказуемее и упрощает отладку, особенно для переменных модуля, присваивание которых может происходить в разных процедурах.

Итог

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

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