Para entender el post necesitas: Tener conocimientos de SQL Server, Crystal Reports y Visual Basic 6, así como estar familiarizado con las conexiones vía ODBC.

Parece que, desde la versión 8 ó 9 de Crystal Reports, existe un problema a la hora de cambiar la base de datos a la que queremos conectar cuando lanzamos un informe, ya sea utilizando los módulos RDC o .NET de Crystal Reports. Recuerdo haberle dado muchas vueltas en su día, cuando tuve que programar un administrador de informes con sus filtros y la información de conexión vía ODBC (nombre del DSN, driver, servidor, usuario y contraseña) de modo que fuesen fácilmente configurables. Por aquel entonces cargaba (innecesariamente) los datos en un RecordSet con la sentencia SQL del informe y luego se lo asignaba al objeto CRAXDRT.Report correspondiente. Creía que el método funcionaba correctamente, hasta que tuve que hacer un pequeño lanzador de informes con el runtime de Crystal Reports XI y detectamos que siempre atacaba a la base de datos que fuese declarada en el informe origen. Después de quebraderos de cabeza varios, y hacer muchas tonterías, di con la solución al comprobar la sentencia SQL del informe (que era lo primero que tenía que haber hecho, leches).

Parece que desde la versión 8 en adelante, se les ocurrió la genial idea de dejar guardada la información de la base de datos a la que debía conectar el informe explícitamente en la clausula FROM de la dichosa sentencia SQL. De modo que, hagas lo que hagas con la cadena de conexión del informe, a éste le basta con encontrar el servidor SQL al que estaba enlazado para que deseche la nueva información o, si no la encuentra, seguramente falle sin más.

Por suerte, este problema tiene solución sin tocar la sentencia SQL. Basta con modificar los datos de conexión de las tablas utilizadas en el informe (ya sea alterando la ConnectionString o las ConnectionProperties) y alterar el origen de los datos mediante la propiedad Location de la tabla. A continuación os dejo el código fuente de una función con la que podéis atajar el problema:

Entorno utilizado: Visual Basic 6 SP6 con el runtime de Crystal Reports XI Release 2.
Base de datos: SQL Server 2000. Puede ser útil también para Oracle.


Public Function AplicaCambios(ByRef crrep As CRAXDRT.Report _
, strDsn As String, strServer As String, strDb As String _
, strUid As String, strPwd As String, strDriver As String) As Boolean
    Dim i As Integer
    Dim esSqlServer As Boolean

    AplicaCambios = True

    'Comparamos sin distinguir mayúsculas. _
     Si se trata de un report contra SQL Server tendremos _
     que procesar el Location de cada tabla.

    If InStr(1, strDriver, "SQL SERVER", vbTextCompare) Then
        esSqlServer = True
    Else
        esSqlServer = False
    End If

    For i = 1 To crrep.database.Tables.Count
        With Me.crReport.database.Tables(i)
            Call .ConnectionProperties.DeleteAll

            Call .ConnectionProperties.Add("DSN", strDsn)
            Call .ConnectionProperties.Add("Server", strServer)
            Call .ConnectionProperties.Add("Database", strDb)
            Call .ConnectionProperties.Add("User ID", strUid)
            Call .ConnectionProperties.Add("Password", strPwd)
            Call .ConnectionProperties.Add("UseDSNProperties", False)

            If esSqlServer Then
                On Error Resume Next
                .Location = strDb & ".dbo." & .Location

                If Err.Number Then
                    Call MsgBox("Error al procesar los nombres de las tablas: " _
                    & vbCrLf & .Location & " al pasar a " _
                    & strDb & ".dbo." & .Location _
                    & vbCrLf & Err.Number & ": " & Err.Description)

                    AplicaCambios = False
                    Exit For
                End If
                On Error GoTo 0
            End If
        End With
    Next
End Function 'AplicaCambios


La comprobación del driver no sé si os resultará útil; en mi caso, el programa lo utilizo para atacar mediante ODBC a SQL Server o a ficheros de texto plano; por eso no aplico el cambio de la propiedad Location siempre.

Por último, creo conveniente comentar que una de las ventajas de Crystal Reports XI es que no hay que procesar los subinformes, ya que todas las tablas se encuentran localizadas en el miembro Database del objeto CRAXDRT.Report. Creo recordar que, para la versión 9, sí era necesario recorrer todas las secciones para aplicar los cambios.

Espero que sirva de ayuda a alguien. Para sugerencias o dudas, tienen a su disposición los comentarios.