PDA

View Full Version : سوال: روش چاپ در برنامه نویسی سه لایه



piroozman
جمعه 14 تیر 1398, 11:10 صبح
سلام. در یک برنامه ویندوز فرم که به صورت سه لایه نوشته شده است، بهترین روش برای ارسال داده ها از DAL به UI جهت چاپ اون چی میتونه باشه؟ طوری که بشه به صورت Design Time فرم چاپ رو آماده کرد. چیزی که به ذهن من میرسه این هست که داده ها رو با استفاده از LINQ در DAL فراخوانی کنم، اونها رو به DataTable تبدیل کنم و به DataTable هایی که در یک DataSet قرار دارند که از قبل در UI آماده کردم منتقل کرده و فرم چاپ رو به آنها Bind کنم. این روشی هست که فعلا در ذهن دارم ولی امیدوارم روش بهتری هم وجود داشته باشه. از دوستان ممنون میشم راهنماییم کنند.

mmbguide
جمعه 14 تیر 1398, 16:19 عصر
سلام

من چون خودم هنوز با DataSetها کار میکنم به همون روشی که گفتی کار میکنم

Mahmoud.Afrad
جمعه 14 تیر 1398, 16:31 عصر
نیازی به تبدیل به دیتاست و دیتاتیبل ندارید. اگر از ابزارهای چاب مثل stimulreport استفاده کنید ، دیتاسورسی از نوع کلاس می پذیرند که در اینصورت دیتا را به صورت لیست به ابزار گزارش ارسال می کنید.

piroozman
جمعه 14 تیر 1398, 17:55 عصر
من از کنترلهای Devexpress استفاده می کنم. میشه در مورد روشی که می فرمایید بیشتر توضیح بدید. یا این که در مورد Devexpress اطلاعاتی دارید دراختیار من بگذارید. ممنون

mmbguide
جمعه 14 تیر 1398, 21:22 عصر
البته اگر میخواهید محتویات نمایش داده شده در GridView رو چاپ کنید میتونید همون DataSource رو هم به گزارش ارسال کنید. البته من هنوز خیلی متوجه نشدم دنبال چه چیزی هستید دقیقا. ولی ابزارهای گزارش سازی مثل StimulReport خیلی کار کردن باهاش راحته

piroozman
شنبه 15 تیر 1398, 11:22 صبح
البته اگر میخواهید محتویات نمایش داده شده در GridView رو چاپ کنید میتونید همون DataSource رو هم به گزارش ارسال کنید. البته من هنوز خیلی متوجه نشدم دنبال چه چیزی هستید دقیقا. ولی ابزارهای گزارش سازی مثل StimulReport خیلی کار کردن باهاش راحته
برای مشاهده داده ها در گرید به صورت runtime اقدام کردم. یعنی اطلاعات رو با استفاده از EF از DAL به BLL و از اونجا به UI منتقل میکنم و کامپوننتها رو به اون بایند میکنم. وقتی گزارش سازی مثل Xtrareport شرکت Devexpress استفاده میکنی به امکان دسترسی اشیاء ساخته شده در کدها نداره (که البته فکر کنم مابقی گزارش سازها هم به همین شکل باشند). این در حالی است که من میخوام به صورت ویزاردی اقدام کنم و مجبور نباشم برای همه ستونها و ردیفها و غیره کد نویسی کنم. فقط میخوام گزارش رو به صورت ویزارد طراحی کنم و به داده ها بایند کنم. کارفرما میگه که داده ها حتما باید از DAL به UI منتقل بشند و این اجازه رو ندارم در UI به طور مستقیم به داده های پایگاده داده متصل بشم. همانطور که گفتم میتونم برای این کار داده های منتقل شده از DAL رو به UI که شامل یک یا چند دیتاست (و هر دیتاست شامل چندین دیتاتیبل) هستش، منتقل کنم و گزارش ساز رو به اون بایند کنم. این چیزی هست که به ذهنم میرسه ولی شاید روش بهتری باشه. بنابراین منظور من از این پست ابن بود که آیا این روش درست هستش؟ آیا روش دیگه ای پیشنهاد می کنید که از این روش راحتتر و نیز استانداردتر باشه. امیدوارم منظورم رو درست بیان کرده باشم. منتظر پاسخ ارزشمند شما هستم.

Mahmoud.Afrad
شنبه 15 تیر 1398, 18:25 عصر
داکیومنت خود شرکت سازنده را ببینید اگر مشکلی بود بعد سوال کنید
https://documentation.devexpress.com/XtraReports/1179/Detailed-Guide-to-DevExpress-Reporting/Provide-Data-to-Reports/Bind-a-Report-to-a-Data-Source

piroozman
دوشنبه 17 تیر 1398, 08:25 صبح
همانطور که گفتم قصد دارم داده ها از DAL فراخوانی شده، به BLL ارسال شده و از آنجا در اختیار XtraReport قرار بدم. سناریو به این شکل هستش:
در لایه DA
public static List<t_Products> GetAllProductList() {
try
{
return objContext.t_Products.OrderBy(c => c.f_ProName).ToList();
}
......
}

در لایه BL
public static List<t_Products> GetAllProductList() {
return DAL.DALProducts.GetAllProductList();
}
در UI
List<t_Products> ProductList = BLLProducts.GetAllProductList();
var queryProduct=ProductList.Where(oo => oo.f_ProTypeID == 1)
.Select(current=>new {current.f_ProductID,current.f_ProCode,current.f_P roName,current.f_ProWeight,current.f_ProTypeID});
//ساخت یک DataTable از کوئری LINQ
productDT =Utilities.IEnumerableToDataTable.LINQToDataTable( queryProduct);

//در رویداد کلیک یک دکمه داریم:
private void simpleButton1_Click(object sender, EventArgs e)
{
if (productDT.Rows.Count > 0)
{
//ارسال DataTable مرتبط با محصولات به نام productDT به XtraReport ی به نام ProductsAndBOM
Reports.XtraReports.ProductsAndBOM x = new Reports.XtraReports.ProductsAndBOM(productDT);
x.Report();
}
else
.... }

و در آخر این که در داخل XtraReport که نام آن را ProductAndBOM گذاشتم یک DataSet دارم به نام mahshamDataSet که در آن جدولی به نام t_Product وجود دارد. فیلدهای این جدول را روی Report قرار داده ام. DataTable ارسال شده به Report را با استفاده از دستور Merge در دیتاتیبل t_Product قرار میدهم:

public partial class ProductsAndBOM : DevExpress.XtraReports.UI.XtraReport
{
public ProductsAndBOM()
{
InitializeComponent();
}
System.Data.DataTable requiredRawMaterilSource;
System.Data.DataTable productsSource;
public ProductsAndBOM(System.Data.DataTable products)
{
productsSource = products;
}
new public void Report()
{
mahshamDataSet1.t_Products.Merge(productsSource);
ProductsAndBOM productBOMXtraReport = new ProductsAndBOM();
ReportPrintTool printTool = new ReportPrintTool(productBOMXtraReport);
UserLookAndFeel lookAndFeel = new UserLookAndFeel(this);
lookAndFeel.UseDefaultLookAndFeel = false;
lookAndFeel.SkinName = "Office 2016 Colorful";
printTool.ShowRibbonPreview(lookAndFeel);
}
}

متاسفانه در هنگام Merge کردن جدول ارسالی به Report با جدول mahshamDataSet1.t_Products خطای زیر را دریافت می کنم:
An unhandled exception of type 'System.NullReferenceException' occurred in Mahsham.UI.exe
Additional information: Object reference not set to an instance of an object.

دوستان لطف کنید کدها رو بررسی کنید ببینید باید چه کار کنم تا این خطا رو دیافت نکنم و این که این روش به نظر شما دست هستش. کارفرما گیر داده که در UI و Report ها نباید به Database ارتباط برقرار بشه. ممنون

piroozman
دوشنبه 17 تیر 1398, 12:47 عصر
دوستان لطف کنید کدها رو بررسی کنید ببینید باید چه کار کنم تا این خطا رو دیافت نکنم و این که این روش به نظر شما دست هستش. کارفرما گیر داده که در UI و Report ها نباید به Database ارتباط برقرار بشه. ممنون
متوجه مشکل شدم. کدها طوری عمل می کرد که قبل از فراخوانی InitializeComponent و ساخت یکی شی از دیتاست، سعی در پر کردن یک فضای null داشته و بنابراین خطا می داد. ضمن این که در قسمت ایجاد گزارش دوباره با استفاده از new گزارش جدیدی ساخته میشد که ربطی به گزارش اول نداشته و فیلدها رو نمایش نمی داد بنابراین کدها را به شکل زیر اصلاح کردم:

public partial class ProductsAndBOM : DevExpress.XtraReports.UI.XtraReport
{
public ProductsAndBOM(System.Data.DataTable products)
{
InitializeComponent();
productsSource = products;
}
//System.Data.DataTable requiredRawMaterilSource;
System.Data.DataTable productsSource;


public ProductsAndBOM()
{

}


new public void Report()
{
//mahshamDataSet1 = new Data.MahshamDataSet();

// ProductsAndBOM productBOMXtraReport = new ProductsAndBOM();
mahshamDataSet1.t_Products.Merge(productsSource);
ReportPrintTool printTool = new ReportPrintTool(this);
UserLookAndFeel lookAndFeel = new UserLookAndFeel(this);
lookAndFeel.UseDefaultLookAndFeel = false;
lookAndFeel.SkinName = "Office 2016 Colorful";
printTool.ShowRibbonPreview(lookAndFeel);
}


}