2011-11-15 39 views
7

Tôi hiện đang làm việc trên một chương trình trong C# cho phép người dùng của chúng tôi chạy, xem và xuất một loạt các Báo cáo tinh thể. Các báo cáo được thực hiện bằng cách sử dụng Crystal Reports 2008 GUI. Một trong những lý do chính để làm điều này là cho phép chúng tôi bảo toàn siêu liên kết khi Báo cáo tinh thể được xuất sang PDF. Chương trình của tôi thực hiện điều này bằng cách xuất sang rtf, sau đó chuyển đổi rtf thành pdf. Nếu bất cứ ai biết về một phương pháp ít phức tạp của việc bảo quản siêu liên kết khi chuyển đổi sang PDf, tôi rất muốn nghe nó, nhưng đó không phải là câu hỏi hiện tại của tôi.Làm cách nào tôi có thể truy xuất câu lệnh SQL SELECT được sử dụng trong Báo cáo tinh thể?

Tôi đã thực hiện rất nhiều thử nghiệm về cách tối ưu hóa chương trình của mình để làm cho việc xuất ít nhất có thể. Từ những gì tôi đã nhìn thấy, có truy vấn ứng dụng cho dữ liệu, sau đó kết buộc resultset với Crystal Report là phương pháp nhanh nhất. Vấn đề của tôi là tôi không thể mã hóa các truy vấn vào chương trình, chúng cần phải được truy xuất lại từ chính Crystal Report.

Trong Crystal Reports 2008, có một tùy chọn được gọi là "Hiển thị truy vấn SQL" trong trình đơn Cơ sở dữ liệu. Điều này sẽ trả về một cửa sổ với truy vấn SQL được sử dụng cho báo cáo đã cho. Đây chính xác là những gì tôi cần để có được bàn tay của tôi từ bên trong ứng dụng của tôi. Tôi đã tải một báo cáo tinh thể và, trong khi gỡ rối, duyệt qua đối tượng ReportDocument đang cố gắng tìm truy vấn, nhưng không có may mắn.

Vì vậy, câu hỏi của tôi là; có phương pháp nào có sẵn cho phép tôi rút ra truy vấn được sử dụng bởi một Báo cáo Crystal đã cho không?

+0

Nếu bảng trong báo cáo là "Lệnh SQL", bạn vẫn có thể đặt nguồn dữ liệu không? Tôi nghĩ rằng bảng đã được tạo ra từ một tập dữ liệu (xsd)? – dotjoe

+0

Trong thử nghiệm của tôi, Báo cáo tinh thể đã sử dụng "Lệnh SQL" làm "Bảng". Tôi không có vấn đề ràng buộc báo cáo với một tập dữ liệu mà tôi đã truy vấn từ cơ sở dữ liệu, sử dụng cùng một lựa chọn SQL tạo thành "Lệnh SQL" trong báo cáo. Nó hoạt động hoàn hảo, và nhanh hơn rất nhiều so với việc tự báo cáo để làm mới dữ liệu của chính nó. – Chronicide

+0

Thú vị, tôi đang trong quá trình cố chuyển đổi báo cáo sang mô hình PUSH và có lẽ tôi không cần phải làm gì nếu tôi có thể chuyển vào nguồn dữ liệu. Tôi là tất cả các thủ tục lưu trữ mặc dù w/và w/out tham số. – dotjoe

Trả lời

2

Được rồi, vì vậy dotjoe đã cho tôi tất cả các gợi ý mà tôi cần để làm việc này. Các mã sau đây có thể được sử dụng để kéo văn bản lệnh từ một báo cáo tinh thể.

public string getCommandText(ReportDocument rd) 
{ 
    if (!rd.IsLoaded) 
     throw new ArgumentException("Please ensure that the reportDocument has been loaded before being passed to getCommandText"); 
    PropertyInfo pi = rd.Database.Tables.GetType().GetProperty("RasTables", BindingFlags.NonPublic | BindingFlags.Instance); 
    return ((dynamic)pi.GetValue(rd.Database.Tables, pi.GetIndexParameters()))[0].CommandText; 
} 

Có vẻ hơi lộn xộn, nhưng nó có ý nghĩa gì đó khi bạn bắt đầu lội qua nó. Về cơ bản, nó sử dụng sự phản chiếu để lấy giá trị của thuộc tính CommandText, với một ít động lực được ném vào để vượt qua các thuộc tính động trong ReportDocument.

Điều này đang kéo văn bản lệnh cho tôi, nhưng tôi không có thời gian để làm bất kỳ kiểm tra nào về mã. Tôi chắc chắn tôi sẽ thực hiện một số điều chỉnh khi tôi đã có thời gian để làm việc với điều này. Tôi không có đầu mối gì xảy ra với các báo cáo không sử dụng "Lệnh SQL". Tôi sẽ đăng bình luận khi tôi đã thử nghiệm thêm.

  • Scott

T.B. Điều này đòi hỏi bạn tham khảo hình ảnh phản chiếu/thư viện động tiêu chuẩn, cũng như các thư viện Crystal Report như sau:

crystaldecisions.reportappserver.datadefmodel

crystaldecisions.crystalreports.engine

crystaldecisions.shared

+0

công việc rất tuyệt vời! – dotjoe

+0

Tôi muốn lệnh sql với các tham số được thay thế, Với mã đã cho, tôi có thể nhận lệnh sql nhưng các parmeters không được thay thế bằng các giá trị được cung cấp. Làm cách nào tôi có thể nhận được chỉ số sql cuối cùng? & Tôi có thể lấy Số liệu của truy vấn trong bộ sưu tập IEnumerable hoặc một dataTable bằng cách sử dụng ReportDocument không? – zeppelin

3

Tôi nhận ra đây là một câu hỏi rất cũ, nhưng nghĩ rằng tôi sẽ cung cấp một thay thế cho những người vấp ngã trên này nhưng cần một mục tiêu khung 3.5 (năng động là không có sẵn trong 3.5).

Bạn sẽ cần các tham chiếu sau để giải pháp này hoạt động.

using CrystalDecisions.ReportAppServer.DataDefModel; 
using CrystalDecisions.CrystalReports.Engine; 

Sau đó, chỉ cần truy cập vào giao diện ClientDoc với thông tin sau và trả về danh sách chuỗi văn bản lệnh.

private static List<string> GetCommandText(CrystalDecisions.CrystalReports.Engine.ReportDocument report) 
    { 
     var rptClientDoc = report.ReportClientDocument; 
     return rptClientDoc.DatabaseController.Database.Tables.OfType<CommandTable>() 
       .Select(cmdTbl => cmdTbl.CommandText).ToList(); 
    } 
+1

Tôi thích cách này nhất; nó dễ đọc và dễ hiểu hơn. – tuespetre

+0

@tuespetre Cảm ơn! Vui mừng nó đã giúp! –

Các vấn đề liên quan