Hello community,

 

We have a use case where some business logic has been implemented as a business process and the output of it is set to 2 business process parameters. We need to trigger this BP from source code and read the output parameters after execution of the process. The execution part is straight forward. The reading of parameters is not. 

 

I went through various articles/questions on the community related to these. But most of them only talk about executing a process by setting parameters and not reading parameters after execution. Request some assistance.

I also went through the IProcessExecutor documentation here and it permits to retrieve one result parameter. What if I need to read more than 1 parameter at the end of the business process execution?? Is there any other way to execute a BP from server side code and get the output parameter?

Note - I am aware that the Business process can be executed via a Http call to the ProcessEngineService and output parameters retrieved via the ResultParameterName query parameter. This is not a viable option for us. Additionally, it only permits one ResultParameterName and not reading multiple business process parameters.

Like 0

Like

2 comments
Best reply

Hello,

 

You can use this example to receive parameters: 

// getting UserConnectionUserConnection userConnection = GetUserConnection();
// getting  IProcessExecutor
IProcessExecutor processExecutor = userConnection.ProcessEngine.ProcessExecutor;
// List of input parameters
var inputParameters = new Dictionary<string, string> {
    ["ProcessSchemaParameter1"] = "Value1",
    ["ProcessSchemaParameter2"] = "Value2"
};
//  List of output parameters
var resultParameterNames = new string[] {
    "ProcessSchemaParameter3",
    "ProcessSchemaParameter4"
};
string processSchemaName = "processSchemaName";
Guid processSchemaUId = Guid.Parse("00000000-0000-0000-0000-000000000000");
 
// Run the process by schema name and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, resultParameterNames);
// Run the process by schema UId and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, resultParameterNames);
 
//  Run the process by schema name with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, inputParameters, resultParameterNames);
// Run the process by schema UId with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, inputParameters, resultParameterNames);

You can also get values of the resulting parameters by accessing the ResultParameterValues property of the IReadOnlyDictionary <string, object> type of the ProcessDescriptor class: 

ProcessDescriptor processDescriptor = processExecutor.Execute("processSchemaName", inputParameters, resultParameterNames);
object parameter3Value = processDescriptor.ResultParameterValues["ProcessSchemaParameter3"];
if (processDescriptor.ResultParameterValues.TryGetValue("ProcessSchemaParameter4", out object parameter4value)) {
    Console.Log(parameter4value);
}

Please note that such process will always be run in not-background mode and you will be able to receive several parameters only from version 7.17.1. 

 

Best regards,
Angela

Hello,

 

You can use this example to receive parameters: 

// getting UserConnectionUserConnection userConnection = GetUserConnection();
// getting  IProcessExecutor
IProcessExecutor processExecutor = userConnection.ProcessEngine.ProcessExecutor;
// List of input parameters
var inputParameters = new Dictionary&lt;string, string&gt; {
    ["ProcessSchemaParameter1"] = "Value1",
    ["ProcessSchemaParameter2"] = "Value2"
};
//  List of output parameters
var resultParameterNames = new string[] {
    "ProcessSchemaParameter3",
    "ProcessSchemaParameter4"
};
string processSchemaName = "processSchemaName";
Guid processSchemaUId = Guid.Parse("00000000-0000-0000-0000-000000000000");
 
// Run the process by schema name and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, resultParameterNames);
// Run the process by schema UId and forwarding output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, resultParameterNames);
 
//  Run the process by schema name with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaName, inputParameters, resultParameterNames);
// Run the process by schema UId with forwarding input and output parameters
ProcessDescriptor processDescriptor = processExecutor.Execute(processSchemaUId, inputParameters, resultParameterNames);

You can also get values of the resulting parameters by accessing the ResultParameterValues property of the IReadOnlyDictionary <string, object> type of the ProcessDescriptor class: 

ProcessDescriptor processDescriptor = processExecutor.Execute("processSchemaName", inputParameters, resultParameterNames);
object parameter3Value = processDescriptor.ResultParameterValues["ProcessSchemaParameter3"];
if (processDescriptor.ResultParameterValues.TryGetValue("ProcessSchemaParameter4", out object parameter4value)) {
    Console.Log(parameter4value);
}

Please note that such process will always be run in not-background mode and you will be able to receive several parameters only from version 7.17.1. 

 

Best regards,
Angela

Angela Reyes,

Thank you Angela for the inputs

Show all comments

we have a custom button on the section page that triggers a process.

When the business process returns to the section page code, is it possible to capture a return parameter from the process  ? how ?

Like 0

Like

1 comments

The issue is that the process will execute asynchronously. The only way to get the value back from the process is, instead of using it as an output param, to send it as a message using a script task in the process that you will retrieve with client-side code on the page. 

You can see an article outlining how to do this here: https://customerfx.com/article/sending-a-message-from-server-side-c-to-…

 

Basically, at the end of your process, you'll add a script task. In that script task you'll get the param value, then send it as a message (as outlined in the article). Then, in your page code, you'll listen for that message, check to make sure it's the message sent from your process, and then read the value and do whatever is needed with it.

Ryan

Show all comments

What is the data type to read a date parameter in a script task ?

 

var myVar = Get<????>("MyParameter") 

 

Like 0

Like

3 comments
Best reply

You would use:

 

var myDate = Get<DateTime>("MyDateParam");

 

A date only param is still just a .NET DateTime struct just like a Date and Time value in Creatio -  A date only will just have a zero time value (so the value would be something like "Oct 29, 2020 00:00:00")

Ryan

You would use:

 

var myDate = Get<DateTime>("MyDateParam");

 

A date only param is still just a .NET DateTime struct just like a Date and Time value in Creatio -  A date only will just have a zero time value (so the value would be something like "Oct 29, 2020 00:00:00")

Ryan

Hi Ricardo,

 

Indeed, you can use the solution suggested above. However, please note that you'll get the date in a server timezone.

var myDate = Get<DateTime>("MyDateParam");

 

There is an option to pass a string as usual and parse it then. Also, you can pass ticks and use the result. For example: 

long ticks = Get<long>("MyDateParameterInTicks");

new DateTime(ticks, DateTimeKind.Utc).ToLocalTime();

 

Please read more about ticks property by the link below:

https://docs.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=…

 

Regards,

Anastasiia

Anastasiia Markina,

That is good to know, thanks Anastasiia.

Show all comments

Hi. I am getting the this error :

When I compile the script task:

What is missing ? Please help.

Like 0

Like

4 comments

IIRC the DataValueType param expected here isn't an enum. Try changing the code to add this:

var dataValueTypeManager = (DataValueTypeManager)userConnection.AppManagerProvider.GetManager("DataValueTypeManager");
var textDataValueType = (TextDataValueType)dataValueTypeManager.GetInstanceByName("Text");

 

Then use:

storedProcedure.WithOutputParameter("res_msg", textDataValueType);

Ryan

Ryan Farley,

Thanks. Now it runs.

But sorry, I still need some help on recovering the output prm from the stored procedure. It always returns "Core.DB.QueryParameter", instead of the string returned by the SP.

 

Ricardo Bigio,

You can capture that using this:

var resultParameter = (string)storedProcedure.Parameters.FindByName("res_msg").Value;

Ryan

Perfect. Thanks

Show all comments

Which C# data type (decimal, double, etc) should I use in a script task "Get<datatype>("ProcessParameter")" for decimal process parameters?

 

Like 0

Like

2 comments

Hi Ricardo

You should use System.decimal C# type.
And it's a C# structure in .NET and .NET Core.
https://docs.microsoft.com/en-us/dotnet/api/system.decimal?view=netcore…

 

Thank you

Mohamed
 

Hi Ricardo, 

 

Indeed, you can use System decimal C# type as Mohamed mentioned above. However, in case of any difficulties, please try the standard int datatype.

 

Regards, 

Anastasiia

Show all comments

I attempted to get a lookup value in an email body, however it came through as the Id of the lookup value.

I tried to create a text process parameter and use a formula: [#Read PCR Data.First item of resulting collection.PCR Change Type#].ToString()

I expected the result to look like thisL reason: "Proactive Break/Fix"

however the result looked like this: reason: "ec15074d-4b35-4191-ae85-5bf01144101a"

How can I get the text value instead of the id?

Like 0

Like

2 comments

Mitch, 

You will have to read the lookup within the PCR Data, in your example not only do you have to "Read PCR Data" but you should also read the "PCR Change Type" lookup (in another element) which is in the object you are already reading.

The filtration will be something like 'ID = Read PCR Data.PCR Change Type'.

Extra** The reason you got your result (and why it is still technically true) is because you are only reading the UID value of the lookup and not the Name value - there is some magic that happens to connect the UID.Name in the view. So what your code is doing is casting the UID 'type' to string 'type'.

Hope this helps!

Philip Wierciszewski,

Perfect! thanks so much!

Show all comments

Hello. I have two critical ideas for improving Parameter selection for example in Email Templates, especially the Macros.

Ability to JOIN datatypes on reverse relation.
Example: I am working with Email Template of type Order. I have no chance to included products of the order because the relation is this:

Order <-- Products in Order <-- Product

If u had ability to join Products in Order on OrderID and then Product on ProductID I could show it.
SQL Code would be:

SELECT * FROM Order
JOIN Products in Order AS PiO on PiO.OrderID = Order.OrderID
JOIN Product on Product.ProductID= PiO.ProductID

 

Then I could use the other tables data through join. Currently this is not possible as far as I can tell.

We should be able to join everywhere in bpm'online where we use the parameter-menu:

However it is possible to do JOIN on Printable tables and on Details:

 

To summarize: I can have foreign table data shown on Details and Printables. But not for example in Email Template. I believe this is very important

3 comments

I can get a Table of my Products and Products in Order when setting up a Detail or a Printable Table. I need to be able to do the same with Email Template > Macros

Hi Julius,

Totally support the idea. We are having this need in nearly every project and allways have to find a workaround.

Rgds,

Luis

Hello Julius!

We have already registered a query for our R&D team to implement this functionality. Thank you for the suggestion!

Best regards,

Bogdan

Show all comments

Processes that are designed to be used as sub-processes can become confusing because Parameters appear in alphabetical order and have no indication of which are required as inputs.  It would be helpful to have an additional checkbox setting for Required or Input in the parameter set up, especially when a process is designed to be used as a sub-process by different teams creating processes.

2 comments

Dear Janine,

You can use an auto-generated page at the begining of the business process with full list of all parameters and you can specify if the field is required to fill in in this auto-generated page (see screenshot http://prntscr.com/n5tita). And you can also change the position of those parameters in an auto-generated page using "Move up" and "Move down" options. And after that you can use those parameters in next steps of a business process.

Best regards,

Oscar

There are two problems with this suggestion.

1) This doesn't help for processes that are designed as subprocesses.  There is no indicator for others teams creating processes based on the processes I'm creating what parameters are input and output parameters without external documentation.

2) Mobile is not very manual start process friendly.

I would rather have a checkbox to enable a star on the parameter when the process is used as a subprocess than have to change the names of parameters to read differently.

Show all comments

Parameters of a process appear in creation order in the process or alphabetical order as a sub-process, which can become unwieldy or confusing when referencing subprocesses since there is no way to indicate which ones are required to be passed into a process to function correctly.  Is there any way to sort the Parameters manually, for example, so that inputs parameters are at the top of the list?

Like 0

Like

1 comments

Dear Janine,

Currently the logic is that parameters in the process are ordered by creation date (if we are talking about custom business processes). And indeed they cannot be sorted in another order and I will create a request to our R&D team so they could include this functionality in out of the box version of the application. Thank you for this idea!

Best regards,
Oscar

Show all comments

How do I test if a String Parameter in a process has not been filled in using a Formula?  For example, the following are not working because they do not evaluate to true when the parameter is not filled in:

[#MyStringParameter#]==""
 
[#MyStringParameter#]==String.Empty

Is there a function for String length?

Like 0

Like

2 comments

I've used the following: 

string.IsNullOrEmpty([#MyStringParameter#])

However, I believe I've used what you're using as well (but might have wrapped it in parentheses)

Ryan Farley,

String.IsNullOrEmpty([#MyStringParameter#]) works.  Thanks!

Show all comments