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