مقدمه: امروزه با توجه به حجم وسیع اطلاعات، استفاده از Database در برنامه ها به جزء لاینفک تبدیل گشته است. حال با توجه به اینکه در زمینه های تجاری (و یا زمینه های غیرتجاری با حجم زیاد اطلاعات) ارائه ی گزارش از این Database ها، امری الزامی در یک نرم افزار و یا یک شبکه است، لازم است که ساختاری مناسب جهت انجام این مهم ایجاد شود. سالها پیش متخصصان بعد از ایجاد کامل نرم افزار، مجبور به صرف زمان قابل توجهی (گاهی به اندازه نیمی از زمان ایجاد نرم افزار) برای ساخت و مدیریت این گزارش ها بودند، به خاطر اینکه مجبور می شدند علاوه بر ایجاد اطلاعات گزارش، آنرا (به عنوان مثال) داخل یک صفحه A4 قرار دهند، به صورتی که هم قابل چاپ (بدون هیچ نرم افزار کمکی) باشد، و هم با تقسیم اطلاعات در صفحات پشت سر هم، فرمت و قالب بندی آنها بدون تغییر باقی بماند. طی چند سال اخیر، روش ها و نرم افزار های متعددی از شرکت های مختلف برای حل این معزل و کمک به برنامه نویسان ارائه شد. در هیچ زمینه ای، روش های مختلف کامل نیستند و هر کدام مزایا و معایبی دارند. این روشها هم از این قاعده مستثنی نبودند، ولی بالاخره روشی که شرکت فرانسوی Business Objects ارائه داد، توسط مایکروسافت به عنوان یک روش استاندارد در پلتفرم NET. پذیرفته شد، و یک نسخه ی رایگان (و البته با امکانات محدود) از نرم افزار آن که Crystal Reports نام دارد،هم در Visual Studio .Net گنجانده شد. این مطلب را می توانید در فرم اسپلش Visual Studio و در زیر منوی About از Visual Studio مشاهده کنید. نکاتی که قبل از شروع مقاله باید به آنها دقت کنید : بحث کامل در مورد Crystal Reports حداقل به 4-3 کتاب می انجامد. این فناوری حتی یک زبان برای خود دارد، و به دلیل کاربرد گسترده، از دو Syntax مختلف تشکیل شده است، تا طیف وسیع برنامه نویسان، با کمترین زمانی که صرف می کنند، بتوانند از Crystal Reportsاستفاده کنند. البته در این مقاله فقط در مورد نحوه ی استفاده از آن بحث می شود، که البته بحث کامل خود آن نیز به چند مقاله نیاز دارد. نکته: این مقاله به صورتی نوشته شده است که در صورت نخواندن قسمت های آتی مقاله، بتوانید بدون اشکال از Crystal Reports در نرم افزار هایتان بهره ببرید. برای بهره برداری کامل از این مقاله، نیاز به مهارت های زیر دارید: · داشتن علم مقدماتی SQL Server · آشنایی به یکی از زبان های .NET (البته برنامه های این مقاله به زبان VB.NET نوشته شده است، ولی با توجه به اینکه فهم توابع به کار برده شده، برای درک کامل کد و ترجمه آن به هر زبان دیگری از جمله #C و #J کافی می باشد، برای درک کامل این مقاله، آشنایی به هرکدام از زبان های NET. برای شما کافی است.) نکته: با توجه به حجم مقاله ناگزیرم برنامه را به صورت مر حله به مرحله ( Step By Step ) آموزش دهم. بخش طراحی و استفاده از Wizard : قست ابتدای این برنامه که همان افزودن Database به پروژه هست، در دو حالت بررسی می شود. (توصیه می کنم بعد از اتمام مقاله برای هر حالت یک پروژه نمونه انجام دهید.) حالت اول - Database شما قبلا ساخته شده است و شما فقط آنرا به پروژه اضافه می کنید: با استفاده از گزینه ی Add Existing Item از منوی Project فایل SQL Databaseخود را به پروژه اضافه کنید. در این هنگام به صورت خودکار صفحه ی Data Source Configuration Wizard باز می شود. نود Tables را باز کرده ، جدولی را که می خواهید گزارش سازی کنید، انتخاب کرده و بر روی Finish کلیک کنید. در این هنگام فایل Database و دیتاست مربوط به آن که شامل جدول مورد نظر است، به پروژه افزوده می شود. (در برخی از موارد به دلیل باگ نا مشخصی در Visual Studio، باید Visual Studio را بسته و دوباره باز کنید. توصیه می کنم ابتدا مرحله بعد را اجرا کنید و در صورت برخورد به مشکل، این کار را انجام دهید.) حالت دوم - Database را در ابتدای پروژه ایجاد می کنید: یک Database جدید ایجاد می کنید، در این هنگام صفحه ی Data Source Configuration Wizardکه قبلا آن را مشاهده کرده اید، باز می شود.این بار فقط گرینه ی Tables را انتخاب کرده و بر روی دکمه Finish کلیک می کنید. جداولتان را در Database ایجاد کرده، بر روی فایل dbsCrystalDataSet کلیک کرده و سپس جدول مورد نظر را از داخل Server Explorer به صفحه ی نمایش داده شده از dbsCrystalDataSet، Drag and Drop می کنید. قسمت مشترک - از این قسمت برنامه در هر دو حالت مشترک است. کنترل CrystalReportViewer را از ToolBox به داخل فرم درگ کنید. تا اینجا فرمی مشابه فرم زیر خواهید داشت. در صورتی که پنل Tasks مربوط به CrystalReportViewer1 را مشاهده نمی کنید، بر روی فلش کوچکی که در سمت راست و بالای CrystalReportViewer1 قرار دارد، کلیک کنید. گزینه ی Create a New Crystal Report را از پنل Tasks انتخاب کرده و نامی را که برای فایل گزارش پیشنهاد می شود، تایید کنید. در این هنگام فایلی به نام CrystalReport1.rpt ایجاد شده و صفحه ی Crystal Reports Gallery باز می شود. در این صفحه شما می توانید قالب کلی گزارش را انتخاب کنید. برای برنامه ی ما گزینه های پیش فرض جوابگو هستند، پس تنها بر روی OK کلیک کنید. در صفحه بعد باید Data Source مورد نیاز را انتخاب کنید. در لیست Available Data Source ، مسیر Project Data --> ADO.NET DataSets را باز کرده و در دیتاستی که ایجاد کردید، جدول مورد نظر را انتخاب کرده و بر روی دکمه < کلیک کنید، تا جدول به لیست Selected Tables افزوده شود. دکمه Next را انتخاب کنید، تا صفحه ی انتخاب فیلد نمایان شود. نود جدولتان را که داخل لیست Available Fields قرار دارد، باز کنید. کلید کنترل را نگه دارید و فیلد هایی را که می خواهید در گزارشان موجود باشند، انتخاب کنید. بر روی دکمه < کلیک کنید تا فیلد ها به لیست Fields To Display اضافه شوند. نکته: قسمت اصلی ویزارد در همین مرحله به اتمام می رسد، ولی در مرحله ی بعد، گروه بندی فیلد ها توضیح داده می شوند. در صورتی که به گروه بندی نیازی ندارید، برای خروج از ویزارد می توانید در همین صفحه بر روی دکمه Finish کلیک کنید. بر روی دکمه Next کلیک کنید، تا صفحه Grouping ظاهر شود. یکی از فیلد های Report Fieldsرا که در لیست Available Fields قرار دارد انتخاب کرده، و بر روی دکمه < کلیک کنید، تا فیلد به لیست Group By افزوده شود. نکته: در اینجا ذکر چند نکته ضروری است: اولا: شما می توانید چند فیلد را از نود Report Fields انتخاب کنید. در این صورت گروه بندی به صورت سلسه مراتبی انجام می شود، به این معنا که در صورتی گروه بندی با فیلد (I)ام صورت می گیرد، که بیش از یک رکورد از اطلاعات در یک گروه که با فیلد (I - 1)ام دسته بندی شده است، وجود داشته باشد. ثانیا: شما می توانید یک فیلد از جدولتان را که در نود Report Fieldsموجود نیست، برای گروه بندی انتخاب کنید. در این صورت با وجود اینکه فیلد انتخاب شده، در جدولتان موجود نیست، ولی رکورد ها بر حسب آن فیلد دسته بندی می شوند. کار ما با ویزارد در همین نقطه به پایان می رسد، پس بر روی دکمه Finish کلیک کنید. (در صفحات بعد می توانید اطلاعات دیگری از جمله ُSummarized Fields و Filter Fields را ست کنید و ظاهر کلی گزارش را تغییر دهید.) در این لحظه فایل گزارش به پروژه افزوده شده و فایل در Visual Studio نمایش داده می شود. بخش کد نویسی : رویداد Load از فرمتان را باز کنید تا چند خطی هم کد بنویسیم: ۱: ابتدا باید مسیر فایل گزارش را در یک متغیر نگهداری کنید: (فرض کنید فایل در شاخه ی D:\Project\CrystalReport قرار دارد.) Dim strReportPath As String = "D:\Project\CrystalReport\CrystalReport1.rpt" نکته: این کد با اینکه درست است، ولی قابلیت حمل را زیر سوال می برد، چون با تغییر محل شاخه ی پروژه باید این مسیر را عوض کنید. برای قابلیت حمل می توانید از کدی مشابه کد زیر استفاده کنید: Dim strReportPath As String = GetCurrentDirectory.Substring(0, _ GetCurrentDirectory.Length - 10) & "\CrystalReport1.rpt" که در این صورت باید خط زیر را به ابتدای صفحه کد اضافه کنید: Imports System.IO.Directory در این صورت اگر بارها مسیر شاخه ی پروژه تغییر کند، در اجرای برنامه اختلالی پیش نمی آید. من تا همین حد از قابلیت حمل را برای شما پیشنهاد می کنم، ولی هنوز هم زمانی که پروژه را Release می کنید، باید کد را به صورت زیر تغییر دهید: Dim strReportPath As String = GetCurrentDirectory() & "\CrystalReport1.rpt" نکته: برای کسانی که می خواهند یک برنامه داشته باشند، عاری از کدی که اشکال مهندسی نرم افزار به آن گرفته شود، کد زیر توصیه می شود: Dim strReportPath As String = GetCurrentDirectory() If strReportPath.Substring(strReportPath.Length - 9) = "bin\Debug" Then strReportPath = strReportPath.Substring(0, strReportPath.Length - 10) End If strReportPath &= "\CrystalReport1.rpt" ۲: در این قسمت باید یک CrystalDocument بسازید و مسیر فایل را در آن Load کنید: Dim rptEmployee As New CrystalDecisions.CrystalReports.Engine.ReportDocum ent rptEmployee.Load(strReportPath) ۳: در این زمان یک دیتاست بسازید و اطلاعات جدولتان را در آن قرار دهید (من اینکار را با استفاده از یک تابع انجام دادم، شما می توانید از هر روش دیگری استفاده کنید)، سپس آن را به متد SetDataSource از سند گزارشتان ارسال کنید: Dim dstData As DataSet = fncGetData() rptEmployee.SetDataSource(dstData) ۴: در انتها خاصیت ReportSource از کنترل CrystalReportViewer1 را به سند گزارشتان ست کنید: CrystalReportViewer1.ReportSource = rptEmployee تا اینجا کد رویداد Load از فرم تمام شد، ولی برای این که همه افراد بتوانند برنامه را بدون اشکال اجرا کنند، کد تابع fncGetData هم ارائه می شود: (در این برنامه نام فایل Database، dbsCrystal و نام فایل دیتاست dbsCrystalDataSet در نظر گرفته شده است.) Private Function fncGetData() As DataSet Dim strConn As String = "Data Source=.\SQLEXPRESS;AttachDbFilename=" & _ GetCurrentDirectory.Substring(0, GetCurrentDirectory.Length - 10) & _ "\dbsCrystal.mdf;Integrated Security=True;User Instance=True" Dim sqlConnection1 As New SqlConnection(strConn) Dim strQuery As String = "Select * From tblEmployee" Dim sqlDataAdapter1 As New SqlDataAdapter(strQuery, sqlConnection1) Dim dstData As New dbsCrystalDataSet sqlDataAdapter1.Fill(dstData, "tblEmployee") Return dstData End Function نکته: توجه شود که در این تابع یک dbsCrystalDataSet (نام فایل دیتاستی که ایجاد کردید) ایجاد شده، نه یک DataSet. همچنین در رشته ی strConn در تابع بالا مسئله ی قابلیت حمل به طور ناقص مطرح می شود، که برای رفع این مسئله می توانید از روشی که در رشته ی strReportPath در رویداد Load فرم مطرح کردم، استفاده کنید. برای استفاده از تابع بالا لازم است خط زیر را به بالای صفحه ی کد اضافه کنید: Imports System.Data.SqlClient حالا صفحه ی کد شما باید دارای کدی به صورت زیر باشد: نکته: توجه شود که راه های ساده تری هم برای استفاده از Crystal Reports وجود دارد، که بعضی نیاز به کد نویسی هم ندارند، ولی در این مقاله عمدا این روش آموزش داده شد که بتوانید با کمی تغییر در کد ""Select * From tblEmployee هر گونه فیلتری برای اطلاعات در نظر بگیرید، و عملا نیاز به مراتب کمتری به استفاده از زبان Crystal Report برای به دست آوردن اطلاعات با یک فیلتر خاص، داشته باشید. حالا برنامه کامل است آن را اجرا کنید. فرم زیبایی! مانند زیر مشاهده خواهید کرد: (البته پر شده از اطلاعات جدول خودتان) (گزارش داخل فرم) (فرم متشکل از گزارش) همانطور که در Toolbar موجود در بالای کنترل CrystalReportViewer1 مشاهده می کنید، این کنترل، خروجی دادن اطلاعات به فرمت های مختلف ( از جمله PDF، DOC و XLS ) ، پرینت اطلاعات ، جستجو در داده ها، صفحه پیمایی اطلاعات و حتی زوم کردن بر روی صفحه ( تا 400% و بدون کاهش کیفیت نوشته ها ) را برای شما و کاربر نهایی مهبا می کند. سخن پایانی : در مقاله (یا مقالات) آتی ان شاالله (یعنی اگر مقالاتی باشد!) موارد زیر بررسی خواهد شد: ü تغییر جزییات گزارش ü پرینت ، جستجو ، صفحه پیمایی و خروجی دادن گزارش (با امکانات بیشتر) با استفاده از کد (برای استفاده خود برنامه در زمان اجرا، و نه فقط برای کاربر) ü دادن این قابلیت به برنامه، که کاربر قبل از مشاهده گزارش بتواند اطلاعات را فیلتر کند و یا به گزارش پارامتر! ارسال کند. ü نحوه ی استفاده از عملگر های خلاصه سازی ( Summary Operators )، مرتب سازی گروه ها ( Group Sort )و مرتب سازی رکورد ها ( Record Sort ) ü فرستادن یک Formula به گزارش (کاری مشابه فیلترینگ اطلاعات انجام می دهد، البته با امکانات و جزییات گسترده تر) ü اجزا و نحوه ی استفاده از زبان خاص مورد استفاده در Crystal Reports (به تنهایی به ۱ یا ۲ مقاله نیاز دارد) چند مسئله ی کوچک: · از اینکه تا اینجا با من همراه بودبد، کمال تشکر را دارم. · از اینکه مقاله کمی بیش از حد بزرگ شد، معذرت می خواهم، ولی به دو دلیل این مسئله پیش آمد. اولا: اگر همه ی مقالات در مورد Crystal Report را به همین بزرگی بنویسم، باز هم به ۵-۴ مقاله نیاز داریم! ثانیا: اصولا من کوچک کردن این مقاله را یک نوع کلاه گذاشتن بر سر خواننده تلقی می کنم، و از آنجا که از این مسئله به واقع متنفرم، سعی کردم بر این وسوسه پیروز شوم!!! · در ابتدا می خواستم مثل بعضی از دوستان تمام کد ها را به صورت عکس در این مقاله قرار دهم(چون زیباتر به نظر می رسند)، ولی از آنجا که در کشور همیشه آباد ما اینترنت جیره بندی! می شود، دیدم سرعت بارگذاری این صفحه، از زیبایی مهم تر است. به همین خاطر از کسانی که زیبایی برای آنها از محتوا مهمتر است! کمال پوزش را می طلبم!!! · در ضمن در صورت ایراد سوال و یا اشکال، بنده در خدمت دوستان هستم. همانطور که می دانید فقط نظرات، پیشنهادات و انتقادات (من این یکی را واقعا دوست دارم، باور ندارید؟ امتحان کنید) شماست که باعث دلگرمی من (به عنوان نویسنده ی یک مقاله ی کوچولو) شده و من را به ادامه این مقاله و ارائه مقالاتی در زمینه های دیگر ترغیب می کند. به خاطر داشته باشید که من هیچ نیازی به ارائه ی این مقالات ندارم، پس با نظرات هر چند کوچکتان نشان دهید که خواهان ادامه این مقاله و مقالات مشابه هستید، چون اگه شما هم نیاز نداشته باشید، آن وقت یعنی هیچ کس به این مقالات نیاز ندارد! و این یعنی اینکه من باید وقتم را صرف کار مفید تری کنم (که به نیاز یک نفر پاسخ مثمر ثمر دهد).