ผมเพิ่งหัดใช้ Crystal Reports for Visual Studio .NET เมื่อไม่นานนี้ โดยใช้ Data Source เป็น OLE DB ซึ่งผมเจอปัญหาสำคัญเรื่องหนึ่ง คือ Database Fields ของ Report จะจำ Server, Database Name ตอนที่เราเลือกครั้งแรก ซึ่งจะทำให้เกิดปัญหาในกรณีที่มีการเปลี่ยนชื่อ Server หรือเปลี่ยนชื่อ Database จะทำให้ Crystal Reports ไม่สามารถดึงข้อมูลได้ ใน Property ของ Report ก็มีอะไรให้เซ็ตค่าน้อยมาก ผมได้ใช้ Google หาข้อมูล ว่าจะส่งค่า Logon informations เข้า database ให้กับ Crystal Report ตอนรันได้อย่างไร ซึ่งก็หาเจอครับ แต่มีความยุ่งยากมาก โดยการส่งค่ามีวิธีการดังนี้ครับในขั้นตอนแรกให้ประกาศตัวแปรประเภท Database, Tables, Table, TableLogonInfo, ConnectionInfo ซึ่งคลาสเหล่านี้อยู่ใน namespace CrystalDecisions.Shared ดังนี้ครับ
ต้องขอบคุณเว็บ businessobjects.com ที่มี knowledge base เรื่องน ี้ทำให้ผมสามารถแก้ปัญหาได้ครับ
How to pass Database logon info to a Crystal Report at runtime in VB.NETPassing SQL logon information to a report and subreport in VB .NET
// C# .NETusing CrystalDecisions.Shared;private Database crDatabase;private Tables crTables;private Table crTable;private TableLogOnInfo crTableLogOnInfo;private ConnectionInfo crConnectionInfo = new ConnectionInfo ();จากนั้นให้กำหนดค่า connection ในการ logon เข้า data source โดยถ้าใช้ ODBC ให้กำหนด ServerName เป็น DSN แต่ถ้าใช้ OLE DB ให้กำหนดเป็นชื่อของ database server และกำหนด DatabaseName, UserID, Password แต่ในกรณีที่ใช้ Oracle จะไม่มี DatabaseName ให้เซ็ตเป็น empty string
crConnectionInfo.ServerName = "DSN or Server Name";crConnectionInfo.DatabaseName = "DatabaseName";crConnectionInfo.UserID = "Your UserID";crConnectionInfo.Password = "Your Password";ขั้นตอนต่อไป คือการ get ข้อมูลของ tables จาก Report ในที่นี้ตัวแปร ReportDocument คือ crReportDocument
crDatabase = crReportdocument.Database;crTables = crDatabase.Tables;จะได้ reference ของ tables เก็บในตัวแปร crTables ในขั้นตอนสุดท้าย จะวนลูปและกำหนด connection information ให้แต่ละ tables โดยใช้ method Table.ApplyLogOnInfo() และต้องเปลี่ยน location ของ table ให้ชี้ไปที่ Database ตัวใหม่ด้วย ดังนี้ครับ
for (int i = 0; i < crTables.Count; i++){ crTable = crTables [i]; crTableLogOnInfo = crTable.LogOnInfo; crTableLogOnInfo.ConnectionInfo = crConnectionInfo; crTable.ApplyLogOnInfo(crTableLogOnInfo); crTable.Location = "DatabaseName.dbo." + crTable.Location.Substring(crTable.Location.LastIndexOf(".") + 1)}จะเห็นได้ว่าหลายขั้นตอนพอสมควรกว่าจะเปลี่ยน Database ได้ ซึ่ง code ข้างต้นใช้ได้กับ Report ที่ไม่มีรายงานย่อย (Subreport) เท่านั้นนะครับ ถ้า Report ของเรามีรายงานย่อย code ข้างต้นจะเปลี่ยนค่า database logon ให้เฉพาะรายงานหลัก (Main Report) ถ้าต้องการเปลี่ยนค่าของ Subreport ด้วย จะต้องดึงค่า SubreportObject ออกมา โดยค้นหาจากทุก Sections แล้วกำหนด logon information ให้กับ ทุก tables ในทุก Subreports ครับ 









