Есть ли какой-либо способ ускорить генерацию crystal reports?

#asp.net #crystal-reports

#asp.net #crystal-отчеты

Вопрос:

Мы запускаем веб-приложение для создания отчетов, которое позволяет пользователю выбирать несколько полей, и на основе выбранных полей генерируется crystal report. SQL, сгенерированный для самого сложного отчета, вернет данные менее чем за 5 секунд, однако на выполнение отчета уходит в среднем 3 минуты, иногда дольше, что приводит к тайм-ауту. Мы используем VS2010. Отчеты в основном настраиваются «из коробки» без каких-либо реальных манипуляций или вычислений, просто отображая данные в удобном формате. Можем ли мы попытаться ускорить это, предварительно загрузив фиктивный отчет для загрузки DLL, какой-нибудь хак, чтобы ускорить работу crystal, что угодно?

РЕДАКТИРОВАТЬ: Добавлен код для отображения привязки данных

 protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        string strFile = Server.MapPath(@"AwardStatus.rpt");
        CrystalReportSource1.Report.FileName = strFile;
        DataTable main = Main();
        CrystalReportSource1.ReportDocument.SetDataSource(main);

        CrystalReportViewer1.HasCrystalLogo = false;

        CrystalReportSource1.ReportDocument.ExportToHttpResponse(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, Response, false, "pmperformance");

    }
}

private DataTable Main()
{
    Guid guidOffice = Office;
    CMS.Model.ReportsTableAdapters.ViewACTableAdapter rptAdapter = new CMS.Model.ReportsTableAdapters.ViewACTableAdapter();

    Reports.ViewAwardedContractsDataTable main = new Reports.ViewAwardedContractsDataTable();

    if (Office == new Guid())
    {
        IEnumerable<DataRow> data = rptAdapter.GetData().Where(d => UserPermissions.HasAccessToOrg(d.guidFromId, AuthenticatedUser.PersonID)).Select(d => d);
        foreach (var row in data)
        {
            main.ImportRow(row);
        }
    }
    else if (guidOffice != new Guid())
    {
        main = rptAdapter.GetDataByOffice(guidOffice);
    }
    else
    {
        main = new Reports.ViewACDataTable();
    }


    return main;
}

private Guid Office
{
    get
    {
        string strOffice = Request.QueryString["Office"];
        Guid guidOffice = BaseControl.ParseGuid(strOffice);

        if (!UserPermissions.HasAccessToOrg(guidOffice, AuthenticatedUser.PersonID))
        {
            return Guid.Empty;
        }
        else
        {

            return guidOffice;
        }
    }
}



protected void CrystalReportSource1_DataBinding(object sender, EventArgs e)
{
   //TODO
}
  

Комментарии:

1. Как вы привязываете данные к отчету? Можете ли вы опубликовать код, который генерирует отчет?

2. Если вы пройдетесь по этому коду, зависнет ли он в какой-либо момент? Похоже, вы выполняете изрядную часть обработки для DataTable.

3. @Barry — нет, кажется, что все выполняется довольно быстро, никаких реальных зависаний, о которых нужно предупреждать.

4. Какого размера файл отчета? Сохраняется ли вместе с отчетом большой объем данных, что может привести к увеличению времени загрузки из-за размера файла?

Ответ №1:

Это может показаться немного легкомысленным, но, возможно, стоит отказаться от использования crystal reports… Недавно у нас были с ними изрядные проблемы (одна из них — ошибка нехватки памяти), и мы перешли к другим вариантам и вполне довольны…

Комментарии:

1. мы склоняемся к этому, если мы не можем устранить некоторые из этих недостатков, к чему вы перешли, что вам нравится?

2. Я и раньше с некоторым успехом пользовался MS Reporting Services, но в этом случае нам нужны были PDF-файлы, и мы обратились к написанию собственных с помощью iTextSharp — немного кривой обучения, но выводим точно так, как требуется, и очень быстро. И больше никаких разочарований дизайнера crystal reports.

3. Не знаю, имеет ли это значение, но уровень поддержки MS для CR, похоже, снижается: blogs.msdn.com/b/vbteam/archive/2010/04/08 /…

Ответ №2:

Вот что я бы сделал:

Установите часы с момента получения пользователем выбора полей вплоть до момента отображения отчета. Посмотрите, насколько увеличивается время обработки.

Когда вы смотрите на часы, могут возникать различные ситуации:

  1. Если Crystal Reports требует времени для заполнения отчета, проверьте, как вы его заполняете. Если вы связываете поля отчета непосредственно с вашей таблицей данных, CR, вероятно, тратит время на поиск данных. Я предлагаю создать новую таблицу (t_rpt) с динамическими столбцами (Field1, Field2, ..FieldN) и указать ваш шаблон отчета на эту таблицу. Я не знаю, делаете ли вы это уже.

  2. Если вам требуется время для поиска самих данных, я предлагаю создать представление вашей таблицы. Несмотря на большой объем памяти, это ускорит поиск, и вы сможете удалить представление, как только закончите.

Если ничего из вышеперечисленного нет, сообщите нам, что показывают ваши часы.

Ответ №3:

Что касается загрузки любого большого объема данных, вы всегда захотите использовать хранимую процедуру.

Помимо этого, вы увидите задержку в отчете, выполняемом при первой загрузке библиотеки DLL Crystal. Да, вы можете предварительно загрузить их, как вы упомянули, и это немного поможет.