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

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

1С: как передать переменную — все рабочие способы

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

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

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

Ниже разобраны все основные способы: от простейшей передачи через параметры процедуры до обмена данными между формами и фоновыми заданиями, с примерами кода и разбором типичных ошибок.

Передача переменной в процедуру или функцию

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

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

Сообщить("Скидка: " + СуммаДокумента * ПроцентСкидки / 100);

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

РассчитатьСкидку(10000, 5);

Если параметр не передан при вызове, он получает значение Неопределено. Можно задать значение по умолчанию прямо в объявлении: Процедура Печать(Документ, КоличествоКопий = 1). Такие параметры должны стоять в конце списка — иначе компилятор выдаст ошибку.

Функция отличается тем, что возвращает результат оператором Возврат. Это второй канал передачи данных: значение уходит внутрь через параметры и возвращается наружу как результат вызова.

Передача по ссылке и по значению: ключевое слово «Знач»

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

Процедура ДобавитьСтроку(Таблица) // без Знач — по ссылке

Таблица.Добавить("Новая строка");

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

Массив = Новый Массив;

ДобавитьСтроку(Массив);

// Массив уже содержит элемент

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

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

По ссылке или по значению

Без Знач (по ссылке)

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

С ключевым словом Знач

Подходит для входных данных, которые менять нельзя: суммы, даты, ссылки на документы. Минус — копирование больших объектов.

Экспортные переменные и обмен между модулями

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

// В общем модуле

Перем ТекущаяНастройка Экспорт;

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

ОбщегоНазначения.ТекущаяНастройка = "Значение";

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

Для глобальных настроек, привязанных к сеансу пользователя (текущий пользователь, отбор по организации), правильное место — параметры сеанса, которые задаются в модуле сеанса и доступны везде через ПараметрыСеанса.ИмяПараметра.

Передача переменной между формами

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

Параметры при открытии формы

Чтобы передать данные в открываемую форму, формируют структуру параметров и передают её в ОткрытьФорму(). В открываемой форме значения доступны через свойство Параметры в обработчике ПриСозданииНаСервере:

// Открывающая форма

ПараметрыФормы = Новый Структура("Контрагент, ДатаОтгрузки", Контрагент, Дата);

ОткрытьФорму("Документ.Заказ.Форма.ФормаПодбора", ПараметрыФормы, ЭтотОбъект);

// Открываемая форма

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("Контрагент") Тогда

ОтборКонтрагент = Параметры.Контрагент;

КонецЕсли;

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

Третий параметр ОткрытьФорму() — владелец формы. Он важен: именно владелец получит оповещение о выборе или закрытии, если дочерняя форма его отправит.

Возврат значения через оповещение

Обратная передача — из открытой формы обратно — делается через описание оповещения. При открытии указывают, какая процедура обработает результат, а дочерняя форма вызывает Закрыть(Результат):

Оповещение = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);

&НаКлиенте

Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

Объект.Контрагент = Результат;

КонецЕсли;

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

Для обмена между уже открытыми формами без связи «владелец-подчинённая» используют Оповестить() и обработчик ОбработкаОповещения() в форме-приёмнике. Имя события — произвольная строка, по которой приёмник отличает своё сообщение от чужих.

Передать значение из одной формы в другую
  1. 1
    В форме-источнике сформируйте структуру с передаваемыми значениями
  2. 2
    Вызовите ОткрытьФорму() с параметрами и укажите владельца
  3. 3
    В открываемой форме прочитайте значения в ПриСозданииНаСервере через Параметры
  4. 4
    Для возврата результата передайте ОписаниеОповещения и закройте форму через Закрыть(Результат)
  5. 5
    Проверьте в отладчике, что значения дошли в оба конца

Передача данных через временное хранилище и фоновые задания

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

Фоновые задания — отдельный сеанс, поэтому переменные туда тоже передаются только явно: массивом параметров в ФоновыеЗадания.Выполнить("ОбщийМодуль.МояПроцедура", МассивПараметров). Результат фоновое задание возвращает через временное хранилище, адрес которого передаётся ему одним из параметров.

Ограничение: через параметры фоновых заданий и временное хранилище нельзя передавать несериализуемые объекты — например, объекты типа «ДокументОбъект» с открытой транзакцией или COM-объекты. Передавайте ссылки и примитивные типы, а объект получайте заново в месте использования.

Типичные ошибки и как их проверить

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

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

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

Типичные ошибки
01
Использование локальной переменной одной процедуры в другой — ошибка «Переменная не определена»; передавайте значение параметром
02
Изменение переданного по ссылке значения без необходимости — побочные эффекты в вызывающем коде; добавьте Знач
03
Чтение Параметров формы в ПриОткрытии вместо ПриСозданииНаСервере — параметры пустые или недоступны
04
Передача ДокументОбъект между клиентом и сервером — ошибка сериализации; передавайте ссылку
05
Экспортная переменная клиентского модуля, читаемая на сервере — значение теряется при клиент-серверном вызове

Для проверки того, что переменная дошла в нужном виде, достаточно отладчика: поставьте точку останова в точке приёмки и посмотрите значение в табло. Быстрая альтернатива при разработке — Сообщить(ТипЗнч(Параметр)) и вывод самого значения, чтобы убедиться, что передан не только правильный объект, но и правильного типа.

Контрольные точки

Как проверить передачу

Значение в точке приёмки через отладчик
Норма

Значение и тип совпадают с переданными

Тревожный признак

Неопределено или другой тип — потеря при передаче

Изменение по ссылке
Норма

Изменения видны в вызывающем коде только там, где задумано

Тревожный признак

Исходная переменная меняется, хотя не должна — добавьте Знач

Параметры формы
Норма

В ПриСозданииНаСервере Параметры.Свойство() возвращает Истина

Тревожный признак

Свойство отсутствует — проверьте структуру при ОткрытьФорму

Итог

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

Внутри модуля переменные передают параметрами процедур и функций: по ссылке — когда нужно изменить данные, со словом Знач — когда нужно их защитить. Между формами — через параметры ОткрытьФорму и оповещения, между сеансами и фоновыми заданиями — через временное хранилище. Локальная переменная недоступна извне никогда — её значение можно только передать.

Частые вопросы

Как передать переменную из одной процедуры в другую в том же модуле?

Укажите её как параметр при вызове: МояПроцедура(МояПеременная). Если вторая процедура должна изменить значение, объявите параметр без Знач — изменения будут видны после возврата. Альтернатива — объявить переменную в разделе переменных модуля, тогда она доступна всем процедурам модуля.

Чем отличается передача по ссылке от передачи по значению в 1С?

По ссылке (по умолчанию) процедура работает с исходной переменной, и её изменения видны в месте вызова. С ключевым словом Знач передаётся копия, и исходная переменная не меняется. Для больших таблиц и структур копирование по значению даёт заметный расход памяти.

Как вернуть несколько значений из функции?

Функция возвращает одно значение, но им может быть структура, массив или таблица значений: Возврат Новый Структура("Сумма, Количество", 100, 5). Второй способ — передать в функцию структуру по ссылке и заполнить её внутри, тогда результат читается из той же структуры после вызова.

Как передать данные из формы списка в форму элемента?

При программном открытии формы элемента передайте структуру параметров вторым аргументом ОткрытьФорму(), а в форме элемента прочитайте её в ПриСозданииНаСервере через Параметры. Для стандартного открытия по двойному щелчку переопределите обработчик Выбор таблицы списка и вызовите ОткрытьФорму() вручную с нужными параметрами.

Почему параметры формы пустые, хотя я их передал?

Чаще всего параметры читаются не в том обработчике: используйте ПриСозданииНаСервере, а не ПриОткрытии. Также проверьте, что имена ключей в структуре при открытии и при чтении через Параметры.Свойство("Имя") совпадают с точностью до регистра не требуется, но до букв — обязательно.

Можно ли передать переменную в фоновое задание?

Да, через массив параметров: ФоновыеЗадания.Выполнить("Модуль.Процедура", МассивПараметров). Передавать можно только сериализуемые значения — примитивные типы, ссылки, структуры, массивы. Объекты типа ДокументОбъект передать нельзя: передавайте ссылку и получайте объект внутри фоновой процедуры. Результат возвращайте через временное хранилище.