Вопрос

Добрый день, форумчане)

Всегда был интересен вопрос след. характера:

В чём отличие типа данных у параметра БП таких как Уникальный идентификатор и Справочник?

Может в Справочник можно как-то внутрь заглянуть и вытянуть displayValue, избегая запрос к root таблице?

Сталкивался кто с подобным, интересен опыт Ваш.

У меня такой же вопрос

1 комментарий

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

_processSchemaParameter1 = () => { return (Guid)(new Guid("b06f1e0e-f46b-1410-7190-00155d043204")); };
_processSchemaParameter2 = () => { return (Guid)(new Guid("b06f1e0e-f46b-1410-7190-00155d043204")); };
...
private Func<Guid> _processSchemaParameter1;
public virtual Guid ProcessSchemaParameter1 {
	get {
return (_processSchemaParameter1 ?? (_processSchemaParameter1 = () => Guid.Empty)).Invoke();
	}
	set {
_processSchemaParameter1 = () => { return value; };
	}
}
 
private Func<Guid> _processSchemaParameter2;
public virtual Guid ProcessSchemaParameter2 {
	get {
return (_processSchemaParameter2 ?? (_processSchemaParameter2 = () => Guid.Empty)).Invoke();
	}
	set {
_processSchemaParameter2 = () => { return value; };
	}
}
...
private void WritePropertyValues(DataWriter writer, bool useAllValueSources) {
	if (!HasMapping("ProcessSchemaParameter1")) {
writer.WriteValue("ProcessSchemaParameter1", ProcessSchemaParameter1, Guid.Empty);
	}
	if (!HasMapping("ProcessSchemaParameter2")) {
writer.WriteValue("ProcessSchemaParameter2", ProcessSchemaParameter2, Guid.Empty);
	}
}
 
...
protected override void InitializeMetaPathParameterValues() {
	base.InitializeMetaPathParameterValues();
	MetaPathParameterValues.Add("e0873088-8334-4b85-96a4-fa3e5ecb7374", () => ProcessSchemaParameter1);
	MetaPathParameterValues.Add("246467c7-071b-4cb0-8073-30c4f72be120", () => ProcessSchemaParameter2);
...	
protected override void ApplyPropertiesDataValues(DataReader reader) {
	base.ApplyPropertiesDataValues(reader);
	bool hasValueToRead = reader.HasValue();
	switch (reader.CurrentName) {
case "ProcessSchemaParameter1":
	if (!hasValueToRead) break;
	ProcessSchemaParameter1 = reader.GetValue<System.Guid>();
break;
case "ProcessSchemaParameter2":
	if (!hasValueToRead) break;
	ProcessSchemaParameter2 = reader.GetValue<System.Guid>();
break;
	}
}
...

А в метаданных:

      "Parameters": [
        {
          "TypeName": "Terrasoft.Core.Process.ProcessSchemaParameter",
          "UId": "e0873088-8334-4b85-96a4-fa3e5ecb7374",
          "Name": "ProcessSchemaParameter1",
          "CreatedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395",
          "ModifiedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395",
          "DataValueType": "b295071f-7ea9-4e62-8d1a-919bf3732ff2",
          "SourceValue": {
            "Source": 3,
            "Value": "[#Lookup.c449d832-a4cc-4b01-b9d5-8a12c42a9f89.b06f1e0e-f46b-1410-7190-00155d043204#]",
            "ModifiedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395"
          },
          "ReferenceSchemaUId": "c449d832-a4cc-4b01-b9d5-8a12c42a9f89"
        },
        {
          "TypeName": "Terrasoft.Core.Process.ProcessSchemaParameter",
          "UId": "246467c7-071b-4cb0-8073-30c4f72be120",
          "Name": "ProcessSchemaParameter2",
          "CreatedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395",
          "ModifiedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395",
          "DataValueType": "23018567-a13c-4320-8687-fd6f9e3699bd",
          "SourceValue": {
            "Source": 3,
            "Value": "[#Lookup.c449d832-a4cc-4b01-b9d5-8a12c42a9f89.b06f1e0e-f46b-1410-7190-00155d043204#]",
            "ModifiedInSchemaUId": "f4c123c0-d628-4d9f-867c-6c0b78c86395"
          }
        }
      ],

То есть разницы практически нет, хотя внешний вид и интерфейс выбора значения разные.

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

select top 10 *, cast(PropertiesData as varchar(max)) from SysProcessData

Там для параметров видно тоже только Id.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

В БД ничего похожего найти не смог 
Есть какие-нибудь идеи по удалению процесса?

Сам процесс перестал открываться, выбрасывает из конфигуратора на стандартную страницу ошибки

У меня такой же вопрос

2 комментария
Лучший ответ

Начните с этого поста

Начните с этого поста

И с этого.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Всем привет.

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

Заранее спасибо за помощь.

У меня такой же вопрос

2 комментария
Лучший ответ

Начиная с версии 7.12.3 все создаваемые бизнес-процессы в bpm’online являются интерпретируемыми. Для обращения к значениям параметра процесса следует использовать методы get и set 

Метод Get возвращает значение параметра элемента или процесса.

Сигнатура метода:

Get<T>(string path)

где:

T — тип значения параметра;

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам:

“имя параметра”,

“имя свойства”,

“имя элемента.имя параметра”,

“имя элемента.имя свойства”.

Метод Set указывает значение параметру элемента или процесса.

Сигнатура метода:

Set(string path, T value)

где:

value — указываемое значение,

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам, описанным выше для метода Get.

 

Так например чтобы получить в скриптаске UserConnection нужно использовать конструкцию:

UserConnection userConnection = Get<UserConnection>("UserConnection");

Чтобы получить строковый параметр БП:

string message = Get<string>("Message");

Подробнее тут

Начиная с версии 7.12.3 все создаваемые бизнес-процессы в bpm’online являются интерпретируемыми. Для обращения к значениям параметра процесса следует использовать методы get и set 

Метод Get возвращает значение параметра элемента или процесса.

Сигнатура метода:

Get<T>(string path)

где:

T — тип значения параметра;

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам:

“имя параметра”,

“имя свойства”,

“имя элемента.имя параметра”,

“имя элемента.имя свойства”.

Метод Set указывает значение параметру элемента или процесса.

Сигнатура метода:

Set(string path, T value)

где:

value — указываемое значение,

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам, описанным выше для метода Get.

 

Так например чтобы получить в скриптаске UserConnection нужно использовать конструкцию:

UserConnection userConnection = Get<UserConnection>("UserConnection");

Чтобы получить строковый параметр БП:

string message = Get<string>("Message");

Подробнее тут

Григорий Чех,

Спасибо большое! Как-то этот мануал мимо меня прошёл.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

У меня есть элемент "Читать данные", у него есть ИД, Имя, и другие параметры сущности, которую считали. Как получить значения этих параметров из кода в элементе "Задание-сценарий"?

У меня такой же вопрос

2 комментария
Лучший ответ

Добрый день! вот ссылка на статью https://academy.terrasoft.ru/documents/technic-bpms/7-12/element-proces…
 

Метод Get возвращает значение параметра элемента или процесса.

Сигнатура метода:

Get<T>(string path)

где:

T — тип значения параметра;

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам:

•“имя параметра”,

•“имя свойства”,

•“имя элемента.имя параметра”,

•“имя элемента.имя свойства”

Добрый день! вот ссылка на статью https://academy.terrasoft.ru/documents/technic-bpms/7-12/element-proces…
 

Метод Get возвращает значение параметра элемента или процесса.

Сигнатура метода:

Get<T>(string path)

где:

T — тип значения параметра;

path — строка, определяющая путь к параметру или свойству. Путь формируется согласно правилам:

•“имя параметра”,

•“имя свойства”,

•“имя элемента.имя параметра”,

•“имя элемента.имя свойства”

Вы можете нужные Вам значения из элемента "Читать данные" добавить в параметры бизнес-процесса (БП), а потом в элементе "Задание-сценарий" вычитать их из параметров БП с помощью метода Get

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

В процессе использую параметр с типом Коллекция объектов. Значение данного параметра передается в процесс из родительского процесса. Далее в элементе с типом задание сценарий происходит некая работа с коллекцией (по сути коллекция передается в другой метод, сами ее значения не меняются). После чего по условию БП либо идет дальше, либо возвращается в данный же кубик задание сценарий и должен снова вызвать метод и передать данную коллекцию в качестве параметра. Однако, при повторном заходе в задание сценарий, БП падает с ошибкой 

Terrasoft.Common.ItemNotFoundException: Элемент с идентификатором "00000000-0000-0000-0000-000000000000" не найден
   в Terrasoft.Core.ManagerItemCollection`1.GetByUId(Guid uid)
   в Terrasoft.Core.Manager`2.GetInstanceByUId(Guid uid)
   в Terrasoft.Core.Process.GetGoldWarrantyAmountProcess.get_ProductConditionCollection()
   в Terrasoft.Core.Process.GetGoldWarrantyAmountProcess.ScriptTask1Execute(ProcessExecutingContext context)
   в Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)

Насколько я понимаю, это именно ошибка чтения параметра - коллекции объектов. 
В связи с этим у меня возникает вопрос: как корректно передавать параметр с типом коллекция объектов в другой БП, чтобы цикл его жизни не был равен одному запуску дочернего БП, а был доступен на всем протяжении работы данного БП?

У меня такой же вопрос

1 комментарий

Судя по тому, что в первый раз передалось нормально, потом значение переменной кто-то очищает. Если есть возможность, можно произвести отладку и посмотреть, какое значение в разные моменты находится в параметре.

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

У меня такой же вопрос

2 комментария

Здравствуйте! Попробуйте передавать по каналу web-socket
Код на стороне БП

var userConnection = Get<UserConnection>("UserConnection");
var messageToUser = Get<string>("AbMessageToUser");
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(userConnection, "AbCreatingSmsAudienceProcess", messageToUser);
return true;

На клиенте следующий код
 

define("ContactSectionV2", [], function() {
	return {
		entitySchemaName: "Contact",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},
			subscriptionFunction: function() {
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.onAbCreatingSmsAudienceProcessMessage, this);
			},
			onAbCreatingSmsAudienceProcessMessage: function(scope, message) {
				if (!message || message.Header.Sender !== "AbCreatingSmsAudienceProcess") {
					return;
				}
				var message2 = message.Body;
				if (!this.Ext.isEmpty(message2)) {
					this.Terrasoft.showInformation(message2);
				}
			}
		},
		messages: {}
	};
});

 

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

 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.

Запускаю  БП из действия раздела:

var selectedRows = this.get("SelectedRows");
var accounts = selectedRows.join();
var processName = "UsrChangeAccountOwnerProcess";

var params = {
	AccountIds: accounts
};
ProcessModuleUtilities.runProcess(processName, params);

При запуске БП по выделенным записям (более 50 записей) возвращается ошибка:

https://yadi.sk/i/k7KXj5VE3PTDoj

Предположительно ошибка связана с длиной строки с идентификаторами выделенных записей, которая передаётся в параметр процесса. Т.к. если выделено до 50 записей, то БП запускается. 
Вопросы:
Как снять ограничение на длину параметра?
Можно ли запустить БП с использованием callService, передав параметры в виде jsonData, а не в url?

У меня такой же вопрос

3 комментария

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

Терещук Сергей,

А с чем связана описанная мной проблема?

Коновалов Игорь,

Я думаю, что это вызвано ограничениями, которые прописаны для WCF сервиса, который вызывается. В частности, 

maxReceivedMessageSize. Но я могу и ошибаться.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

День добрый, Коллеги!

Необходима помощь в решении нескольких тривиальных задач при построении БП (решение желательно листинг простенький или ссылку)

1) Как программно через элемент БП задание-сценарий получить ID созданной записи из элемента Страница редактирования

2) Как программно через элемент БП задание-сценарий получить/установить параметр БП

3) Как в условном потоке написать условие ID!=null, при том что ID с типом уникальный идентификатор

Данные вопросы возникли при решении простой задачи: при входе в подпроцесс на него передается AccountID -> при старте БП идет проверка AccountID есть/нет
если есть, то идем к шагу задачи
если нет, то идем на шаг с создание Контрагента

На данный момент реализация проверки на AccountID!=null довольно убогая... через чтение данных получаю count записей с id = AccountID и в условном потоке проверяю сравнением...

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

p.p.s. Я пытался найти описание методов для получения коллекции параметров БП в SDK, но не нашел ) если они там есть и я просто проглядел - скиньте ссылку

Заранее спасибо!

У меня такой же вопрос

4 комментария

Артем, добрый день.

Прежде всего, хочу уточнить, что в стартовом элементе с типом "Сигнал" можно сразу же задать условия, выполнение которых является обязательным для старта БП по данному сигналу:

Но, т.к. в таком случае, Вам бы пришлось создать два БП, рассмотрим конкретно Ваш кейс.
БП будет следующим:

Стартовое сообщение - сигнал на объекте "Активность" после добавления новой записи.
Далее в элементе "Чтение данных" считываем все поля записи, по которой был запущен процесс:

После этого, создаем условный поток к элементу "Создание нового контрагента", условие следующее:

ReadDataUserTask1.ResultEntity.GetTypedColumnValue<Guid>("Account.Id") != Guid.Empty

где ReadDataUserTask1 - название элемента "Чтение данных".

и потом добавляем поток по умолчанию к элементу "Создать новую задачу".

В принципе это всё.

Если будут вопросы - обращайтесь.

Спасибо, Дмитрий!
Вопрос N3 можно считать решенным ) (не знал что в условии можно использовать C#)

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

если при старте родительского БП AccountID был заполнен (была связь Лида с контрагентом), то передавать далее в подпроцесс необходимо именно его
, а если при старте родительского БП AccountID пустой (например Лида квалифицировали как контакт и поле Контрагент пустое), то передавать далее в подпроцесс необходимо идентификатор записи из шага "Создайте нового контрагента".

Можно конечно решить вопрос с помощью конструктора, но это избыточность в чистом виде =\ куда проще мне было бы вставить после шага "Создайте нового контрагента" скриптик, который просто заполнил бы параметр процесса AccountID идентификатором созданной записи из шага "Создайте нового контрагента" + я практически на 100% уверен что в будущем еще не раз придется работать с параметрами БП через скрипт.

Так что вопросы 1,2 все еще актуальны

Артём, добрый день.

Если Вы добавили в структуру процесса параметр MyParam с типом GUID, то обратиться к нему можно просто:

MyParam = new Guid(stringGuid);
Guid fromParam = MyParam;

это по второму вопросу. Т.е. обращаемся в любом скрипте процесса по имени параметра.

По первому вопросу:

Если Вы раскроете действие "Открыть карточку редактирования", то увидите там параметр RecordId, с него и считывайте:

Guid recordId = OpenPageElement1.RecordId;

Спасибо Дмитрий!
На этот раз все вопросы сняты

С уважением,
Волков Артем

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте!

Первый элемент БП - Открытие окна (создается новый документ).
Второй элемент БП - Задача.

Подскажите пожалуйста, как передать из первого элемента значение какого-либо поля (в моем случае Контрагента) во второй элемент и как передать ID этого созданного документа, т.е. чтобы в задаче, которая создается после документа, в поле Документ стоял созданный документ.

У меня такой же вопрос

1 комментарий

Здравствуйте!

Необходимо создать параметр диаграммы AccountID, параметр DocumentID уже должен быть создан автоматически, если нет - создайте и его:

1

Далее, настройте соответствие параметров на первом шаге:

2

Задачу, рекомендую Вам создавать с помощью элемента открытия окна редактирования, аналогично настроив соответствие полям карточки и параметрам диаграммы.

Войдите или зарегистрируйтесь, чтобы комментировать
Публикация

При автоматическом запуске процессов
1
есть вопрос, как получить параметр, по которому мы запустили процесс
К примеру, мы создали условия для автоматического запуска по созданию записей в реестре, и хотим получить ID записи, по которой мы запустили процесс.
Для этого на элементе Start БП определим событие OnStart
2
Создадим параметр диаграммы AutoID
3
В коде

function Item1OnStart(StartItem) {
        var ParentDiagram = GetDiagramByItem(StartItem);
        var RecordID = WFGetParamValue(ParentDiagram, 'AutoID');
}

После чего имеем ID записи в переменной RecordID

Поделиться

12 комментариев

Здравствуйте! Делаю так, как описано, но GetDiagramByItem(StartItem) выдает ошибку, пишет "предполагается наличие объекта".

Решение найдено, нужно было добавить в используемые скрипты scr_WorkflowUtils.

Добавлю маленький комментарий, если есть желание дополнительно записать в параметры значения по ключевому полю RecordID, разумно воспользоваться функцией GetDatasetFieldValueByID с scr_DB

var CustomerID = GetDatasetFieldValueByID('ds_Opportunity',RecordID ,'CustomerID'); //Подключаем scr_DB, 
WFSetParamValue(StartItem,'AccountID',CustomerID);

Подскажите каким образом можно реализовать передачу ID продукта, по которому автоматически запускается БП, в параметр диаграммы?

Здравствуйте, Василий.

Сделайте точно также как описано в этой теме. Т.е. создайте параметр диаграммы типа строка с именем, к примеру, StartedProductID.

Далее, определите событие OnStart для элемента Start. И в коде считайте значение этого параметра (в нем и будет хранится ID продукта, по которому запущен БП):

function Item1OnStart(StartItem) {
        var ParentDiagram = GetDiagramByItem(StartItem);
        var RecordID = WFGetParamValue(ParentDiagram, 'StartedProductID');
}

А если не получится так сделать как говорит Дмитрий, назовите параметр AutoID :wink:

   var RecordID = WFGetParamValue(ParentDiagram, 'AutoID');

Честно я не понял в какой момент заполняется параметр диаграммы что StartedProductID, что AutoID :wink: изначально. Как их получить понятно, не понятно почему они будут иметь нужные значения.

Кирилл, заполняется этот параметр (AutoID) в момент старта процесса (если такой параметр диаграммы существует).
Сам процесс заполнения параметра реализован при создании триггера на таблицу, который при срабатывании передает значение ID записи по которой он сработал в БП.

Так значит нужно именно AutoID, а не к примеру StartedProductID? :smile:

Да, именно так. :)

Подскажите, пожалуйста, есть несколько задач в БП, как мне получить ID выполненной задачи при старте следующей?

как всегда, когда что-нибудь спросишь ответ сам находится

Войдите или зарегистрируйтесь, чтобы комментировать