2011-11-15 24 views
7

Actualmente estoy trabajando en un programa en C# que permite a nuestros usuarios ejecutar, ver y exportar un lote de Crystal Reports. Los informes se realizaron utilizando la GUI de Crystal Reports 2008. Una de las razones principales para hacer esto es permitirnos conservar hipervínculos cuando el Informe de Crystal se exporta a PDF. Mi programa hace esto exportando a rtf, luego convirtiendo el rtf a un pdf. Si alguien sabe de un método menos intrincado para preservar hipervínculos al convertir a PDf, me encantaría escucharlo, pero esa no es mi pregunta actual.¿Cómo puedo recuperar la instrucción SQL SELECT utilizada en un Crystal Report?

He hecho muchas pruebas sobre cómo optimizar mi programa para que la exportación tome el menor tiempo posible. Por lo que he visto, tener la consulta de la aplicación para los datos, luego vincular el conjunto de resultados al Informe de Crystal es, de lejos, el método más rápido. Mi problema es que no puedo codificar las consultas en el programa, deben ser rescatadas del mismo informe de Crystal.

En Crystal Reports 2008, hay una opción llamada "Mostrar consulta SQL" en el menú Base de datos. Esto abre una ventana con la consulta SQL utilizada para el informe dado. Esto es exactamente lo que necesito tener en mis manos desde mi aplicación. Cargué un informe de Crystal y, durante la depuración, atravesé el objeto ReportDocument tratando de encontrar la consulta, pero no tuve suerte.

Entonces, mi pregunta es; ¿hay algún método disponible que me permita extraer la consulta utilizada por un Crystal Report dado?

+0

Si la tabla del informe es un "Comando SQL", ¿aún puede establecer la fuente de datos? Pensé que la tabla tenía que crearse a partir de un conjunto de datos (xsd)? – dotjoe

+0

En mi prueba, Crystal Report usaba un "Comando SQL" como la "Tabla". No tuve problemas para vincular el informe a un conjunto de datos que había consultado desde la base de datos, utilizando la misma selección SQL que formaba el "Comando SQL" en el informe. Funcionó perfectamente, y fue mucho más rápido que obtener el informe para actualizar sus propios datos. – Chronicide

+0

Interesante, estoy tratando de convertir los informes al modelo PUSH y tal vez no sea necesario si puedo pasar el datasource. Los míos son todos los procedimientos almacenados a través de parámetros w/w/out. – dotjoe

Respuesta

2

Bien, entonces dotjoe me dio todos los consejos que necesitaba para resolver esto. El siguiente código se puede usar para extraer el texto de comando de un informe de 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; 
} 

Parece un poco desordenado, pero tiene algún sentido cuando empiezas a vadearlo. Básicamente, utiliza la reflexión para obtener el valor de la propiedad CommandText, con un poco de dinámica lanzada para pasar las propiedades dinámicas en el ReportDocument.

Esto está tirando del texto de comando para mí, pero no he tenido tiempo de hacer ninguna prueba en el código. Estoy seguro de que haré algunas modificaciones una vez que haya tenido tiempo de trabajar con esto. No tengo idea de qué ocurre con los informes que no usan "Comandos SQL". Publicaré un comentario una vez que haya probado esto más.

  • de Scott

P. S. Esto requiere que se hace referencia a las bibliotecas dinámicas de reflexión/estándar, así como las siguientes bibliotecas de Crystal Report:

crystaldecisions.reportappserver.datadefmodel

CrystalDecisions.CrystalReports.Engine

CrystalDecisions.Shared

+0

muy buen trabajo! – dotjoe

+0

Quiero el comando sql con parámetros reemplazados, con el código dado puedo obtener el comando sql pero los parámetros no se reemplazan con los valores proporcionados. ¿Cómo puedo obtener la declaración sql final? & ¿Puedo obtener el DataSet de la consulta en una colección IEnumerable o una tabla de datos usando ReportDocument? – zeppelin

3

Me doy cuenta de que esta es una pregunta muy antigua, pero pensé que ofrecería una alternativa para aquellos que se toparan con esto pero necesitan un objetivo marco de 3.5 (la dinámica no está disponible en 3.5).

Necesitará las siguientes referencias para que esta solución funcione.

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

A continuación, sólo acceda a la interfaz ClientDoc con la siguiente y devolver una lista de cadenas de texto de comando.

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

Me gusta de esta manera lo mejor; es más fácil de leer y entender – tuespetre

+0

@tuespetre ¡Gracias! Me alegro de que ayudó! –

Cuestiones relacionadas