Как заполнить Crystal Reports с помощью SQL
Поскольку кажется, что нет никакого способа загрузить старые отчеты VB6 (ActiveReports) в.Net, мне нужно воссоздать десятки отчетов в.Net. Я бы хотел сделать это как можно менее болезненно.
В VB6 авторы оригинала просто делали что-то подобное для каждого отчета:
adoConn.ConnectionString = globalConnectionObject.ConnectionString
adoConn.Source = ReportFunctions.GetAllUsers()
GetAllUsers()
возвращает строку SQL, которая выбирает группу полей; эти поля затем используются в отчете.
Сейчас:
Как я могу сделать что-то похожее в.Net (используя встроенные Crystal Reports или встроенную "Microsoft Reporting Technology")?
Я не могу заставить "Эксперта базы данных" распознать globalConnectionObject
(объект ADODB.Connection); и если я заполняю набор данных и делаю
report.SetDataSource(dataSet)
Он говорит мне: "В отчете нет таблиц".
Как мне заполнить отчет Crystal Reports!? (строка соединения / местоположение данных не известны во время компиляции)
2 ответа
Создание соединения:
/// <summary>
/// Sets the connection.
/// </summary>
public void SetConnection()
{
_connection = new SqlConnection(Settings.Default.connectionString);
if (_connection.State == System.Data.ConnectionState.Open)
{
_connection.Close();
}
_connection.Open();
}
/// <summary>
/// Closes the connection.
/// </summary>
public void CloseConnection()
{
if (_connection.State == System.Data.ConnectionState.Open)
{
_connection.Close();
_connection.Dispose();
}
}
используя вышеуказанное соединение Заполните набор данных вручную или добавьте набор данных в свое решение, чтобы получить данные без написания кодов подключения. Скажем, вы добавили Employee.XSD. Добавьте табличный адаптер в XSD, который поможет вам извлекать данные из базы данных, автоматически генерируя запросы и таблицы данных. После всего этого. Создайте метод где-нибудь в вашем проекте,
Public DataTable GetAllEmployees()
{
Employee.EmployeeTableAdapter adapt = New Employee.EmployeeTableAdapter();
DataTable dt = New DataTable();
dt = adapt.GetData(); // you can also use fill based on your criteria.
return dt; //your datatable with data
}
Теперь в вашей форме добавьте элемент управления просмотра отчетов.
ReportViewer1 rpt = New ReportViewer();
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("path of rpt file");
rptDoc.SetDataSource(GetAllEmployees());
rpt.Document = rptDoc;
rpt.Refresh();
Перед этим из Crystal Report добавьте поля таблицы в отчет согласно вашему требованию.
Еще один способ достичь
Crystal Reports можно использовать над различными объектами. Если у вас есть сценарий для его динамического связывания, см. Мой ответ ниже. Тогда вы можете сделать одну вещь - добавить новый набор данных в решение. Создайте таблицу данных и добавьте необходимые столбцы с соответствующим типом данных. НЕ добавляйте запрос или табличный адаптер. Теперь из вашего кода добавьте файл класса и создайте свойства, точно такие же, как столбцы данных. Теперь установите источник данных в качестве источника отчета и добавьте его столбец в отчет.
For example , if you have columns
ID - integer
EmpName - string
Salary - double
Department - string
Создать класс
public class Employee
{
private SqlConnection _connection;
public int ID {get;set;}
public string EmpName {get;set;}
public double Salary {get;set;}
public string Department {get;set;}
/// <summary>
/// Sets the connection.
/// </summary>
public void SetConnection()
{
//assuming connection string is placed in settings file from Project Properties.
_connection = new SqlConnection(Settings.Default.connectionString);
if (_connection.State == System.Data.ConnectionState.Open)
{
_connection.Close();
}
_connection.Open();
}
/// <summary>
/// Closes the connection.
/// </summary>
public void CloseConnection()
{
if (_connection.State == System.Data.ConnectionState.Open)
{
_connection.Close();
_connection.Dispose();
}
}
public DataTable GetEmployees()
{
DataTable dt = new DataTable("Employee");
// using above connection
SetConnection();
using(SqlCommand command = new SqlCOmmand("commandText",_connection))
{
using(SqlDataReader reader = command.ExecuteReader())
{
dt.Load(reader);
}
}
return dt;
}
}
Теперь создайте другую функцию, которая будет заполнять таблицу данных, созданную внутри набора данных.
public void PopulateDataTable()
{
DataTable dt = GetEmployee();
Employee dsEmployee = New DataSet();
dsEmployee.EmployeeDataTable dtEmp = new dsEmployee.EmployeeDataTable();
dtEmp = dt;
}
Мы делаем нечто подобное с помощью Crystal Reports, и это заставило меня действительно не любить Crystal Reports. Используя эксперта по базе данных, я создал новое соединение с базой данных и новую команду с SQL, который я хочу использовать. Это определяет столбцы, которые Crystal Reports может использовать, и позволяет вам создавать отчет. Затем при отображении отчета мы делаем:
ReportDocument rd = new ReportDocument();
rd.Load(MapPathSecure("NameOfMyReport.rpt"));
rd.SetDataSource(dataSet.Tables[0]);
Я сделал это только с одной таблицей, поэтому я не знаю, как это повлияет на наличие нескольких таблиц в наборе данных. По сути, вы устанавливаете структуру отчета с помощью эксперта по базе данных и команды. Затем вы перезаписываете фактические данные во время выполнения. Я действительно хотел бы, чтобы у Crystal Reports был более надежный способ сделать это, или чтобы я понял это, если он существует.