← Назад к заметкам

Заметки

$this->SetVariable() в PHP-активити: где работает и где нет

Как SetVariable работает в PHP-активити бизнес-процесса Bitrix24: переменные процесса, глобальные переменные, поля документа и типы значений.

$this->SetVariable() меняет переменную текущего экземпляра бизнес-процесса. Это не обновление поля CRM, не изменение глобальной переменной портала и не создание новой переменной в шаблоне. Переменную лучше заранее создать в дизайнере БП и передавать в неё значение подходящего типа.

Задача

В PHP-активити часто нужно вернуть результат обратно в бизнес-процесс: ID найденной сделки, список пользователей, сумму, статус выполнения или текст ошибки.

Для этого используют $this->SetVariable(). На простом примере всё выглядит очевидно:

$this->SetVariable('ResultText', 'Готово');

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

Из-за этого код формально выполняется, но дальше в БП значение не появляется там, где его ожидали.

Где работает SetVariable

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

Типичный сценарий: прочитать одну переменную, обработать значение в PHP и сохранить результат в другую переменную.

$root_activity = $this->GetRootActivity();

$deal_id = (int)$root_activity->GetVariable('DealId');

if ($deal_id > 0) {
    $this->SetVariable('ProcessedDealId', $deal_id);
}

После этого переменную ProcessedDealId можно использовать в следующих действиях процесса: в условии, уведомлении, создании задачи или другом PHP-действии.

Лучше не рассчитывать, что SetVariable «сам создаст» удобную переменную для дальнейшего выбора в дизайнере. Для нормальной поддержки процесса переменную нужно завести заранее и дать ей понятный код: ProcessedDealId, PhpActivityStatus, ResponsibleUsers.

Где SetVariable не поможет

Самая частая ошибка — думать, что переменная БП и поле документа это одно и то же. Это разные вещи.

Такой код не должен восприниматься как обновление пользовательского поля CRM:

$this->SetVariable('UF_CRM_1234567890', 'Новое значение');

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

// SetVariable не меняет поле документа.
// Для изменения поля CRM нужно использовать действие БП,
// REST, D7 или CRM API — в зависимости от задачи.

Также SetVariable не меняет параметр шаблона бизнес-процесса. Параметры задаются при запуске процесса, а переменные используются уже внутри выполнения. Если нужно передать результат дальше по процессу, обычно нужна именно переменная.

Ещё один нюанс: переменная меняется в текущем экземпляре процесса. Если тот же шаблон запустится ещё раз, у нового запуска будет своё значение переменной.

Типы значений

Значение, которое передаётся в SetVariable, должно подходить типу переменной в бизнес-процессе.

Для строки можно передать обычный текст, для числа — число, для флага — ожидаемое значение вроде Y или N.

$amount = 15000.75;

$this->SetVariable('PaymentAmount', $amount);
$this->SetVariable('IsNeedRepeat', 'Y');

Для переменной типа «Пользователь» обычно передают значения в формате user_ID. Если переменная множественная, передаётся массив.

$this->SetVariable('ResponsibleUsers', [
    'user_1',
    'user_2',
]);

Для множественных переменных логика такая же: если переменная ждёт несколько значений, передавайте массив, а не строку с ID через запятую.

$this->SetVariable('SelectedIds', [
    15,
    27,
    39,
]);

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

$this->SetVariable('StatusId', '3887');

Если после записи переменная не подставляется в действие, сначала стоит посмотреть не на сам SetVariable, а на тип переменной: одиночная она или множественная, какой формат пользователя ожидается, не передаётся ли строка туда, где нужен массив.

Глобальные переменные

Глобальные переменные бизнес-процессов — отдельная сущность. Их удобно использовать как настройки, но SetVariable не делает переменную процесса глобальной.

Например, такой код просто запишет значение в переменную текущего процесса GlobalManagerId, если такая переменная есть в шаблоне:

$this->SetVariable('GlobalManagerId', 'user_1');

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

$global_variable = \Bitrix\Bizproc\Workflow\Type\GlobalVar::getById('managerId');

if ($global_variable) {
    $this->SetVariable('ManagerFromGlobalVar', $global_variable['Default']);
}

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

Для отладки результата удобно хранить отдельные служебные переменные статуса и ошибки:

try {
    $this->SetVariable('PhpActivityStatus', 'success');
    $this->SetVariable('PhpActivityError', '');
} catch (Throwable $exception) {
    $this->SetVariable('PhpActivityStatus', 'error');
    $this->SetVariable('PhpActivityError', $exception->getMessage());
}

Тогда следующие действия БП могут понять, успешно ли отработало PHP-действие, и не нужно искать причину только в журнале выполнения.