none
Saber si existe base de datos de access 2007

    Pregunta

  • Hola a todos:

    Precisaría saber si existe una base de datos Access 2007 en el archivo de configuración.

    Clarifico el tema, tengo unos usuarios que trabajan con el access 2007 y la cadena de conexión está montada de la siguiente manera:

    Public Class Configuracion
    
        Public Shared Function CadenaConexion() As String
            Try
                Dim cnx As String = ConfigurationManager.ConnectionStrings("MiCadenaConexion").ConnectionString
                Return cnx & System.Text.Encoding.Default.GetString(System.Convert.FromBase64String("xxxxxxxxxxxxxxx=="))
            Catch exc As Exception
                Throw exc
            End Try
        End Function
    End Class

    Funciona correctamente, ahora bien, el problema lo tengo en que ahora el programa trabaja con 3 cadenas de conexión, quedando el método configuración de la siguiente manera:

      Public Shared Function CadenaConexion() As String
    
            Try
    
                If Configuracion.strNombreBaseDeDatos = "MiCadenaConexion" Then
                    Dim cnx As String = ConfigurationManager.ConnectionStrings("MiCadenaConexion").ConnectionString
                    Dim PasswordEncriptado As String = System.Text.Encoding.Default.GetString(System.Convert.FromBase64String("xxxxxxxxxw=="))
                    Return cnx & PasswordEncriptado
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoSqlEx" Then
                    Dim cnx As String = ConfigurationManager.ConnectionStrings("PerseoSqlEx").ConnectionString
                    Return cnx
    
                ElseIf Configuracion.strNombreBaseDeDatos = "PerseoSQLce" Then
                    Dim cnx As String = ConfigurationManager.ConnectionStrings("PerseoSQLce").ConnectionString
                    cnx &= ";Password=xxxx"
                    Return cnx
                Else
                    'Base de datos antigua única.
                    Configuracion.strNombreBaseDeDatos = "MiCadenaConexion"
                    Dim cnx As String = ConfigurationManager.ConnectionStrings("MiCadenaConexion").ConnectionString
                    Dim PasswordEncriptado As String = System.Text.Encoding.Default.GetString(System.Convert.FromBase64String("O0pldCBPTEVEQjpEYXRhYmFzZSBQYXNzd29yZD1semRsa2xncw=="))
                    Return cnx & PasswordEncriptado
                End If
    
            Catch exc As Exception
                Throw 'exc
            End Try
    
        End Function

    Bueno, querría saber discernir si el usuario es antiguo "Access 2007" o nuevo, en este caso se requiere que ya abra la SqlCompact y me estoy haciendo un lío con este tema, ya que la comprobación de si tiene Access la necesito hacer antes de que me grabe en el exe.config las nuevas base de datos (SqlCompact y SqlServer Express).

    Entiendo que si antes de la carga que realiza en el Submain compruebo que la conexión que utiliza es la antigua se la dejo y si no es así ya le pongo que coja la de SqlCompact. Os pongo el Submain y disculpar por tanto código pero será más fácil de entender:

      <STAThread()>
        Friend Shared Sub Main()
    
            Application.EnableVisualStyles()
            Application.SetCompatibleTextRenderingDefault(False)
    
            AddHandler Application.ThreadException, AddressOf Application_ThreadException
    
            'Added this
            AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionEventRaised
    
            'Comprobamos la instalación de SqlCOmpact 4.0
            ComprobarInstalaciónSqlCompact()
    
            'Comprobamos la instalación de Crystal Reports
            ComprobarInstalaciónMotorInformes()
    
            'Mostramos el tipo de versión del sistema operativo instalado
            VersionAInstalarDeAccess() 'Motor de Access
    
    
    
            LeerCadenasDeConexion()
    
            '***************
    
            ' ''BORRAR. esto es solo para que coja la base de datos inicialmente con la base de datos que queramos.
            'My.Settings.BaseDatosActual = "MiCadenaConexion"
            'My.Settings.Save()
            'MsgBox(My.Settings.BaseDatosActual)
    
            '**********
    
            If VarGlobal.strVersion = "DEF" Then
                Configuracion.strNombreBaseDeDatos = "PerseoSQLce"
                My.Settings.BaseDatosActual = "PerseoSQLce"
                My.Settings.Save()
            End If
    
            'Base de Datos actual
            If My.Settings.BaseDatosActual = "MiCadenaConexion" Then
                Configuracion.strNombreBaseDeDatos = "MiCadenaConexion"
    
            ElseIf My.Settings.BaseDatosActual = "PerseoSqlEx" Then
                Configuracion.strNombreBaseDeDatos = "PerseoSqlEx"
    
            ElseIf My.Settings.BaseDatosActual = "PerseoSQLce" Then
                Configuracion.strNombreBaseDeDatos = "PerseoSQLce"
    
            ElseIf My.Settings.BaseDatosActual = "PerseoMySql" Then
                Configuracion.strNombreBaseDeDatos = "PerseoMySql"
    
            ElseIf My.Settings.BaseDatosActual = String.Empty Then
                Configuracion.strNombreBaseDeDatos = "PerseoSQLce"
                My.Settings.BaseDatosActual = "PerseoSQLce"
                My.Settings.Save()
            End If
    
    
            'Mostramos el tipo de versión cargada por defecto.
            AccesoDatosConsultas.TIPO_VERSION()
    
            AccesoDatosFormulas.SeleccionControlTablaParametros()
            modIdiomas.CodigoPaises()
    
            Using frm As New frmPresentacion()
                frm.ShowDialog()
            End Using
    
            If Configuracion.strNombreBaseDeDatos = "MiCadenaConexion" Then
                If My.Settings.ConvertAccess = False Then
                    Using frm1 As New frmProcesoConversion
                        frm1.ShowDialog()
                    End Using
                End If
            End If
    
    
            If VarGlobal.WControl = "0" Or VarGlobal.WControl = "2" Or VarGlobal.WControl = "6" Or VarGlobal.WControl = "8" Or VarGlobal.WControl = "9" Then
                Dim frm As New frmDemo
                'AccesoDatosFormulas.MostrarDatosInstalaciónDemo()
                frm.ShowDialog()
                Application.Run()
            ElseIf VarGlobal.WControl = "K" Then
                Dim frmAct As New frmActivacion
                frmAct.ShowDialog()
                Exit Sub
            ElseIf VarGlobal.WControl = "X" Then
                Exit Sub
            End If
    
            '*************************************
    
            'Para cuando realizemos una actualización, no pasará por la licencia.
            'Ponemos la variable bolActualizacion a '''''true''''' cuando sea una actualización.
    
            VarGlobal.bolActualizacion = False  'True
    
            AccesoActualizacionDatos.ActualizarCampoPlazosEnParametrosEnActualizacion()
    
            '*************************************
    
            'La versión "BASIC" no entra por la licencia.
            If VarGlobal.strVersion = "DEF" Then
                VarGlobal.bolActualizacion = True
                VarGlobal.WControl = "1"
    
            End If
    
            If VarGlobal.bolActualizacion = False Then
                If ExisteArchivoLicencia() = True Then
                    If modSeguridad.LicenciaCorrecta Then
                        ' MsgBox("Licencia correcta.")
                    Else
                        NumeroProcesador() 'MsgBox("Licencia incorrecta.")
                        Exit Sub
                    End If
                Else
                    NumeroProcesador() 'MsgBox("Licencia incorrecta.")
                    Call NumeroProcesadorMaquina()
                    Exit Sub
                End If
            End If
    
    
            '//Login: Usuario y contraseña 
            Using lgn As New frmLogin()
                lgn.ShowDialog()
            End Using
    
            If LoginService.ContrasenaCorrecta = False Then
                Exit Sub
            Else
                If VarGlobal.WControl = "1" Then
                    Dim emp As New frmEmpresas
                    emp.Show()
                    Application.Run()
                ElseIf VarGlobal.WControl = "3" Or VarGlobal.WControl = "4" Then
                    AccesoActualizacionDatos.GrabarVariableControlenDemo_Control_1()
                    Dim emp As New frmEmpresas
                    emp.Show()
                    Application.Run()
                End If
            End If
    
        End Sub

    Bueno, espero que me haya hecho entender con este tema.

    Un cordial saludo a todos y feliz año.

    Gemma



    lunes, 2 de enero de 2017 7:49

Respuestas

  • ¡Madre mía el jaleo tan enorme que tienes! Me vas a disculpar, pero ya me pierdo con tu código. :-(

    No sé si serán los años o la cantidad tan enorme (EXAGERADA DIRÍA YO) de variables globales (o compartidas, como prefieras llamarlas) que tienes dispersadas por todo tu proyecto, pero me pierdo. ¿Por dónde le "meto mano" a todo el código fuente que has publicado?

    Vamos a tu pregunta:

    > Precisaría saber si existe una base de datos Access 2007 en el archivo de configuración.

    Siempre y cuando en tu archivo de configuración tengas una sola cadena de conexión para conectarte a una base de datos de datos, la solución sería fácil, porque tan sólo tienes que saber si el nombre del proveedor invariable de la cadena de conexión tiene el valor System.Data.OleDb:

      <connectionStrings>
        <clear />
        <add name="MiCadenaConexion" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;
    Data Source =|DataDirectory|\gemmafin.accdb" providerName="System.Data.OleDb" /> </connectionStrings>

    Pero como tienes TRES CADENAS DE CONEXIÓN DIFERENTES, con TRES NOMBRES DIFERENTES, y en el procedimiento LeerCadenasDeConexion utilizas también TRES VARIABLES BOOLEAN DIFERENTES y encima GLOBALES (ConexAccess, ConexSqlCompact y ConexServerEx), a ver cómo averiguas qué cadena de conexión es la que tienes que utilizar.

    Fíjate el bucle que estás recorriendo en el procedimiento LeerCadenasDeConexion:

    >         For Each cs As ConnectionStringSettings In settings
    >
    >                NombreConexion = (cs.Name)
    >
    >                Select Case NombreConexion
    >                    Case "MiCadenaConexion"
    >                        ConexAccess = True
    >
    >                    Case "PerseoSQLce"
    >                        ConexSqlCompact = True
    >
    >                    Case "PerseoSqlEx"
    >                        ConexServerEx = True
    >
    >                    Case Else
    >                        ConexAccess = True
    >                End Select
    >
    >                Proveedor = (cs.ProviderName)
    >                Conexion = (cs.ConnectionString)
    >            Next

    Al finalizar el bucle, digo yo que las TRES VARIABLES GLOBALES SERÁN TRUE, salvo que alguien edite el archivo de configuración y haya eliminado alguna de las TRES CADENAS DE CONEXIÓN.

    Para lo que estás haciendo, y cómo lo estás haciendo, mejor hubiera sido que diseñaras TRES APLICACIONES DIFERENTES, una para cada base de datos, porque en definitiva es lo que está haciendo tu aplicación al utilizar TRES CADENAS DE CONEXIÓN DIFERENTES y otras tantas variables globales por si la conexión es Access, SQL Server o SQL Server Compact. Menos mal que te has parado y no te ha dado con trabajar también con MySQL, Oracle, y restantes motores de bases de datos existentes, porque si con tres cadenas de conexión es ya una locura, no te quiero decir lo que hubiera sido con cuatro, cinco o seis motores de bases de datos más: el acabose cuando en realidad no debería ser así. :-))

    Me vas a disculpar Gemma, pero esto no se hace así. El motivo de tener una misma aplicación para trabajar con distintos proveedores de datos (o con "factorías de proveedores", que es como he observado que lo denominas), es para que en tu archivo de configuración de la aplicación tengas una ÚNICA CADENA DE CONEXIÓN, que dependiendo del proveedor invariable que se utilice en ella, así trabajará tu aplicación. Es decir, para que tengas una misma aplicación que trabaje con diferentes motores de datos, de tal manera que si un cliente quiere trabajar con Access, otro con SQL Server y un tercero con SQL Server Compact, no tengas que tener tres compilaciones diferentes de tu programa, porque con sólo cambiar la cadena de conexión en el archivo de configuración de la aplicación, debería ser MÁS QUE SUFICIENTE para lograr ese objetivo. Y sería el propio cliente (o su Administrador, si es que dispone de alguno), el que modificara el archivo de configuración de la aplicación para que se adapte a aquel motor de datos que desea utilizar. ¿Has captado la idea del motivo para que una aplicación cualquiera trabaje con un proveedor de datos invariable?

    Soy consciente de que cada motor de datos tiene sus peculiaridades propias, y que tienes que tenerlas en cuenta, pero para ello, entiendo que no es necesario tener un "CHORREÓN" de variables globales dispersas por todo el proyecto para conocer si estás trabajando con Access, SQL Server, o con el proveedor "Pepito.Jimenez.com", porque con una simple consulta a la cadena de conexión existente en el archivo de configuración, ésta te daría el nombre invariable del proveedor: "System.Data.OleDb" (para Access), "System.Data.SqlClient" (para SQL Server, incluido SQL Server Express), "System.Data.SqlServerCe.4.0" (para SQL Server Compact 4.0), y así sucesivamente con otros diferentes proveedores de datos. Pero como tienes TRES CADENAS DE CONEXIÓN DIFERENTES, ¿a ver cómo lo hacemos?

    Por cierto, y antes que se me olvide, observo también en el procedimiento LeerCadenasDeConexion (menos mal que te he preguntado qué es lo que hacía éste procedimiento), que ejecutas lo siguiente:

    >  If ConexAccess = False Then
    >      ...
    >      ...
    >      ...
    >      ' Nombre de la cadena de conexión
    >      s.Name = "MiCadenaConexion"
    >      ' Cadena de conexión propiamente dicha.
    >      s.ConnectionString = "Data Source =|DataDirectory|\gemmafin.accdb"
    >      ' Nombre del proveedor de datos invariable
    >      s.ProviderName = "Microsoft.ACE.OLEDB.12.0"   --> Esto está mal
    >      ...
    >      ...
    >   End If

    El nombre del proveedor de datos invariable para Access es "System.Data.OleDb". El valor "Microsoft.ACE.OLEDB.12.0" es el nombre del proveedor OleDb, y es el que se le tiene que asignar al parámetro Provider de la cadena de conexión, quedando ésta en el archivo de configuración de la aplicación como he indicado más arriba.

    ¿No estará aquí la solución para saber si "existe la base de datos de Access 2007"? Lo entrecomillo porque a decir verdad, poco tiene que ver el Asunto de tu pregunta con lo que en realidad deseas, que si he comprendido bien, no es ni más ni menos que conocer qué cadena de conexión de las tres que tiene tu app.config es la que debes de usar en tu aplicación dependiendo del cliente.

    Y para conseguirlo, tan solo le tienes que indicar al cliente las pautas necesarias para que él solito modifique el archivo de configuración de tu aplicación, porque se supone (o mejor dicho, se debería de suponer) que tu aplicación está más que preparada para trabajar con cualquier motor de base de datos de los permitidos por ella, y que su proveedor invariable aparezca en la ÚNICA CADENA DE CONEXIÓN que debería de existir en el archivo de configuración de la aplicación. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.





    lunes, 2 de enero de 2017 11:12
    Moderador

Todas las respuestas

  • "gemma_campillo" escribió:

    > disculpar por tanto código pero será más fácil de entender

    Pues yo creo que en éste caso no va a ser más fácil. :-(

    ¿Qué código se ejecuta en el procedimiento llamado LeerCadenasDeConexion()?

    ¡Feliz Año Nuevo!


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]


    lunes, 2 de enero de 2017 8:41
    Moderador
  • Hola maestro, buenos días.

    Este es el código.

    Private Shared Sub LeerCadenasDeConexion()
            '<add name = "PerseoMySql" connectionString="server=127.0.0.1;uid=root;pwd=lzdlklgs;port=3306;database=PerseoMySql;"   
            'providerName = "MySql.Data.MySQLClient" />
    
            'Leemos del archivo de configuración, las cadenas de conexión que tenemos.
            Dim settings As ConnectionStringSettingsCollection = ConfigurationManager.ConnectionStrings
            If Not settings Is Nothing Then
                For Each cs As ConnectionStringSettings In settings
    
                    NombreConexion = (cs.Name)
    
                    Select Case NombreConexion
                        Case "MiCadenaConexion"
                            ConexAccess = True
    
                        Case "PerseoSQLce"
                            ConexSqlCompact = True
    
                        Case "PerseoSqlEx"
                            ConexServerEx = True
    
                            'Case "PerseoMySql"
                            '    ConexMySql = True
                        Case Else
                            ConexAccess = True
                    End Select
    
                    Proveedor = (cs.ProviderName)
                    Conexion = (cs.ConnectionString)
                Next
            End If
    
            If ConexAccess = False Then
                Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath)
                Dim connectionStringsSection As ConnectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)
                ' Creamos una nueva cadena de conexión.
                Dim s As New ConnectionStringSettings()
                ' Nombre de la cadena de conexión
                s.Name = "MiCadenaConexion"
                ' Cadena de conexión propiamente dicha.
                s.ConnectionString = "Data Source =|DataDirectory|\gemmafin.accdb"
                ' Nombre del proveedor de datos invariable
                s.ProviderName = "Microsoft.ACE.OLEDB.12.0"
                connectionStringsSection.ConnectionStrings.Add(s)
                ' Guardamos los cambios en el archivo de configuración de la aplicación.
                config.Save(ConfigurationSaveMode.Full, False)
            End If
    
            If ConexSqlCompact = False Then
                Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath)
                Dim connectionStringsSection As ConnectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)
                ' Creamos una nueva cadena de conexión.
                Dim s As New ConnectionStringSettings()
                ' Nombre de la cadena de conexión
                s.Name = "PerseoSQLce"
                ' Cadena de conexión propiamente dicha.
                s.ConnectionString = "Data Source=|DataDirectory|\PerseoSQLce.sdf"
                ' Nombre del proveedor de datos invariable
                s.ProviderName = "System.Data.SqlServerCe.4.0"
                connectionStringsSection.ConnectionStrings.Add(s)
                ' Guardamos los cambios en el archivo de configuración de la aplicación.
                config.Save(ConfigurationSaveMode.Full, False)
            End If
    
            If ConexServerEx = False Then
                Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath)
                Dim connectionStringsSection As ConnectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)
                ' Creamos una nueva cadena de conexión.
                Dim s As New ConnectionStringSettings()
                ' Nombre de la cadena de conexión
                s.Name = "PerseoSqlEx"
                ' Cadena de conexión propiamente dicha.
                s.ConnectionString = "Data Source=.\SQLEXPRESS;Initial Catalog=PerseoSqlEx;Integrated Security=true"
                ' Nombre del proveedor de datos invariable
                s.ProviderName = "System.Data.SqlClient"
                connectionStringsSection.ConnectionStrings.Add(s)
                ' Guardamos los cambios en el archivo de configuración de la aplicación.
                config.Save(ConfigurationSaveMode.Full, False)
            End If
    
            'If ConexMySql = False Then
            '    Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath)
            '    Dim connectionStringsSection As ConnectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)
            '    'Creamos una nueva cadena de conexión.
            '    Dim s As New ConnectionStringSettings()
            '    ' Nombre de la cadena de conexión
            '    s.Name = "PerseoMySql"
            '    'Cadena de conexión propiamente dicha.
            '    s.ConnectionString = "server=127.0.0.1;uid=root;pwd=lzdlklgs;port=3306;database=PerseoMySql;"
            '    'Nombre del proveedor de datos invariable
            '    s.ProviderName = "MySql.Data.MySQLClient"
            '    'Añadimos la nueva cadena de conexión al objeto ConnectionStringsSection.
            '    connectionStringsSection.ConnectionStrings.Add(s)
            '    'Guardamos los cambios en el archivo de configuración de la aplicación.
            '    config.Save(ConfigurationSaveMode.Full, False)
            'End If
        End Sub
    

    Un abrazo.

    Gemma

    lunes, 2 de enero de 2017 9:09
  • ¡Madre mía el jaleo tan enorme que tienes! Me vas a disculpar, pero ya me pierdo con tu código. :-(

    No sé si serán los años o la cantidad tan enorme (EXAGERADA DIRÍA YO) de variables globales (o compartidas, como prefieras llamarlas) que tienes dispersadas por todo tu proyecto, pero me pierdo. ¿Por dónde le "meto mano" a todo el código fuente que has publicado?

    Vamos a tu pregunta:

    > Precisaría saber si existe una base de datos Access 2007 en el archivo de configuración.

    Siempre y cuando en tu archivo de configuración tengas una sola cadena de conexión para conectarte a una base de datos de datos, la solución sería fácil, porque tan sólo tienes que saber si el nombre del proveedor invariable de la cadena de conexión tiene el valor System.Data.OleDb:

      <connectionStrings>
        <clear />
        <add name="MiCadenaConexion" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;
    Data Source =|DataDirectory|\gemmafin.accdb" providerName="System.Data.OleDb" /> </connectionStrings>

    Pero como tienes TRES CADENAS DE CONEXIÓN DIFERENTES, con TRES NOMBRES DIFERENTES, y en el procedimiento LeerCadenasDeConexion utilizas también TRES VARIABLES BOOLEAN DIFERENTES y encima GLOBALES (ConexAccess, ConexSqlCompact y ConexServerEx), a ver cómo averiguas qué cadena de conexión es la que tienes que utilizar.

    Fíjate el bucle que estás recorriendo en el procedimiento LeerCadenasDeConexion:

    >         For Each cs As ConnectionStringSettings In settings
    >
    >                NombreConexion = (cs.Name)
    >
    >                Select Case NombreConexion
    >                    Case "MiCadenaConexion"
    >                        ConexAccess = True
    >
    >                    Case "PerseoSQLce"
    >                        ConexSqlCompact = True
    >
    >                    Case "PerseoSqlEx"
    >                        ConexServerEx = True
    >
    >                    Case Else
    >                        ConexAccess = True
    >                End Select
    >
    >                Proveedor = (cs.ProviderName)
    >                Conexion = (cs.ConnectionString)
    >            Next

    Al finalizar el bucle, digo yo que las TRES VARIABLES GLOBALES SERÁN TRUE, salvo que alguien edite el archivo de configuración y haya eliminado alguna de las TRES CADENAS DE CONEXIÓN.

    Para lo que estás haciendo, y cómo lo estás haciendo, mejor hubiera sido que diseñaras TRES APLICACIONES DIFERENTES, una para cada base de datos, porque en definitiva es lo que está haciendo tu aplicación al utilizar TRES CADENAS DE CONEXIÓN DIFERENTES y otras tantas variables globales por si la conexión es Access, SQL Server o SQL Server Compact. Menos mal que te has parado y no te ha dado con trabajar también con MySQL, Oracle, y restantes motores de bases de datos existentes, porque si con tres cadenas de conexión es ya una locura, no te quiero decir lo que hubiera sido con cuatro, cinco o seis motores de bases de datos más: el acabose cuando en realidad no debería ser así. :-))

    Me vas a disculpar Gemma, pero esto no se hace así. El motivo de tener una misma aplicación para trabajar con distintos proveedores de datos (o con "factorías de proveedores", que es como he observado que lo denominas), es para que en tu archivo de configuración de la aplicación tengas una ÚNICA CADENA DE CONEXIÓN, que dependiendo del proveedor invariable que se utilice en ella, así trabajará tu aplicación. Es decir, para que tengas una misma aplicación que trabaje con diferentes motores de datos, de tal manera que si un cliente quiere trabajar con Access, otro con SQL Server y un tercero con SQL Server Compact, no tengas que tener tres compilaciones diferentes de tu programa, porque con sólo cambiar la cadena de conexión en el archivo de configuración de la aplicación, debería ser MÁS QUE SUFICIENTE para lograr ese objetivo. Y sería el propio cliente (o su Administrador, si es que dispone de alguno), el que modificara el archivo de configuración de la aplicación para que se adapte a aquel motor de datos que desea utilizar. ¿Has captado la idea del motivo para que una aplicación cualquiera trabaje con un proveedor de datos invariable?

    Soy consciente de que cada motor de datos tiene sus peculiaridades propias, y que tienes que tenerlas en cuenta, pero para ello, entiendo que no es necesario tener un "CHORREÓN" de variables globales dispersas por todo el proyecto para conocer si estás trabajando con Access, SQL Server, o con el proveedor "Pepito.Jimenez.com", porque con una simple consulta a la cadena de conexión existente en el archivo de configuración, ésta te daría el nombre invariable del proveedor: "System.Data.OleDb" (para Access), "System.Data.SqlClient" (para SQL Server, incluido SQL Server Express), "System.Data.SqlServerCe.4.0" (para SQL Server Compact 4.0), y así sucesivamente con otros diferentes proveedores de datos. Pero como tienes TRES CADENAS DE CONEXIÓN DIFERENTES, ¿a ver cómo lo hacemos?

    Por cierto, y antes que se me olvide, observo también en el procedimiento LeerCadenasDeConexion (menos mal que te he preguntado qué es lo que hacía éste procedimiento), que ejecutas lo siguiente:

    >  If ConexAccess = False Then
    >      ...
    >      ...
    >      ...
    >      ' Nombre de la cadena de conexión
    >      s.Name = "MiCadenaConexion"
    >      ' Cadena de conexión propiamente dicha.
    >      s.ConnectionString = "Data Source =|DataDirectory|\gemmafin.accdb"
    >      ' Nombre del proveedor de datos invariable
    >      s.ProviderName = "Microsoft.ACE.OLEDB.12.0"   --> Esto está mal
    >      ...
    >      ...
    >   End If

    El nombre del proveedor de datos invariable para Access es "System.Data.OleDb". El valor "Microsoft.ACE.OLEDB.12.0" es el nombre del proveedor OleDb, y es el que se le tiene que asignar al parámetro Provider de la cadena de conexión, quedando ésta en el archivo de configuración de la aplicación como he indicado más arriba.

    ¿No estará aquí la solución para saber si "existe la base de datos de Access 2007"? Lo entrecomillo porque a decir verdad, poco tiene que ver el Asunto de tu pregunta con lo que en realidad deseas, que si he comprendido bien, no es ni más ni menos que conocer qué cadena de conexión de las tres que tiene tu app.config es la que debes de usar en tu aplicación dependiendo del cliente.

    Y para conseguirlo, tan solo le tienes que indicar al cliente las pautas necesarias para que él solito modifique el archivo de configuración de tu aplicación, porque se supone (o mejor dicho, se debería de suponer) que tu aplicación está más que preparada para trabajar con cualquier motor de base de datos de los permitidos por ella, y que su proveedor invariable aparezca en la ÚNICA CADENA DE CONEXIÓN que debería de existir en el archivo de configuración de la aplicación. ;-)


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.





    lunes, 2 de enero de 2017 11:12
    Moderador
  • Hola Enrique:

    Al final la pregunta es simplemente que cuando el usuario reciba la actualización pueda saber si tiene la conexión de Access únicamente o no, y ahora y para no complicar el tema, simplemente comprobaré el proveedor de datos si existe o no, en este caso el que voy a comprobar es SqlCompact. Que lo tiene no hago nada, puesto que se entiende que en la cadena de conexión ya existe dicho proveedor y si no está, es cuando se que únicamente tiene la conexión de Access.

    También es verdad que el código no necesita tantas propiedades y lo voy a limpiar, pero bueno, la pregunta era la del tema anterior y creo que esa es la mejor forma de saberlo.

    Si solo tiene Access es lógico que solamente trabaje con Access y si tiene Compact o Sql Server, no tengo que hacer nada ya que el my.settings, estará recogiendo la base de datos con la que trabaja la aplicación, y el cliente si quiere cambiar la base de datos, tiene una pantalla, que le permite cambiar de base de datos y traspasar los datos de una base a otra. Funciona perfectamente esto anterior. Ahora cuando lo tenga acabado lo verás.

    Bueno, está entendido el tema y voy a corregir lo que me has indicado.

    Si tengo alguna cosa te la comunico, pero entiendo que ahora lo tengo mucho más claro.

    Bueno maestro muchas gracias por tu ayuda como siempre u por la lógica que empleas.

    Un fuerte abrazo.

    Gemma

    lunes, 2 de enero de 2017 11:49