شرح صورت مسئلهبررسی مسئلهی انتخاب اقدام کنندگان درون یک گرید در مراحل قبل و ارائه یک راه حل برای آن:
طرح مسئله: فرض کنید در فرآیندی یکی از اقدام کنندگان فرآیند باید بتواند نام برخی افراد را در یک گرید قرار دهد تا فرم و دیتا برای کلیهی این افراد ارسال گردد.
یک راهکار: برای حل این مسئله یکی از راهکارها استفاده از دو فرآیند مجزاست، در فرآیند اول انتخاب گیرندگان صورت میگیرد و با روشی به ازای هر اقدام کننده، فرآیند دوم را اجرا کرده و فرم را برای اقدام کنندگان ارسال مینماییم. تصویر زیر نمونهای از دیاگرام این راهکار است:
همانطور که مشاهده میشود در اولین مرحلهی فرآیند “فرایند اول” فرم و دیتا پر میشود که تصویر فرم مربوطه در زیر آمده است:
ستون مورد نظر در این فرم، نام و نام خانوادگی است که حتما باید از نوع سمت سازمانی دیدگاه باشد. پس نام اقدام کنندگان مرحلهی بعد باید در این ستون قرار بگیرد.
در مرحلهی بعد فرآیند با استفاده از یک فعالیت کدنویسی(Script Task) موارد زیر را انجام میدهیم:
- خواندن لیست اقدام کنندگان از گرید و قرار دادن آن درون یک متغیر DataTable
- شمارش تعداد ردیفهای گرید که در آنها اقدام کننده قرار داده شده است و نگهداری آن در یک متغیر
- تعریف متغیر شمارنده i و قراردادن مقدار اولیه 0 در آن.
در زیر نمونه کدی که کارهای فوق را انجام میدهند مشاهده میفرمایید:
using System;
using System.Data;
using System.Data.SqlClient;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class ScriptTask : IScriptTask
{
public IExecution Execution { get; set; }
public void Execute()
{
DataTable dt = new DataTable();
int counttable = 0;
SqlConnection conn = new SqlConnection();
conn.ConnectionString = Execution.GetConnectionString(“BPMSC601″);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = @”SELECT TASKOWNER FROM bpm_KalaNavganShargh_Extra_SampleGrid
WHERE ParentGuid = @BusinessKey AND TASKOWNER is not null”;
cmd.Parameters.AddWithValue(“@BusinessKey”,Execution.GuidValue(“___BusinessKey”));
conn.Open();
dt.Load(cmd.ExecuteReader());
conn.Close();
SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = conn;
cmd2.CommandText = @”SELECT COUNT(*) as counttable FROM bpm_KalaNavganShargh_Extra_SampleGrid
WHERE ParentGuid = @BusinessKey AND TASKOWNER is not null”;
cmd2.Parameters.AddWithValue(“@BusinessKey”,Execution.GuidValue(“___BusinessKey”));
conn.Open();
counttable = Convert.ToInt32(cmd2.ExecuteScalar());
conn.Close();
Execution.SetVariable(“dtVariable”,dt);
Execution.SetVariable(“counttable”,counttable);
Execution.SetVariable(“i”,0);
}
}
}
در ادامهی فرآیند، در قسمت کدنویسی درگاه انحصاری (Exclusive Gateway) بررسی میکنیم که آیا تعداد رکوردهای جدول که دارای نام اقدام کننده هستند بیشتر از 0 هست یا خیر. اگر بیشتر بود فرآیند ادامه پیدا میکند.
using System;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class ConditionalFlow : IConditionalFlow
{
public IExecution Execution { get; set; }
public bool Evaluate()
{
return Execution.IntegerValue(“counttable”)>0;
}
}
}
در ادامه ، در قسمت کدنویسی درگاه انحصاری (Exclusive Gateway) بررسی میکنیم که آیا مقدار متغیر شمارنده از تعداد اقدام کنندگان کمتر باشد. این درگاه انحصاری (Exclusive Gateway)به محض آنکه مقدار متغیر شمارنده از تعداد اقدام کنندگان بزرگتر یا مساوی شد فرآیند را خاتمه میدهد.
using System;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class ConditionalFlow : IConditionalFlow
{
public IExecution Execution { get; set; }
public bool Evaluate()
{ if(Execution.IntegerValue(“i”)<Execution.IntegerValue(“counttable”))
return true;
else
return false;
}
}
}
با ایجاد یک حلقه در فرآیند به ازای هر ردیف از جدول اقدام کننده را تشخیص داده، سپس فرایند دوم را اجرا میکنیم و اقدام کننده را نیز به فرآیند دوم ارسال میکنیم.
برای این منظور از کد زیر استفاده میکنیم:
using System;
using System.Data;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class ScriptTask : IScriptTask
{
public IExecution Execution { get; set; }
public void Execute()
{ int[] arrray = new int[Execution.DataTableValue(“dtVariable”).Rows.Count];
for (int i = 0; i < Execution.DataTableValue(“dtVariable”).Rows.Count; i++)
{
arrray[i] = Convert.ToInt32(Execution.DataTableValue(“dtVariable”).Rows[i][0]);
}
Execution.SetVariable(“abc”,arrray[Execution.IntegerValue(“i”)]);
}
}
}
در این کد همانطور که مشاهده میکنید، متغیری به نام abc حاوی نام اقدام کننده است.
همانطور که مشاهده میفرمایید متغیرDataTable ای که از مرحلهی قبل آمده را تبدیل به یک آرایه مینماییم، حال با استفاده از متغیر شمارنده، در هر بار اجرای حلقه در فرآیند، نام یکی از اقدام کنندگان از آرایه را استخراج کرده و از آن استفاده مینماییم.
با استفاده از کد زیر به ازای هر بار اجرای حلقه در فرآیند یکی به متغیر شمارنده اضافه مینماییم:
using System;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class ScriptTask : IScriptTask
{
public IExecution Execution { get; set; }
public void Execute()
{
int temp = Execution.IntegerValue(“i”);
temp += 1;
Execution.SetVariable(“i”,temp);
}
}
}
حال با استفاده از یک رویداد پایان – پیام (End Event – message) فرآیند دوم را اجرا کرده و متغیر abc که حاوی نام اقدام کننده است را به فرآیند “فرایند دوم” ارسال مینماییم.
در فرآیند دوم تسکی که باید توسط اقدام کننده مورد نظر اجرا شود، اقدام کنندهی آنرا از نوع کدنویسی انتخاب کرده و کد زیر را درون آن مینویسیم:
using System;
using Chargoon.Didgah.BPMS.CommonApi;
namespace Chargoon.Didgah.BPMS.Runtime
{
public class OwnerSelector : IOwnerSelector
{
public Iexecution Execution { get; set; }
public Owner GetOwner()
{
int UserStaffId = Execution.IntegerValue(“abc”);
return new Owner(UserStaffId);
}
}
}
نکته: درپیادهسازی این راهکار در مشتریهای مختلف باید به نامهای جداول و ستونها و نام رشته اتصال دقت نمود زیرا میتوانند از آنچه که دراین اسکریپتها آورده شده است متفاوت باشند.