Как получить оператор SQL SELECT, используемый в отчете Crystal?

В настоящее время я работаю над программой на C#, которая позволяет нашим пользователям запускать, просматривать и экспортировать пакет Crystal Reports. Отчеты были сделаны с использованием графического интерфейса Crystal Reports 2008. Одна из основных причин для этого - позволить нам сохранять гиперссылки при экспорте отчета Crystal Report в PDF. Моя программа делает это, экспортируя в RTF, а затем преобразовывает RTF в PDF. Если кто-нибудь знает менее запутанный метод сохранения гиперссылок при конвертации в PDf, я бы хотел услышать это, но это не мой текущий вопрос.

Я провел множество тестов по оптимизации моей программы, чтобы экспорт занимал как можно меньше времени. Из того, что я видел, запрос приложения к данным, а затем привязка набора результатов к отчету Crystal Report - самый быстрый способ. Моя проблема в том, что я не могу жестко запрограммировать запросы в программе, их нужно получить из самого Crystal Report.

В Crystal Reports 2008 есть опция "Показать запрос SQL" в меню "База данных". Это вызывает окно с запросом SQL, используемым для данного отчета. Это именно то, что мне нужно, чтобы получить изнутри моего приложения. Я загрузил отчет Crystal и во время отладки перебрал объект ReportDocument, пытаясь найти запрос, но безуспешно.

Итак, мой вопрос: Есть ли какой-либо метод, который позволил бы мне вытащить запрос, используемый данным Crystal Report?

2 ответа

Решение

Итак, dotjoe дал мне все подсказки, которые мне нужны, чтобы решить это. Следующий код можно использовать для извлечения текста команды из отчета Crystal.

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;
}

Это выглядит немного грязно, но это имеет какой-то смысл, когда вы начинаете пробираться через него. По сути, он использует отражение, чтобы получить значение свойства CommandText, с небольшой добавленной динамикой, чтобы обойти динамические свойства в ReportDocument.

Это тянет за собой текст команды, но у меня не было времени на какие-либо тесты кода. Я уверен, что сделаю некоторые изменения, как только у меня будет время поработать с этим. Я понятия не имею, что происходит с отчетами, в которых не используются "команды SQL". Я отправлю комментарий, как только я проверю это дальше.

  • Скотт

PS Для этого необходимо, чтобы вы ссылались на стандартные библиотеки отражений / динамиков, а также на следующие библиотеки Crystal Report:

crystaldecisions.reportappserver.datadefmodel

crystaldecisions.crystalreports.engine

crystaldecisions.shared

Я понимаю, что это очень старый вопрос, но подумал, что я бы предложил альтернативу для тех, кто сталкивается с этим, но нуждается в целевой структуре 3.5 (динамическая недоступна в 3.5).

Для работы этого решения вам понадобятся следующие ссылки.

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

Тогда просто получите доступ к ClientDoc взаимодействовать со следующим и возвращать список командных текстовых строк.

    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();
    }
Другие вопросы по тегам