Заметки
$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-действие, и не нужно искать причину только в журнале выполнения.