مستند مسئله انتخاب اقدام‌کنندگان در گرید

بررسی مسئله­ انتخاب اقدام‌کنندگان درون یک گرید در مراحل قبل و ارائه یک راه‌حل برای آن

طرح مسئله: فرض کنید در فرآیندی یکی از اقدام کنندگان فرآیند باید بتواند نام برخی افراد را در یک گرید قرار دهد تا فرم و دیتا برای کلیه­ی این افراد ارسال گردد.

یک راه‌حل: برای حل این مسئله یکی از راهکارها استفاده از دو فرآیند مجزاست، در فرآیند اول انتخاب گیرندگان صورت می‌گیرد و با روشی به ازای هر اقدام‌کننده، فرآیند دوم را اجرا کرده و فرم را برای اقدام‌کنندگان ارسال می­‌کنیم. تصویر زیر نمونه­‌ای از دیاگرام این راهکار است:

همان‌طور که مشاهده می­‌شود در اولین مرحله‌ فرآیند “فرایند اول” فرم و دیتا پر می­‌شود که تصویر فرم مربوطه در زیر آمده است:

ستون مورد نظر در این فرم، نام و نام خانوادگی است که حتماً باید از نوع سمت سازمانی دیدگاه باشد. پس نام اقدام‌کنندگان مرحله­ بعد باید در این ستون قرار بگیرد.

در مرحله‌ بعد فرآیند با استفاده از یک فعالیت کدنویسی (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);

}

}

}

نکته: درپیاده­‌سازی این راهکار برای مشتری­‌های مختلف باید به نام‌­های جداول و ستون‌ها و نام رشته اتصال دقت کرد؛ زیرا می­‌توانند از آن‌چه که در این اسکریپت­‌ها آورده شده است، متفاوت باشند.

نظرات کاربران 0 نظر

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *