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

Внимание! Материал данной статьи устарел. Рекомендуется использовать документацию к платформе "1С:Предприятие 8".

Встроенный язык 1С:Предприятия поддерживает два способа передачи параметров в процедуры и функции: передача параметров по ссылке и передача параметров по значению. 

Передача параметров по ссылке

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

Пример:

Копировать в буфер обмена
Процедура Процедура1(ФормальныйПараметр1)

        ФормальныйПараметр1 = 2 * 3;

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

ФактическийПараметр = 10;
Процедура1(ФактическийПараметр);

// будет выведено значение 6 - изменение формального
// параметра внутри процедуры повлияло на изменение
// значения фактического параметра, переданного при
// вызове процедуры: по умолчанию, параметры передаются
// по ссылке!
Сообщить(ФактическийПараметр);

Передача параметров по значению

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

Пример:

Копировать в буфер обмена
Процедура Процедура2(Знач ФормальныйПараметр1)

        ФормальныйПараметр1 = 2 * 3;

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

ФактическийПараметр = 10;
Процедура2(ФактическийПараметр);

// будет выведено значение 10 - изменение формального
// параметра внутри процедуры НЕ повлияло на изменение
// значения фактического параметра, переданного при
// вызове процедуры: параметр передан по значению!
Сообщить(ФактическийПараметр);

Особенности передачи переменных различных типов данных по значению

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

Пример 1:

Рассмотрим в качестве примера ситуацию, когда параметром процедуры, передаваемым по значению, является таблица значений. Внутри вызываемой процедуры ОбработатьТаблицу() создается новый экземпляр таблицы значений, в который добавляется три строки. Это никак не влияет на состояние таблицы значений Тз, переданной в качестве фактического параметра при вызове процедуры ОбработатьТаблицу():

Копировать в буфер обмена
// Указано, что передача параметра ТаблЗнач осуществляется по значению
Процедура ОбработатьТаблицу(Знач ТаблЗнач) 

    // Создадим новую таблицу значений
    ТаблЗнач = Новый ТаблицаЗначений;

    // Добавим в таблицу значений две колонки
    ТаблЗнач.Колонки.Добавить("Колонка1"); 
    ТаблЗнач.Колонки.Добавить("Колонка2"); 

    // Добавим несколько строк в таблицу значений
    Для п = 1 По 3 Цикл
        НовСтрока = ТаблЗнач.Добавить(); 
        НовСтрока.Колонка1 = "Колонка"; 
        НовСтрока.Колонка2 = п; 
    КонецЦикла; 

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

// Создадим новую таблицу значений
Тз = Новый ТаблицаЗначений; 

// Добавим в таблицу значений три колонки
Тз.Колонки.Добавить("Колонка1"); 
Тз.Колонки.Добавить("Колонка2"); 
Тз.Колонки.Добавить("Колонка3"); 

// Добавим несколько строк в таблицу значений
Для п = 1 По 10 Цикл
    НовСтрока = Тз.Добавить(); 
    НовСтрока.Колонка1 = "Колонка1"; 
    НовСтрока.Колонка2 = "Колонка2"; 
    НовСтрока.Колонка3 = п; 
КонецЦикла; 

// будет выведено значение 10
Сообщить("Число элементов в ТЗ до обработки: " + Тз.Количество());

// Вызовем процедуру, передав фактический параметр Тз по значению
ОбработатьТаблицу(Тз);

// будет выведено значение 10: внутри процедуры ОбработатьТаблицу
// в формальный параметр сохранили новую таблицу значений
Сообщить("Число элементов в ТЗ после обработки: " + Тз.Количество());

Пример 2:

Рассмотрим в качестве примера ситуацию, когда параметром процедуры, передаваемым по значению, является таблица значений. Внутри вызываемой процедуры СвернутьТаблицу() таблица значений, переданная в качестве параметра при вызове процедуры, сворачивается:

Копировать в буфер обмена
// Указано, что передача параметра ТаблЗнач осуществляется по значению
Процедура СвернутьТаблицу(Знач ТаблЗнач) 

    // Свернем таблицу значений по колонкам Колонка1 и Колонка3
    ТаблЗнач.Свернуть("Колонка1", "Колонка3"); 

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

// Создадим новую таблицу значений
Тз = Новый ТаблицаЗначений; 

// Добавим в таблицу значений три колонки
Тз.Колонки.Добавить("Колонка1"); 
Тз.Колонки.Добавить("Колонка2"); 
Тз.Колонки.Добавить("Колонка3"); 

// Добавим несколько строк в таблицу значений
Для п = 1 По 10 Цикл
    НовСтрока = Тз.Добавить(); 
    НовСтрока.Колонка1 = "Колонка1"; 
    НовСтрока.Колонка2 = "Колонка2"; 
    НовСтрока.Колонка3 = п; 
КонецЦикла; 

// будет выведено значение 10
Сообщить("Число элементов в ТЗ до сворачивания: " + Тз.Количество());

// Вызовем процедуру, передав фактический параметр Тз по значению
СвернутьТаблицу(Тз);

// Таблица значений теперь свернута: будет выведено значение 1
Сообщить("Число элементов в ТЗ после сворачивания: " + Тз.Количество());

Схематично изобразить происходящее при вызове процедуры СвернутьТаблицу(Тз) можно следующим образом:

(1) - вызов процедуры СвернутьТаблицу. В качестве фактического параметра указывается переменная Тз, хранящая ссылку на экземпляр таблицы значений;

(2) - из процедуры вызывается метод Свернуть таблицы значений;

(3) - формальный параметр ссылается на тот же самый экземпляр таблицы значений, что и фактический параметр (переменная Тз) - происходит свертка в экземпляре таблицы значений, на которую ссылается переменная Тз;

(4) - выходим из процедуры. Экземпляр таблицы значений, на которую ссылается переменная Тз, находится в свернутом состоянии.

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

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