¿Cómo cambio la conexión de la base de datos ODBC de Crystal Report en tiempo de ejecución?

Tengo un informe hecho con Crystal Reports 2008 que necesito implementar un sistema de producción, lo que significa que necesito poder cambiar la conexión de la base de datos en tiempo de ejecución. La base de datos es PostgreSQL 8.3.0 y la conexión que uso para crear el informe inicial es una conexión ODBC.

He encontrado varias formas de cambiar la conexión de la base de datos, que incluye lo siguiente:

reportDoc.Load(report); reportDoc.DataSourceConnections[0].SetConnection("server", "database", "user", "pwd"); reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path); 

Sin embargo, esto siempre falla con el siguiente mensaje de error.

Error al abrir la conexión.

He validado los parámetros de conexión conectando con éxito a la base de datos con pgAdmin III, así que sé que los parámetros de conexión son correctos. Además, si elimino la línea SetConnection (…) para que el código se vea así:

 reportDoc.Load(report); reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path); 

a continuación, el informe se ejecuta correctamente utilizando los parámetros de conexión que se almacenan en el informe. ¿Es posible que este método no funcione para conexiones ODBC?

¿Cómo cambio la conexión de la base de datos ODBC de Crystal Report en tiempo de ejecución?

Después de investigar aún más , descubrí que había una respuesta en dos partes.

PARTE 1

Si se está conectando a PostgreSQL a través de ODBC (la única forma en que Crystal Reports puede extraer datos de PostgreSQL al momento de escribir esto) usando el propietario de los datos, puede usar el siguiente código:

 reportDoc.Load(report); reportDoc.DataSourceConnections[0].SetConnection("Driver={PostgreSQL ANSI};Server=myServer;Port=5432;", "myDatabase", "myUser", "myPassword"); reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path); // Depending on your application you may have more than one data source connection that needs to be changed. 

Este método solo funciona si se está conectando como un usuario que posee los datos sobre los que informa debido a que no es necesario proporcionar el nombre del esquema.

PARTE 2

Si se está conectando a PostgreSQL a través de ODBC con un usuario que no sea el propietario de los datos, entonces necesita suministrar manualmente el nombre del esquema. Esto se logra con el siguiente código.

 reportDoc.Load(report); ConnectionInfo connInfo = new ConnectionInfo(); connInfo.ServerName = "Driver={PostgreSQL ANSI};Server=myServer;Port=5432;"; connInfo.DatabaseName = "myDatabase"; connInfo.UserID = "myUser"; connInfo.Password = "myPassword"; TableLogOnInfo tableLogOnInfo = new TableLogOnInfo(); tableLogOnInfo.ConnectionInfo = connInfo; foreach (Table table in reportDoc.Database.Tables) { table.ApplyLogOnInfo(tableLogOnInfo); table.LogOnInfo.ConnectionInfo.ServerName = connInfo.ServerName; table.LogOnInfo.ConnectionInfo.DatabaseName = connInfo.DatabaseName; table.LogOnInfo.ConnectionInfo.UserID = connInfo.UserID; table.LogOnInfo.ConnectionInfo.Password = connInfo.Password; // Apply the schema name to the table's location table.Location = "mySchema." + table.Location; } reportDoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, path); 

Resumen

Aquí hay dos datos fundamentales cuando intentamos conectarnos a una base de datos PostgreSQL de Crystal Reports.

  1. El controlador, el servidor y el número de puerto se deben especificar en la propiedad del nombre del servidor.
  2. Si se conecta como un usuario que no sea el propietario de los datos, debe especificar el nombre del esquema para cada tabla desde la que extrae los datos.

Fuentes

Hubo varias fonts usadas que no tenían una respuesta que funcionara en mi escenario específico pero que me condujeron en la dirección correcta. Estas fonts se enumeran a continuación.

Acabo de pasar por esta misma prueba.

Configuré mis conexiones de esta manera (donde sDataSource, etc … son cadenas con la información)

  Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo() myConnectionInfo.ServerName = sDataSource myConnectionInfo.DatabaseName = sInitialCatalog myConnectionInfo.UserID = sUserID myConnectionInfo.Password = sPassword Dim myTables As Tables = report.Database.Tables Dim myTableLogonInfo As TableLogOnInfo = New TableLogOnInfo() myTableLogonInfo.ConnectionInfo = myConnectionInfo For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In myTables myTable.ApplyLogOnInfo(myTableLogonInfo) myTable.LogOnInfo.ConnectionInfo.DatabaseName = myTableLogonInfo.ConnectionInfo.DatabaseName myTable.LogOnInfo.ConnectionInfo.ServerName = myTableLogonInfo.ConnectionInfo.ServerName myTable.LogOnInfo.ConnectionInfo.UserID = myTableLogonInfo.ConnectionInfo.UserID myTable.LogOnInfo.ConnectionInfo.Password = myTableLogonInfo.ConnectionInfo.Password Next 

Actualización de ODBC dentro de un archivo de informe de Crystal.

Estamos utilizando ODBC con MSSQL, no pudimos encontrar cómo actualizar el ODBC dentro de los archivos de cristal dentro de un proyecto de C sharp.

Con el ejemplo proporcionado aquí pudimos encontrar la manera de actualizar ODBC dentro de MSSQL, y es tan simple como esto:

  Cursor.Current = Cursors.WaitCursor; CrystalDecisions.Windows.Forms.CrystalReportViewer CR_Viewer; CR_Viewer = new CrystalDecisions.Windows.Forms.CrystalReportViewer(); this.Controls.Add(CR_Viewer); ConnectionInfo connInfo = new ConnectionInfo(); connInfo.ServerName = "YOUR ODBC NAME"; TableLogOnInfo tableLogOnInfo = new TableLogOnInfo(); tableLogOnInfo.ConnectionInfo = connInfo; //THIS IS A CRYSTAL RPT FILE DIFINE AS A CLASS Facturation_Nord_Ouest.Reports.Facture_Français CrystalReportFr; CrystalReportFr = new Facturation_Nord_Ouest.Reports.Facture_Français(); for (int i = 0; i < CrystalReportFr.Database.Tables.Count; i++) { CrystalReportFr.Database.Tables[i].ApplyLogOnInfo(tableLogOnInfo); } CR_Viewer.ReportSource = CrystalReportFr; CR_Viewer.ActiveViewIndex = 0; CR_Viewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; CR_Viewer.Dock = System.Windows.Forms.DockStyle.Fill; CR_Viewer.Location = new System.Drawing.Point(0, 0); CR_Viewer.Size = new System.Drawing.Size(545, 379); CR_Viewer.TabIndex = 0; CR_Viewer.Name = "Invoice"; CR_Viewer.Zoom(100); CR_Viewer.Show(); Cursor.Current = Cursors.Default; 

Con esto, ODBC en el archivo de cristal se actualiza automáticamente.

Antes que nada, ¡gracias por esta información!

Estoy usando MySQL / C # / Crystal Reports. Después de configurar el ODBC / DSN algo tan simple como esto funcionó para mí.

 using CrystalDecisions.CrystalReports.Engine; using CrystalDecisions.Shared; using MySql.Data.MySqlClient; . . . ConnectionInfo connInfo = new ConnectionInfo(); connInfo.ServerName = "Driver={MySQL ODBC 3.51 Driver};DSN=MyODBCDatasourceName"; TableLogOnInfo tableLogOnInfo = new TableLogOnInfo(); tableLogOnInfo.ConnectionInfo = connInfo; // rpt is my Crystal Reports ReportDocument // Apply the schema name to the table's location foreach (Table table in rpt.Database.Tables) { table.ApplyLogOnInfo(tableLogOnInfo); table.Location = table.Location; } 
 protected void Page_Load(object sender, EventArgs e) { try { ReportDocument cryRpt = new ReportDocument(); TableLogOnInfos crtableLogoninfos = new TableLogOnInfos(); TableLogOnInfo crtableLogoninfo = new TableLogOnInfo(); ConnectionInfo crConnectionInfo = new ConnectionInfo(); cryRpt.Load(@"D:\tem\WebAppReport\WebAppReport\CrystalReport1.rpt"); crConnectionInfo.ServerName = "misserver"; crConnectionInfo.DatabaseName = "testAccountability_data"; crConnectionInfo.UserID = "RW"; crConnectionInfo.Password = "RW"; foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in cryRpt.Database.Tables) { crtableLogoninfo = CrTable.LogOnInfo; crtableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crtableLogoninfo); } CrystalReportViewer1.ReportSource = cryRpt; CrystalReportViewer1.RefreshReport(); } catch { } } 

Este trabajo para Sql Server 2008 R2 para DSN tiene menos conexión.

 Dim myConnectionInfo As CrystalDecisions.Shared.ConnectionInfo = New CrystalDecisions.Shared.ConnectionInfo() myConnectionInfo.ServerName = "Driver={SQL Server Native Client 10.0};Server=P03\sqlrs1;" myConnectionInfo.DatabaseName = "RS1DB" myConnectionInfo.UserID = "user" myConnectionInfo.Password = "pwd" For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In mboReportDocument.Database.Tables Dim myTableLogonInfo As TableLogOnInfo = myTable.LogOnInfo myTableLogonInfo.ConnectionInfo = myConnectionInfo myTable.ApplyLogOnInfo(myTableLogonInfo) Next