ورود

View Full Version : سوال: استفاده از تابع Count در Stiulsoft Report



meysampaknahad
چهارشنبه 11 آبان 1390, 23:59 عصر
با سلام
من میخام با استیمول ریپورت گزارشی نموداری از یکی از ستونهای جدولم تهیه کنم ( شامل تعداد و درصد تکرار) که شامل یکی از پنج مقدار پیش فرض هستند و نوع رشته ای هم دارند.
کریستال ریپورت این کار رو خیلی ساده با تابع Count انجام می داد ولی در این نرم افزار مثل اینکه به این سادگی نیست.
لطفاً راهنمایی کنید.

meysampaknahad
پنج شنبه 12 آبان 1390, 16:35 عصر
فکر نمی کنم تا حالا کسی با این مشکل برخورد کرده باشه.
به هر حال اگه کسی موفق به حلش شد ما رو هم بی نصیب نذاره.

PetekDincos
پنج شنبه 12 آبان 1390, 18:31 عصر
با سلام
در StimulReport برای نمایش نمودار بایستی کنترل Chart رو به گزارش اضافه کنید و سری های مختلفی برای نمایش نوع نمودار وجود دارد شما در پراپرتی Series مربوط به نمودارتون می توانید نوع سری مورد خواسته تون رو مشخص کنید و با Add کردن سری مورد خواسته خود در سری اضافه شده پراپرتی های Argument Data Column,Value Data Column این دو پراپرتی رو به منبع داده مورد نظر خودتون وصل کنید و نمودار خودتون رو نمایش بدید با تشکر

meysampaknahad
پنج شنبه 12 آبان 1390, 18:37 عصر
سلام
این کار رو که انجام دادم . اشتباه نشه دوست عزیز روش ایجاد چارت رو بلدم . برای ستونهایی هم که مقدارشون عددی هست مشکلی نداره ولی ستونی که من میخام درصد استفاده هر آیتم رو ازش استخراج کنم از نوع رشته ای هست و با تعیین مقادیر Argument Data Column,Value Data Column ، در هنگام اجرا خطای Specified cast is not valid. رو نشون میده.
مشکل من اینه که نحوه استفاده از تابع Count در این Series چطوریه؟ در کریستال ریپورت اگر دیده باشید خودش به طور پیشفرض با تابع Count این کار رو برامون انجام میده ولی این نرم افزار گویا با این آیتم مشکل داره

Himalaya
پنج شنبه 12 آبان 1390, 19:22 عصر
سلام
بزارید یه پروژه رو قدم به قدم برای انجام این کار پیش ببریم (بعد خودتون اونو رو پروژتون پیاده کنید (البته اگه منظورتون رو درست فهمیده باشم))
1. یه پروژه (win app) جدید تو vs ایجاد کنید. مثلا با اسم Test
2. دی ال ال های Stmulsoft.Base و Stimulsoft.Report رو به رفرنسها اضافه کنید
3. یه دکمه رو فرم قرار بدید (btnReport) و کدهای زیر رو، تو CodeBehind فرم وارد کنید


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Stimulsoft.Report;

namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnReport_Click(object sender, EventArgs e)
{
var report = new StiReport();
if (File.Exists("Report.mrt"))
report.Load("Report.mrt");
report.RegData("Persons", GetPersons());
report.Dictionary.Variables.Add("Total", GetPersons().Sum(c => c.ErrorCount).ToString());
report.Design();
}

private static List<Person> GetPersons()
{
return new List<Person>
{
new Person { Name = "Amir",Family = "Ajorlo",ErrorCount= 23},
new Person { Name = "Ali",Family = "Naderi",ErrorCount= 41},
new Person { Name = "Hamid",Family = "Saberi",ErrorCount= 12}
};
}
}

public class Person
{
public string Name { get; set; }
public string Family { get; set; }
public int ErrorCount{ get; set; }
}
}


توضیح کدها (هر چند که چیز خاصی نداره)
1. یه نمونه از کلاس StiReport ایجاد کردیم
2. گفتیم اگه فایل Report.mrt کنار فایل exe وجود داشت اونو لود کن (و در مرحله بعد مقادیر لازم رو به اون پاس میدیم). اگه وجود نداشت (فرض هم بر اینه که فعلا وجود نداره) با کد report.Design خود Stimul محیط طراحی گزارش رو باز میکنه (و در مرحله بعد مقادیر لازم رو به اون پاس میدیم) که بعد از طراحی، لازمه که اونو سیو کنیم کنار فایل exe تا از دفعه بعد این فایل لود بشه تو report)
3.من اینجا برای اطلاعاتی که قراره نمودار نمایش بده، از دیتابیس استفاده نکردم. فرض بر اینه که تابع GetPersons قراره به عنوان منبع داده عمل کنه
4. توسط تابع RegData اطلاعات مرحله قبل رو پاس میدیم به گزارش.
5. از اونجایی که قراره مقدار ErrorCount رو برای هر یوزر، به صورت درصد نمایش بدیم، تو خط بعد مجموع همه ErrorCount ها رو محاسبه کردیم و یه متغیر به اسم Total به گزارش اضافه کردیم و این مقدار رو تو اون قرار دادیم. (محاسبه مقدار درصد رو تو محیط استیمول انجام میدیم، در غیر این صورت انجام این کار تو خود vs فوق العاده راحته).
نکته: شاید بگید خوب از تابع Sum تو خود استیمول میتونیم واسه محاسبه مجموع فیلد ErrorCount استفاده کنیم. درسته میشه، ولی نه در سری های مربوط به چارت. (امتحان کنید)
6. report.Design هم که قبلا گفتم، محیط طراحی گزارش رو با توجه به پارامترهای ارسالی، باز میکنه

پروژه رو اجرا کنید و روی دکمه کلیک کنید تا محیط طراحی باز بشه. بخش Dictionary به صورت زیر خواهد بود

77375

اطلاعاتی که ت دیتا سورس Persons قرار میگیره به صورت زیر هستن

77376

با داشتن این اطلاعات، میخوایم نمودار زیر رو ایجاد کنیم

77377

تو محیط استیمول، یه چارت رو صفحه قرار بدید. بلافاصله، پنجره مربوط به تنظیمات چارت باز میشه. مراحل زیر رو دنبال کنید
1. نمودار Clusterd Column رو انتخاب کنید و Next
2. یه استایل برای نمودار انتخاب کنید و Next
3. از قسمت Add Series یه سری از نوع Clusterd Column اضافه کنید و Next (لازم نیست از پنجره سمت راست این بخش، چیزی رو تنظیم کنید)
4. تو پنجره بعد Inside End رو انتخاب کنید و Next (میتونید علامت % رو تو Text After قرار بدید تا به دنباله عدد اضافه بشه. ولی ما میخوایم درصد رو به یه روش دیگه نمایش بدیم. پس تو این قسمت هم لازم نیست چیز خاصی و تنظیم کنید)
5. تو بخش Axis x و تو قسمت Angle مقدار 45 رو وارد کنید و Next (البته این رو هم بگم که تنظیمات این بخشها رو هر جور که دوست دارید، انجام بدید (به این دلیل میگم فقط اینا رو ست کنید، چون میخوام نموداری که نشون دادم ایجاد بشه))
6. تو پنجره بعد هم لازم نیست کاری انجام بشه و Finish

خوب چارت ما ایجاد شد، ولی هنوز به منبع داده متصل نشده (ضمن اینکه هنوز داده ای رو تو سری ایجاد شده قرار ندادیم تا نمایش داده بشه). برای این کار
1. چارت رو انتخاب کنید و تو Properties از قسمت Data گزینه Data Source رو بزنید و Persons رو انتخاب کنید و ok
2. تو پراپرتی Series Lables از Format گزینه P2 رو انتخاب کنید
3. روی چارت کلیک راست کنید و گزینه Design رو بزنید و تو پنجره باز شده، و توی پراپرتی ها، هرچی تو پراپرتی های List of Arguments و List of Values قرار گرفته پاک کنید
4. تو قسمت Argument این فرمول رو وارد کنید

{Persons.Name} {Persons.Family} is: {Persons.ErrorCount}
5. تو قسمت Value این فرمول را وارد کنید

{Persons.ErrorCount * (100.0 / int.Parse(Total))}
6. دکمه Close رو بزنید

این گزارش رو کنار فایل exe برنامه Save کنید و خط report.Design رو تبدیل کنید به report.Show
پروژه رو اجرا کنید و نتیجه رو ببینید

meysampaknahad
پنج شنبه 12 آبان 1390, 22:02 عصر
با سلام و تشکر از دوست عزیز karaji333 (http://barnamenevis.org/member.php?53563-karaji333)
این مثالی که شما زدید درسته و کار هم می کنه. ولی سوال من چیز دیگه ای هستش.
فکر می کنم که من نتونستم سوالم رو خوب توضیح بدم. با یه مثال توضیح میدم
من یک ستون دارم به نام نوع مشکل (ProblemType) که شامل یکی از پنج مقدار پیشفرض ( 1- سخت افزار 2- نرم افزار 3- شبکه 4-آموزش 5-سایر ) هستش.(داخل این ستون چیزی به جز یکی از این پنج مقدار قرار نمیگیره. فرمت این ستون هم قاعدتاً String هستش.)
حالا تویه استیمول من نموداری رو میخام که درصد تکرار هر یک از این مقادیر داخل ستون رو نشون بده. در واقع هم مقدار فیلد Argument Data Column در استیمول برابر Ds.ProblemType از دیتاست هست و هم مقدار فیلد Value Data Column .
بدیهیست که نوع هر دو هم String هستش. کریستال ریپورت خودش به طور پیشفرض با دستور Count of Ds.ProblemType تعداد تکرار مثلاً مقدار نرم افزار رو نشون میده (به طور مثال 20درصد کل مقادیر موجود در این ستون) ولی استیمول خطای Specified cast is not valid رو میده.
http://parsaspace.com/files/3987424884/?c=1009
این هم یک نمونه از پیاده سازی این کار با کریستال ریپورت

Himalaya
جمعه 13 آبان 1390, 01:48 صبح
سلام
اشتباه شما اینجاس که میخواید اطلاعات رو تو استیمول دسته بندی کنید (اینکه هر آیتم چند بار تکرار شده). دسته بندی اطلاعات تو استیمول کار سختی نیست. ولی نه در مورد نمودار.
گروه بندی اطلاعات رو توسط برنامه انجام بدید و اطلاعات نهایی رو واسه استیمول ارسال کنید

روند کار به همون صورت قبل هستش. فقط با توجه به توضیحی که تو پست قبل دادید، کدای زیر رو در نظر بگیرید


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Stimulsoft.Report;

namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnReport_Click(object sender, EventArgs e)
{
var report = new StiReport();
if (File.Exists("Report.mrt"))
report.Load("Report.mrt");

var query = (from c in GetProblems()
group c by c.ProblemName
into section
select new
{
section.Key,
Count = section.Count()
}).ToList();

report.RegData("Problem",query);
report.Dictionary.Variables.Add("Total", GetProblems().Count());
report.Design();
}

private static IEnumerable<Problem> GetProblems()
{
return new List<Problem>
{
new Problem { Id =1, ProblemName = ProblemKind.A.ToString()},
new Problem { Id=2, ProblemName = ProblemKind.D.ToString()},
new Problem { Id=3, ProblemName = ProblemKind.B.ToString()},
new Problem { Id=4, ProblemName = ProblemKind.B.ToString()},
new Problem { Id=5, ProblemName = ProblemKind.B.ToString()},
new Problem { Id=6, ProblemName = ProblemKind.B.ToString()},
new Problem { Id=7, ProblemName = ProblemKind.B.ToString()},
new Problem { Id=8, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=9, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=10, ProblemName = ProblemKind.A.ToString()},
new Problem { Id=11, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=12, ProblemName = ProblemKind.A.ToString()},
new Problem { Id=13, ProblemName = ProblemKind.D.ToString()},
new Problem { Id=14, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=15, ProblemName = ProblemKind.E.ToString()},
new Problem { Id=16, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=17, ProblemName = ProblemKind.C.ToString()},
new Problem { Id=18, ProblemName = ProblemKind.E.ToString()},
new Problem { Id=19, ProblemName = ProblemKind.E.ToString()},
new Problem { Id=20, ProblemName = ProblemKind.A.ToString()},
};
}
}

public class Problem
{
public int Id { get; set; }
public string ProblemName { get; set; }
}

public enum ProblemKind
{
A, // سخت افزار
B, // نرم افزار
C, // شبکه
D, // آموزش
E // سایر
}
}

تابع GetProblems رو به عنوان منبع داده در نظر بگیرید
من برای ینکه نوع مشکل ها رو از هم تفکیک کنم (همون 5 نوعی که ازشون اسم بردید)، از enum استفاده کردم.
قالب اطلاعاتی هم که برای استیمول فرستاده میشه توسط کد زیر تعیین میشه

select new
{
section.Key,
Count = section.Count()
}

که اگه بخوایم نتیجه رو تو گرید نمایش بدیم (واسه درک بهتر) میشه تصویر زیر

77400

پس اطلاعاتی که برای گزارش فرستاده میشن، شامل نام مشکل (A,B,C,D,E از نوع String) و تعداد هرکدوم (از نوع Int) هستش که تو متغیر query قرار میگیره
نسبت به پست قبلیم، چندتا تغییر اعمال کنید
1. فرمول Argument

{Problem.Key}
2. فرمول Value

{Problem.Count * (100.0 / Total)}
3. وقتی رو چارت کلیک راست کردید و Design رو زدید، تو پنجره باز شده رو بخش Event کلیک کنید و ادیتور مربوط به ایونت Get Argument رو باز کنید و کدای زیر رو توش قرار بدید

if (e.Value.ToString() == "A")
e.Value = "سخت افزار. تعداد:" + " " + Problem.Count;
else if (e.Value.ToString() == "B")
e.Value = "نرم افزار. تعداد:" + " " + Problem.Count;
else if (e.Value.ToString() == "C")
e.Value = "شبکه. تعداد:" + " " + Problem.Count;
else if (e.Value.ToString() == "D")
e.Value = "آموزش. تعداد:" + " " + Problem.Count;
else
e.Value = "سایر. تعداد:" + " " + Problem.Count

نتیجه اجرای برنامه میشه تصویر زیر

77401

meysampaknahad
جمعه 13 آبان 1390, 16:07 عصر
با سلام و تشکر از دوست عزیز Karaji333
روشی که اشاره کردید درسته و قبلاً به ذهنم رسیده بود ولی خب همونطور که می دونید این روش یه مقدار بار اضافی رو به سرور تحمیل می کنه ( دستورات Insert , Update , Delete , Select که هر بار باید از دیتابیس مقادیری رو بخونند ، وارد کنند و آپدیت یا پاک کنند )
با استفاده از خود ریپورتر بهتر بود که مثل اینکه در استیمول به این سادگی ها نیست. در این مورد کریستال ریپورت بهتر عمل می کنه
با تشکر از دوستان

Himalaya
دوشنبه 16 آبان 1390, 15:00 عصر
سلام

روشی که اشاره کردید درسته و قبلاً به ذهنم رسیده بودما که نگفتیم نرسیده بود :چشمک:


همونطور که می دونید این روش یه مقدار بار اضافی رو به سرور تحمیل می کنه ( دستورات Insert , Update , Delete , Select که هر بار باید از دیتابیس مقادیری رو بخونند ، وارد کنند و آپدیت یا پاک کنند ) بار اضافی رو سرور؟!!! شما یه Select میخواید بزنید. همین (حالا چه از طریق خود برنامه، چه از طریق استیمول). این بار اضافیش کجا بود
تو گزارش گیری، Update , Delete, Insert برای چیه!!!

babak2000
پنج شنبه 03 مرداد 1392, 21:05 عصر
ما هم همین مشکل را داشتیم توی فورم خودشون هم بود

http://forum.stimulsoft.com/viewtopic.php?t=2454

ولی با تغییر سلکت کوئری (Select) میشه یه کارایی کرد



SELECT CompanyID, COUNT(CompanyID) AS NationalCode
FROM View_Report_Payesh_Janbaz
GROUP BY CompanyID
ORDER BY CompanyID

حالا دوتا فیلد را پاس بدید به دیتا ست و بعد داخل خود گزارش بعنوان آرگومنت و مقدار و ....