Skip to main content




Hello everyone,


What is the trick to getting a process instance for a completed workflow?


I have the code below to retrieve an instance that I (as an administrator of K2 and full access to the particular process) started.  On line 16, where I try to open the process instance, I get an error that states:

26023 Process instance 2203 not found for K2:LITTLER-USGAndora at 10.90.0.20:644


Can anybody let me know what I'm doing wrong?


Thanks a lot,
Greg Andora


The code isn't being diplayed too well on this site, here is a link to it on Windows Live:
Link to Code HTML file







   1:          private void GetWorkflow()

   2:          {

   3:              //for process instantiation

   4:              string serverName = "sfrmsk2";

   5:              string procId = "2203";

   6:   

   7:              //BEGIN PROCESS

   8:              //Instantiate the Connection Object

   9:              using (SourceCode.Workflow.Client.Connection K2Conn = new SourceCode.Workflow.Client.Connection())

  10:              {

  11:                  //Open the Connection Object

  12:                  K2Conn.Open(serverName);

  13:   

  14:                  //Declare the Process Instance Object

  15:                  SourceCode.Workflow.Client.ProcessInstance K2ProcInstance;

  16:                  K2ProcInstance = K2Conn.OpenProcessInstance(int.Parse(procId));

  17:   

  18:   

  19:                  StringBuilder sbWorkflowFields = new StringBuilder();

  20:                  sbWorkflowFields.AppendFormat("<table>");

  21:                  sbWorkflowFields.AppendFormat("<tr><th>Field Name</th>");

  22:                  sbWorkflowFields.AppendFormat("<th>Value</th>");

  23:                  sbWorkflowFields.AppendFormat("<th>Type</th>");

  24:                  sbWorkflowFields.AppendFormat("<th>Hidden</th>");

  25:                  sbWorkflowFields.AppendFormat("</tr>");

  26:   

  27:                  foreach (DataField f in K2ProcInstance.DataFields)

  28:                  {

  29:                      sbWorkflowFields.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", f.Name, f.Value, f.ValueType, f.Hidden);

  30:                  }

  31:   

  32:                  Literal1.Text = sbWorkflowFields.ToString();

  33:   

  34:                  K2Conn.Close();

  35:              }

  36:   

  37:              //END OF PROCESS CODE   

  38:          }

The API only allows access to running instances. Once an instance has been completed, it gets logged to the log database and the only way to get access is through the reporting SmartObjects or SQL queries. 


Side question, what is the reason for opening a completed instance? 


I'm working on an application that brings a user through a series of questions with the purpose of providing an answer at the end.  I'm using K2 as the decision engine, it is determining what question(s) to ask after each set of questions is answered and finally providing the "answer" at the end of the process.  To help with this, I'm using the PageFlow ideas found in the blackmarket project "ASPX Controls for k2 blackpearl" to move a user through the decision making process.


At the end of the process, I was trying to get the data fields in the process to display the conclusion, however, I couldn't get the process instance to load.  I can just get the values from a SmartObject, so it'll still work out.


Thanks a lot for the help,


Greg


Interesting use of K2 🙂.


Good luck with your application.


If you have this working I would appreciate a nudge in the right direction. I'm in a similar situation where I need to read fields from a finished process but I am not sure how to go about using the SmartObjects and I can't find the data in SQL.


Hi,


you can use the below code to fetch the completed instance. smartobject name is the input parameter for this method. you can find this smartobject name for your process in k2 smartobject tester( go to workflow Reports>Workflow solutions> open ur process name and right click view xml)

<smartobjectroot name="Rpt_Process name" >



for exmaple: from  the above sample XML: Rpt_Procees Name


 is smartobject name


 is smartobject name


Code to fetch completed process instance:




public DataSet GetCompletedTask(string strSmartObjectName)


        {


            DataSet ds = new DataSet();


            DataTable dt = new DataTable();


            DataRow dr;


 


            SourceCode.SmartObjects.Client.SmartObjectClientServer serverName = new SourceCode.SmartObjects.Client.SmartObjectClientServer();


            SourceCode.Hosting.Client.BaseAPI.SCConnectionStringBuilder connectionString = new SourceCode.Hosting.Client.BaseAPI.SCConnectionStringBuilder();


 


            // build a connection string


            connectionString.Authenticate = true;


            connectionString.Host = "server name";


            connectionString.Integrated = true;


            connectionString.IsPrimaryLogin = true;


            connectionString.Port = 5555;


 


            // open a K2 Server connection


            serverName.CreateConnection();


            serverName.Connection.Open(connectionString.ToString());


 


            try


            {


                SourceCode.SmartObjects.Client.SmartObject smartObject = serverName.GetSmartObject(strSmartObjectName);


                smartObject.MethodToExecute = "ListProcessInstances";


                smartObject.PropertiesO"Status"].Value = "Completed";


                // call the method


                SourceCode.SmartObjects.Client.SmartObjectList oSmOList = serverName.ExecuteList(smartObject);


 


                if (oSmOList.SmartObjectsList.Count > 0)


                {


                    //To Create dynamic datacolumn


                    foreach (SourceCode.SmartObjects.Client.SmartObject oSmO in oSmOList.SmartObjectsList)


                    {


                        foreach (SourceCode.SmartObjects.Client.SmartProperty oProp in oSmO.Properties)


                        {


                            DataColumn dc = new DataColumn();


                            dc.ColumnName = oProp.Name;


                            dt.Columns.Add(dc);


                        }


                        break;


                    }


 


                    // iterate each smartobject in the collection


                    foreach (SourceCode.SmartObjects.Client.SmartObject oSmO in oSmOList.SmartObjectsList)


                    {


                        dr = dt.NewRow();


                        foreach (SourceCode.SmartObjects.Client.SmartProperty oProp in oSmO.Properties)


                        {


                            drtoProp.Name] = oProp.Value;


                        }


                        dt.Rows.Add(dr);


                    }


                    if (dt.Rows.Count >= 1)


                        ds.Tables.Add(dt);


                }


            }


            catch (Exception ex)


            {


                throw ex;


            }


            finally


            {


                // close the connection


                serverName.Connection.Close();


            }


            return ds;


        }


Reply