Создание отчетов в reportviewer из хранимой процедуры

131
09 июня 2019, 22:20

Использую SQL Server 2014, VS 2017 Суть в том, что нужно по параметрам создавать отчеты, например, вывести какие-нибудь записи за указанный период времени. Я пытался сделать это следующим образом:

  1. Написать хранимую процедуру для вывода отчета
  2. Через DataSet вывести в reportViewer (т к отчеты используют DataSet)

В итоге процедуру написал, результат вывел в DataSet и на этом все:

string sqlExpression = "Вывод_всего_транспорта";
using (SqlConnection connection = new SqlConnection(SQL.connString))
{
      connection.Open();
      SqlCommand command = new SqlCommand(sqlExpression, connection);
      command.CommandType = CommandType.StoredProcedure;
      DataSet ds = new DataSet();
      SqlDataAdapter da = new SqlDataAdapter(command);
      da.Fill(ds);
}

Дальше, как ни пытался в reportViewer не выводится ничего? Буду рад любой помощи

Answer 1

Мой ответ не претендует на решение Вашего вопроса, но я покажу как реализован вывод отчетов у меня. Может пригодится или натолкнет на мысль.

Предположим у нас есть форма (Form1), на которой находятся DataGridView для вывода данных из БД, два datetimepicker для фильтрации по времени и кнопка "Отчет". По нажатию кнопки открывается вторая форма (Form2), на которой лежит компонент reportviewer.

В Form1 создаем следующий метод и кидаем в обработчик кнопки "Отчет":

void Nakladnaya()
        {
            if (dataGridView1.SelectedCells.Count > 0)
            {
                var aktIds = new List<int>();
                // получаем список id записей в таблице
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    aktIds.Add((int)row.Cells["pit_id"].Value);
                }
                //открываем форму с отчетом
                var reportForm = new PriemIzTZAReport("Прием из ТЗА", aktIds);
                reportForm.Show();
            }
            else
            {
                MessageBox.Show("Нет данных для экспорта");
            }

Метод для фильтрации данных в DataGridView с помощью двух datetimepicker:

 if (dateTimePicker1.Checked)
        {
            filterStr += " and pit_date_ins >= '" + dateTimePicker1.Value.ToString() + "'";
        }
        if (dateTimePicker2.Checked)
        {
            string dt_do = dateTimePicker2.Value.ToString();
            filterStr += " and pit_date_ins <= '" + dt_do + "'";
        }
        if (dataGridView1.DataSource != null)
        {
            (dataGridView1.DataSource as DataTable).DefaultView.RowFilter = filterStr;
        }

Во второй форме код выглядит следующим образом:

    private readonly string headerText;
    private List<int> aktIds;
    public PriemIzTZAReport()
    {
        InitializeComponent();
    }
    public PriemIzTZAReport(string headerText, List<int> aktIds)
    {
        InitializeComponent();
        this.headerText = headerText;
        this.aktIds = aktIds;
    }
    private void PriemIzTZAReport_Load(object sender, EventArgs e)
    {
        try
        {
            Text = headerText;
            var dt = BaseWorker.GetPriemIzTZAReport(aktIds);
            if (dt == null)
            {
                throw new Exception("Не удалось получить данные из БД");
            }
            var rds = new ReportDataSource("DataSet1", dt);
            reportViewer1.LocalReport.DataSources.Add(rds);
            reportViewer1.RefreshReport();
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        this.reportViewer1.RefreshReport();
    }

В моем случае, в классе BaseWorker лежат запросы и процедуры для обращения к БД

 var dt = BaseWorker.GetPriemIzTZAReport(aktIds);

Код в классе Baseworker:

//формирование отчета прием из тза
        internal static DataTable GetPriemIzTZAReport(List<int> aktIds)
        {
            SqlConnection conn = BaseWorker.GetConnection();
            try
            {
                var stringIds = new StringBuilder();
                aktIds.ForEach(id => stringIds.Append($"{id},"));
                var sqlQueryString = $"SELECT * FROM dbo.Table WHERE pit_id IN({stringIds.ToString().TrimEnd(',')})";
                SqlCommand cmd = new SqlCommand(sqlQueryString, conn);
                DataTable data = null;
                SqlDataAdapter dataAdapter = null;
                //формируем и устанавливаем источник данных для таблицы
                data = new DataTable();
                dataAdapter = new SqlDataAdapter(cmd);
                dataAdapter.Fill(data);
                if (data.Rows.Count == 0)
                {
                    return null;
                }
                return data;
            }
            catch (Exception exc)
            {
                conn.Close();
                MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

Далее на вторую форму добавляем компонент reportviewer, создаем новый отчет, указываем DataSet1, выбираем или создаем источник данных, выбираем нужную таблицу, рисуем шаблон, и указываем какие столбцы хотим выводить.

READ ALSO
WPF приложение не видит новое окно

WPF приложение не видит новое окно

Я создал новое окно и хочу прописать показ формы через обработчик событий

111
Назначение ItemGroup с Compile=Remove в файле проекта

Назначение ItemGroup с Compile=Remove в файле проекта

В проекте aspnet core + entity framework core мне не очень нравится, как быстро пухнет папка миграций и я стал часто squash'ить (как в гите — не знаю точного термина)...

124
php: добавить данным из БД атрибуты микроразметки

php: добавить данным из БД атрибуты микроразметки

Второе в моей жизни "столкновение" с php сломало мой незрелый мозг гуманитарияПытаюсь добавить в скрипт, выводящий данные из БД в html, атрибуты...

174
Проблема со swiftmailer на локальном сервере

Проблема со swiftmailer на локальном сервере

На локальном сервере установил заглушку fakesandmail(/usr/bin/fakesendmailsh -bs)

117