none
Como seleccionar la base de datos cuando inicie la aplicacion

    Question

  • Hola, mi intencion es que la misma aplicacion cree una base de datos por cliente o empresa,(teniendo todas las mismas caracteristicas, solo camiaria el nombre) y cuando que cuando inicie la aplicacion, aparezca un form preguntando que base de datos deseo abrir. Y ya modificar o añadir los datos.

    Estoy usando base de datos en acces.

    Gracias por la ayuda.

    Monday, October 08, 2012 7:02 PM

Answers

  • Hola:
    Crea un proyecto nuevo y le añades un modulo como este.

    Option Explicit On
    Option Strict On

    Module Inicio
        Public msCadenaConexion As String
        '
        Private _prevInstanceMutex As System.Threading.Mutex

        Public Sub Main()
            ' Compruebo si existe una instancia
            If lF_PreviaInstancia() = True Then
                MessageBox.Show("La aplicacion ya se esta ejecutando", "Sub Main", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return
            End If
            'Ejecutamos nuestra aplicación
            Application.EnableVisualStyles()
            Using loForm As New FrmSeleccionCliente
                loForm.ShowDialog()
                Resultado = loForm.DialogResult
            End Using
            Dim loPrincipal As New FrmPrincipal
            Application.Run(loPrincipal)
        End Sub

        Private Function lF_PreviaInstancia() As Boolean
            Dim lbNuevo As Boolean
            Dim lsNombre As String
            ' Obtengo el nombre completo del ensamblado para usarlo como nombre del mutex
            lsNombre = Reflection.Assembly.GetEntryAssembly.FullName
            ' Creo el mutex intentando ser su propietario. Si el mutex ya fue creado por otra instancia, no se va a poder tomar propiedad del 'mutex y nuevo sera = false
            _prevInstanceMutex = New System.Threading.Mutex(True, lsNombre, lbNuevo)
            Return Not lbNuevo
        End Function
    End Module

    en Proyecto > Propiedades > Objeto de inicio > Sub Main

    Lo primero que se carga es el FrmSeleccionCliente que tiene 1 DataGridView (dgrDatos) y se le cargan todos los clientes.
    Tienes que tener una tabla como esta (En este caso es de SQL para que se vea mejor la diferencia.
    CLIENTE
    =======
    ID_CLIENTE Tinyint  PK
    NOMBRE  Varchar(50)
    CADENA_CONEXION Varchar(255)
    demas campos

    Codigo de FrmSeleccionCliente

    Option Strict On
    Option Explicit On
    Imports System.Data
    Imports System.Data.OleDb
    Imports System.Data.SqlClient

    Public Class FrmSeleccionCliente
        Private Sub FrmSeleccionCliente_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim lsQuery As String = "Select NOMBRE, CADENA_CONEXION From CLIENTE Order By NOMBRE"
            Me.dgrDatos.DataSource = gF_dtActualizaGrid(lsQuery)
            Me.dgrDatos.Columns("CADENA_CONEXION").Visible = False
        End Sub

        Private Sub dgrDatos_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgrDatos.CellContentClick
            If e.RowIndex = -1 Then
                Return
            End If
            Dim loFila As DataGridViewRow = Me.dgrDatos.CurrentRow()
            msCadenaConexion = loFila.Cells("CADENA_CONEXION").Value.ToString()
            Me.Close()
        End Sub

        Private Function lF_dtActualizaGrid( ByVal vsQuery As String) As DataTable
            If (vsQuery = String.Empty) Then
                Return Nothing
            End If
            Try
                Dim loDataTable As New DataTable
                Using loConexion As New SqlConnection(TU_CADENACONEXION_SQL)
                    Dim loDataAdapter As New SqlDataAdapter(vsQuery, loConexion)
                    loDataAdapter.Fill(loDataTable)
                End Using
                Return loDataTable
            Catch ex As Exception
                MessageBox.Show(ex.Message, "lF_dtActualizaGrid", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return Nothing
            End Try
        End Function
    End Class

    Con este Form se consigue cargar la variable msCadenaConexion.
    Una vez que se ha cerrado este Form, se abrira el Form Principal.
    En los siguientes Form cuando quieras abrir una conexion contra la base de datos de Acces usaras siempre la siguiente instruccion:

    Using loConexion As New OleDbConnection(msCadenaConexion)
        ... tus instrucciones
    End Using

    Espero que se entienda
    Un saludo desde Bilbo
    Carlos

    • Marked as answer by nigoman Sunday, October 21, 2012 10:57 PM
    Monday, October 15, 2012 10:52 AM

All replies

  • es que estas equivocando la forma de lograrlo, se spone que en la aplicacion configuras la conexiones, no se la pides al usuario

    para eso existe el app.config el cual puedes editar con el notepad y no solicitar nada al usuario

    ADO.NET Parte 4 Actualización Información Ms Access

    ADO.NET - Parte 2 - Recuperar Información MS  Access

    la db deberia crearse al momento de la instalacion, no esta bien visto que la seleccione o defina el usuario

    en tu aplicativo pon una db de base que se instale al usuario, no necesitas crearla y definir la estructura en runtime

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Monday, October 08, 2012 7:49 PM
  • es que estas equivocando la forma de lograrlo, se spone que en la aplicacion configuras la conexiones, no se la pides al usuario

    para eso existe el app.config el cual puedes editar con el notepad y no solicitar nada al usuario


     En teoria lo que quiero hacer es como si el usuario cuando inicie seleccionar en una tabla o listado el nombre de la empresa y que inice el programa y pueda modificar/borrar/intrducir datos de esa empresa y la idea es que cada empresa tubiera su propia db.

    En definitiva lo que querria hacer es , guardar la bd despues de modificarla o guardar una copia y luego pueda elegir al abrir entre la copia, copias  o la original.

    Gracias y saludos

         
    • Edited by nigoman Monday, October 08, 2012 11:03 PM
    Monday, October 08, 2012 11:02 PM
  • entonces define en el connection string tantas entradas como empresas tengas, al usuario le das a seleccionar los nombres de las key de conxion del config para que seelccione contra cual empresa va a trabjar

    pero vuelvo a plantear que el usuario no deberia configurar nada de esto, lo harias previamente en el config definiendo las N cadena de conexion de cada empresa habilitada

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Tuesday, October 09, 2012 1:09 AM
  • entonces define en el connection string tantas entradas como empresas tengas, al usuario le das a seleccionar los nombres de las key de conxion del config para que seelccione contra cual empresa va a trabjar

    pero vuelvo a plantear que el usuario no deberia configurar nada de esto, lo harias previamente en el config definiendo las N cadena de conexion de cada empresa habilitada

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Hola leandro gracias por responder, pero no puedo "predefinir" las empresas ya que las empresas las mete el usuario, no podria predefinir empresas con las bd en blanco solo para elegir, si el usuario necesita alguna mas no podria crearla. O eso es lo que te he entendido.

    Planteandolo de otra forma, el programa tendria que hacer lo mismo que hace word con un documento de texto, tiene uno en blanco ( en este caso una bd sin información, pero con sus tablas ) se abre y se introducen datos, puedes guardar sobre el mismo archivo y luego abrirlo y recuperar los datos metidos o guardarlo como una copia o con otro nombre y que permita abrirlo tambien ( ya que no tendria el mismo nombre, pero si la misma estructura de tablas ) . Y mi idea es que el usuario tubiera que elegir la empresa con la que va a trabajar ( empresa asociada a una bd, copia o original ) cuando inicia la aplicacion o en un apartado donde pueda elegir o crear la empresa ( en este caso, recuperar un bd o crear una nueva ). Pero sin tocar practicamente nada, solo meter en un textbox el nombre y presionar un boton y el programa realice el resto.

    espero haber planteado bien la cuestion.

    Gracias.

    Tuesday, October 09, 2012 9:31 AM
  • Hola, no se si entiendo bien el caso pero ahi va mi punto de vista...

    Si lo que deseas es hacer un sistema con varias empresas para separar cuentas contables, ventas, etc. lo que debes hacer no es separar las bases de datos ya que esto es un gran problema como puedes ver (entramos en el dilema del huevo y la gallina) sin embargo existen alternativas muy buenas (no somos lo primeros en hacer esto), veamos:

    En las bases de datos existen apuntadores y llaves (primarias, foraneas), que sirven para hacer una relacion, asi puedes interelacionar los datos de una venta con su detalle en tablas distintas, pero si vas mas alla puedes agrupar ventas por sucursal que estas a su vez tendran un detalle y si vamos mas alla tendras Empresas con sus respectivas sucursales con sus respectivas ventas con sus detalles, no se si me explico pero lo que debes hacer es agrupar en una misma BD todas tus empresas, con sus sucursales, ventas y detalles y separarlas logicamente y NO fisicamente (es decir NO en otra BD) de esta forma tendras la oportunidad de que el usuario cree las empresas que necesite dentro de una UNICA BD ya que la nueva empresa sera un indice mas al cual apuntaran todos los registros que de esta deriven

    Espero que me haya explicado y creeme que esto es mucho mejor pues aprovechas la funcionalidad, rendimineto y administracion de tu sistema, solo haz un poco de memoria y veras que antes se trabajaba con archivos separados como tablas y que por eso se evoluciono a las BD que son conjuntos de tablas, en resumen hacer lo que quieres seria volver atras, te recomiendo explotes los beneficios de los gestores de BD actuales.

    Saludos.


    CBR

    • Proposed as answer by Luis Molina M Tuesday, October 09, 2012 11:52 AM
    Tuesday, October 09, 2012 9:50 AM
  • hola nigoman, yo hice un formulario en un proyecto aparte,  en el formulario pongo la info de la base de datos, como servidor, base de datos, usuario y clave, luego genero esa cadena de conexion y la guardo en un archivo ya sea .ini o .dat, al momento de abrir la aplicacion, el programa lee automaticamente el archivo y actualiza de una vez en el app.config, entonces cada vez que quieras abrir la aplicacion el automaticamente lee el archivo .dat o .ini y si quieres cambiar de base de datos, vuelves a abrir el formulario donde generastes la cadena de conexion
    Tuesday, October 09, 2012 3:57 PM
  • Hola, no se si entiendo bien el caso pero ahi va mi punto de vista...

    Si lo que deseas es hacer un sistema con varias empresas para separar cuentas contables, ventas, etc. lo que debes hacer no es separar las bases de datos ya que esto es un gran problema como puedes ver (entramos en el dilema del huevo y la gallina) sin embargo existen alternativas muy buenas (no somos lo primeros en hacer esto), veamos:

    En las bases de datos existen apuntadores y llaves (primarias, foraneas), que sirven para hacer una relacion, asi puedes interelacionar los datos de una venta con su detalle en tablas distintas, pero si vas mas alla puedes agrupar ventas por sucursal que estas a su vez tendran un detalle y si vamos mas alla tendras Empresas con sus respectivas sucursales con sus respectivas ventas con sus detalles, no se si me explico pero lo que debes hacer es agrupar en una misma BD todas tus empresas, con sus sucursales, ventas y detalles y separarlas logicamente y NO fisicamente (es decir NO en otra BD) de esta forma tendras la oportunidad de que el usuario cree las empresas que necesite dentro de una UNICA BD ya que la nueva empresa sera un indice mas al cual apuntaran todos los registros que de esta deriven

    Espero que me haya explicado y creeme que esto es mucho mejor pues aprovechas la funcionalidad, rendimineto y administracion de tu sistema, solo haz un poco de memoria y veras que antes se trabajaba con archivos separados como tablas y que por eso se evoluciono a las BD que son conjuntos de tablas, en resumen hacer lo que quieres seria volver atras, te recomiendo explotes los beneficios de los gestores de BD actuales.

    Saludos.


    CBR

    Gracias por su respuesta,  si eso lo he tenido en cuenta, separarla de forma logica, pero me encuentro con el inconveniente siguiente:

    El programa lo usaran en una gestoria de empresas y los clientes de esta, entonces, los clientes son muchos, cada una tendria una base de datos, ya que usarian el programa para su empresa y en vez de pasar la facturacion de forma fisica, pasarian una copia de la base de datos, si uso una sola bd unitaria, cada vez que un cliente pase su base de datos, elimino la que esta cargada con todos los datos, perdiendo estos. Y teniendo que estar siempre pendiente de no pisar los datos de otros clientes.

    De ahi la idea de poder elegir la base de datos y cargarla con otro nombre, o que se autogenerara el nombre de la misma.

    Tuesday, October 09, 2012 6:24 PM
  • hola nigoman, yo hice un formulario en un proyecto aparte,  en el formulario pongo la info de la base de datos, como servidor, base de datos, usuario y clave, luego genero esa cadena de conexion y la guardo en un archivo ya sea .ini o .dat, al momento de abrir la aplicacion, el programa lee automaticamente el archivo y actualiza de una vez en el app.config, entonces cada vez que quieras abrir la aplicacion el automaticamente lee el archivo .dat o .ini y si quieres cambiar de base de datos, vuelves a abrir el formulario donde generastes la cadena de conexion

    gracias por responder,  habia pensado en algo parecido, pero hacerlo de forma mas automatica ya que lo van a usar personas con escasos conocimientos, entonces simplificarlo de forma que solo fuese en un form elegir la bd que nos interesara y darle a aceptar y el form realizara el resto de forma automatizada.

    Tuesday, October 09, 2012 6:28 PM
  • Hola:
    En la tabla de CLIENTES, añade un campo llamado CADENA_CONEXION Texto de 255 caracteres (orientativo).
    Cada vez que das de alta un CLIENTE, copias el fichero MDB (que contenga tablas, indices etc pero sin datos), y añades 1 registro a esta tabla.
    Al iniciar el programa en un Form le muestras en un DataGridView todos los registros de esta tabla y el usuario tiene que seleccionar uno.
    El valor del campo CADENA_CONEXION se lo asignas a una variable global (por ejemplo msCadenaConexion) al proyecto.
    Luego en el proyecto usas esta variable para conectarte a la base de datos.

    Espero que se entienda
    Un saludo desde Bilbo
    Carlos

    Wednesday, October 10, 2012 7:52 AM
  • Hola:
    En la tabla de CLIENTES, añade un campo llamado CADENA_CONEXION Texto de 255 caracteres (orientativo).
    Cada vez que das de alta un CLIENTE, copias el fichero MDB (que contenga tablas, indices etc pero sin datos), y añades 1 registro a esta tabla.
    Al iniciar el programa en un Form le muestras en un DataGridView todos los registros de esta tabla y el usuario tiene que seleccionar uno.
    El valor del campo CADENA_CONEXION se lo asignas a una variable global (por ejemplo msCadenaConexion) al proyecto.
    Luego en el proyecto usas esta variable para conectarte a la base de datos.

    Espero que se entienda
    Un saludo desde Bilbo
    Carlos

    Hola carlos, gracias por responder me podrias dar un ejemplo de como poder hacerlo?

    un saludo

    Thursday, October 11, 2012 4:16 PM
  • Hola:
    Crea un proyecto nuevo y le añades un modulo como este.

    Option Explicit On
    Option Strict On

    Module Inicio
        Public msCadenaConexion As String
        '
        Private _prevInstanceMutex As System.Threading.Mutex

        Public Sub Main()
            ' Compruebo si existe una instancia
            If lF_PreviaInstancia() = True Then
                MessageBox.Show("La aplicacion ya se esta ejecutando", "Sub Main", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return
            End If
            'Ejecutamos nuestra aplicación
            Application.EnableVisualStyles()
            Using loForm As New FrmSeleccionCliente
                loForm.ShowDialog()
                Resultado = loForm.DialogResult
            End Using
            Dim loPrincipal As New FrmPrincipal
            Application.Run(loPrincipal)
        End Sub

        Private Function lF_PreviaInstancia() As Boolean
            Dim lbNuevo As Boolean
            Dim lsNombre As String
            ' Obtengo el nombre completo del ensamblado para usarlo como nombre del mutex
            lsNombre = Reflection.Assembly.GetEntryAssembly.FullName
            ' Creo el mutex intentando ser su propietario. Si el mutex ya fue creado por otra instancia, no se va a poder tomar propiedad del 'mutex y nuevo sera = false
            _prevInstanceMutex = New System.Threading.Mutex(True, lsNombre, lbNuevo)
            Return Not lbNuevo
        End Function
    End Module

    en Proyecto > Propiedades > Objeto de inicio > Sub Main

    Lo primero que se carga es el FrmSeleccionCliente que tiene 1 DataGridView (dgrDatos) y se le cargan todos los clientes.
    Tienes que tener una tabla como esta (En este caso es de SQL para que se vea mejor la diferencia.
    CLIENTE
    =======
    ID_CLIENTE Tinyint  PK
    NOMBRE  Varchar(50)
    CADENA_CONEXION Varchar(255)
    demas campos

    Codigo de FrmSeleccionCliente

    Option Strict On
    Option Explicit On
    Imports System.Data
    Imports System.Data.OleDb
    Imports System.Data.SqlClient

    Public Class FrmSeleccionCliente
        Private Sub FrmSeleccionCliente_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim lsQuery As String = "Select NOMBRE, CADENA_CONEXION From CLIENTE Order By NOMBRE"
            Me.dgrDatos.DataSource = gF_dtActualizaGrid(lsQuery)
            Me.dgrDatos.Columns("CADENA_CONEXION").Visible = False
        End Sub

        Private Sub dgrDatos_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgrDatos.CellContentClick
            If e.RowIndex = -1 Then
                Return
            End If
            Dim loFila As DataGridViewRow = Me.dgrDatos.CurrentRow()
            msCadenaConexion = loFila.Cells("CADENA_CONEXION").Value.ToString()
            Me.Close()
        End Sub

        Private Function lF_dtActualizaGrid( ByVal vsQuery As String) As DataTable
            If (vsQuery = String.Empty) Then
                Return Nothing
            End If
            Try
                Dim loDataTable As New DataTable
                Using loConexion As New SqlConnection(TU_CADENACONEXION_SQL)
                    Dim loDataAdapter As New SqlDataAdapter(vsQuery, loConexion)
                    loDataAdapter.Fill(loDataTable)
                End Using
                Return loDataTable
            Catch ex As Exception
                MessageBox.Show(ex.Message, "lF_dtActualizaGrid", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return Nothing
            End Try
        End Function
    End Class

    Con este Form se consigue cargar la variable msCadenaConexion.
    Una vez que se ha cerrado este Form, se abrira el Form Principal.
    En los siguientes Form cuando quieras abrir una conexion contra la base de datos de Acces usaras siempre la siguiente instruccion:

    Using loConexion As New OleDbConnection(msCadenaConexion)
        ... tus instrucciones
    End Using

    Espero que se entienda
    Un saludo desde Bilbo
    Carlos

    • Marked as answer by nigoman Sunday, October 21, 2012 10:57 PM
    Monday, October 15, 2012 10:52 AM
  • Hola:

    La linea Resultado = loForm.DialogResult sobra

    La linea Me.dgrDatos.DataSource = gF_dtActualizaGrid(lsQuery) sustituyela por Me.dgrDatos.DataSource = lF_dtActualizaGrid(lsQuery)

    Un saludo desde Bilbo
    Carlos

    Monday, October 15, 2012 10:55 AM
  • Gracias por el codigo, voy a probarlo y te digo.

    Sunday, October 21, 2012 10:58 PM