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

Программист IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем, почему возникает эта ошибка, рассмотрим два основных способа решения задачи (передача через параметры и использование переменных модуля), а также проанализируем лучшие практики написания кода, чтобы избежать ошибок в будущем.

Суть проблемы: локальная область видимости

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


Процедура Первая() Экспорт 
    а = 1; 
    b = 2; 
    Вторая(); 
КонецПроцедуры

Процедура Вторая() Экспорт 
    с = b + a; // Ошибка: Переменные не определены
КонецПроцедуры

Когда мы объявляем переменные а и b внутри процедуры Первая, они становятся локальными. Это означает, что они существуют в памяти компьютера только в тот момент, когда выполняется процедура Первая. Как только выполнение переходит в процедуру Вторая, контекст меняется. Процедура Вторая ничего не знает о том, что происходило внутри Первая, и не имеет доступа к её локальным переменным.

Чтобы исправить это, нам нужно явно передать данные. Рассмотрим варианты решения.

Способ 1: Передача данных через параметры (Рекомендуемый)

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

Давайте изменим определение нашей второй процедуры, добавив в скобки имена параметров, которые она будет принимать:


Процедура Вторая(ЗначениеА, ЗначениеБ) Экспорт 
    // Теперь мы работаем с переданными значениями
    с = ЗначениеА + ЗначениеБ; 
    // Здесь можно выполнять дальнейшие действия с переменной "с"
КонецПроцедуры

Теперь процедура готова принимать данные. Обратите внимание, что имена параметров (ЗначениеА, ЗначениеБ) не обязаны совпадать с именами переменных в вызывающей процедуре (а, b). Это разные сущности.

Теперь настроим вызов из первой процедуры:


Процедура Первая() Экспорт 
    а = 1; 
    b = 2; 
    // Передаем переменные "а" и "b" внутрь процедуры "Вторая"
    Вторая(а, b); 
КонецПроцедуры

Как это работает:

  1. При вызове метода Вторая(а, b) платформа берет значение переменной а и помещает его в первый параметр метода Вторая (который мы назвали ЗначениеА).
  2. Значение переменной b помещается во второй параметр (ЗначениеБ).
  3. Внутри процедуры Вторая производятся вычисления с уже доступными данными.

Важный нюанс: Передача по ссылке и по значению (Знач)

В 1С существует важная особенность передачи параметров. По умолчанию параметры передаются по ссылке. Давайте разберем, что это значит, на примере.


Процедура Первая() 
    а = 1;
    ИзменитьЧисло(а);
    // Чему равно "а" здесь? Оно станет равно 10!
КонецПроцедуры

Процедура ИзменитьЧисло(ВходящееЧисло)
    ВходящееЧисло = 10;
КонецПроцедуры

Так как передача идет по ссылке, переменная ВходящееЧисло ссылается на ту же ячейку памяти, что и переменная а. Изменяя одну, мы меняем и другую.

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


Процедура Вторая(Знач ЗначениеА, Знач ЗначениеБ) Экспорт
    // Изменения переменных здесь НЕ повлияют на переменные в процедуре "Первая"
    с = ЗначениеА + ЗначениеБ;
КонецПроцедуры

Использование Знач считается хорошим тоном, если процедура не должна возвращать измененные данные через параметры.

Способ 2: Использование переменных модуля (Не рекомендуется для Экспортных процедур)

Второй способ заключается в расширении области видимости переменных. Мы можем объявить переменные в самом начале модуля (вне процедур). Такие переменные называются переменными модуля.


Перем ГлобальнаяА;
Перем ГлобальнаяБ;

Процедура Первая() Экспорт 
    // Мы не объявляем новые переменные, а используем объявленные выше
    ГлобальнаяА = 1; 
    ГлобальнаяБ = 2; 
    Вторая(); 
КонецПроцедуры

Процедура Вторая() Экспорт 
    // Процедура "видит" переменные модуля
    с = ГлобальнаяА + ГлобальнаяБ; 
КонецПроцедуры

Почему этот способ работает?
Ключевое слово Перем в заголовке модуля делает эти переменные доступными для всех процедур и функций данного модуля. Они живут столько же, сколько живет сам программный модуль (например, пока открыта форма).

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

  1. Непредсказуемость состояния. Если процедуру Вторая вызовут из другого места программы, неизвестно, какие значения будут в переменных ГлобальнаяА и ГлобальнаяБ. Они могут быть пустыми или содержать мусор от прошлых вычислений.
  2. Сложность отладки. Когда переменных модуля много, очень сложно отследить, какая именно процедура и в какой момент изменила их значение.
  3. Связность кода. Процедуры перестают быть самостоятельными единицами. Вы не можете просто скопировать процедуру Вторая в другой модуль, так как она зависит от внешних переменных.

Использование необязательных параметров

Иногда нам нужно сделать процедуру универсальной, чтобы в неё можно было передавать параметры, а можно было и не передавать. В 1С это реализуется через параметры по умолчанию.

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


Процедура Вторая(ЗначениеА = 0, ЗначениеБ = 0) Экспорт 
    с = ЗначениеА + ЗначениеБ;
    // Если вызвать Вторая(), то с = 0 + 0
    // Если вызвать Вторая(5), то с = 5 + 0
КонецПроцедуры

Конструкция = 0 задает значение по умолчанию. Если при вызове параметр пропущен, платформа подставит ноль (или любое другое указанное вами значение, например Неопределено или пустую строку).

Резюме и рекомендации

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

Следуя этим простым правилам, вы сможете избежать "каши" в коде и ошибок с видимостью переменных, характерных для этапа обучения.

← На главную