Leer secuencialmente dos tablas de un archivo creado en vb.net 2010

Iniciado por arturoro, 2 Diciembre 2015, 07:28 AM

0 Miembros y 1 Visitante están viendo este tema.

arturoro

Hola a todos y buenas tardes o noches: :laugh:

Deseo que me puedan orientar acerca de como puedo hacerle para que me lea en una tabla llamada tabla1 que esta en un archivo creado en access 2010 llamado Database1.accdb, el primer registro del campo llamado L1, que tome el valor y luego se vaya a la otra tabla llamada tabla2 para que tome el valor del primer registro del campo llamado L2, despues comparo esos dos valores si son iguales, que mande msg de registro encontrado, en caso contrario, que siga leyendo el siguiente registro de la tabla2, y que siga comparando, si llega al final del archivo de la tabla2, que se regrese a la tabla1 y se vaya al segundo registro y otra vez repite el proceso asi sucesivamente hasta el fin de la tabla1 (ya que el maestro es la tabla1 y el segundo la tabla2), y si no hay igualdad, que mande mensaje de que no hubo igualdad.

Perdonen mi ignorancia, ya que habia hecho por lo menos el acceso en visual basic 6, y el maestro nos la cambio a visual basic .net 2010 >:D  y la verdad, me manda muchos errores, estuve viendo que ya no es igual de vb6 a vb.net 2010.

Espero me puedan ayudar.

SALUDOS!!!  ;-)

Lekim

Hola

Antes de nada comentarte que no dispongo de Office 2010 ni archivos *.accdb. Pero he realizado este programa para leer archivos *.mdb y  supongo que el programa será capaz de leer los primeros. Ya me dirás.

Se trata de una función llamada LeerDatosTabla. Esta función devuelve un valor de un lugar concreto de una tabla de una base de datos. Se llama de la siguiente manera:


LeerDatosTabla("E:\Database1.accdb", NOMBRE DE TABLA, FILA, COLUMNA, NúmeroDeFilas, NúmeroDeColumnas)

Donde NúmeroDeFilas y  NúmeroDeColumnas devuelven el número de filas y columnas de la tabla. Es necesario que declares estas variables como 'integer' antes de llamar a la función como se muestra en el siguiente ejemplo. Claro que si no lo quieres puedes modificar el código.Tu mismo.


EJEMPLO:
Código (vbnet) [Seleccionar]



Public Class Form1
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   End Sub

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim NúmeroDeFilas As Integer = Nothing          '//Variable para introducir el número de filas de la tabla
       Dim NúmeroDeColumnas As Integer = Nothing       '//Variable para introducir el número de columnas de la tabla
       Try
           Dim Valor1 As String = LeerDatosTabla("C:\Carpeta\Database1.accdb", "L1", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor1
           Dim Valor2 As String = LeerDatosTabla("C:\Carpeta\Database1.accdb", "L2", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor2

           If Valor1.Length > 0 And Valor2.Length > 0 Then '//Comprueba que Valor1 y Valor2 contienen alguna cadena
               If Valor1.Equals(Valor2) Then 'compara
                   MessageBox.Show("Hay coincidencia", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information)
               End If
           End If

           'Label1.text = NúmeroDeFilas  
           'Label2.text = NúmeroDeFilas
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
   End Sub

End Class
#Region "Lectura de base de datos"
Module modGetDateTable
   ''' <summary>
   ''' OBTIENE DATOS DE UNA BASE DE DATOS ACCESS
   ''' </summary>
   ''' <param name="PathFileMDB"></param>
   ''' <param name="NombreTabla"></param>
   ''' <param name="nFila"></param>
   ''' <param name="nColumna"></param>
   ''' <param name="file_Count"></param>
   ''' <param name="Column_count"></param>
   ''' <returns></returns>
   ''' <remarks></remarks>
   Public Function LeerDatosTabla(ByVal PathFileMDB As String, _
                                  ByVal NombreTabla As String, _
                                  ByVal nFila As Integer, _
                                  ByVal nColumna As Integer, _
                                  ByRef file_Count As Integer, _
                                  ByRef Column_count As Integer) As String
       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";"
       Dim DataSet_ As New DataSet       '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)       '//Conexión con la base de datos
       Dim Resultado As String = Nothing
       Try
           Connection.Open()                                                                           '//Abre la clase de datos
           Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                             '//Instrucción SQL
           Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
           DataAdapter.Fill(DataSet_, NombreTabla)                                                     '//Adapta la tabla (fila, columnas) al DataSet
           Connection.Close()                                                                          '//Cierra conexión

           Dim Tabla As DataTable = DataSet_.Tables(NombreTabla)                                       'Crea una tabla e introduce los datos del DataSet
           Dim NumRows As Integer = Tabla.Rows.Count                                                   '//Obtiene el número de filas de la tabla

           file_Count = NumRows                                                                        '//Devuelve Número de filas de la tabla
           Column_count = Tabla.Columns.Count
           Resultado = Tabla.Rows(nFila).Item(nColumna)
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
       Return Resultado
   End Function
End Module
#End Region




[EJEMPLO SIMPLE]
A veces con las funciones metidas en un módulo y  con el Byval y el ByRef pueden ser confusas. Aquí te dejo un ejemplo sencillo de lectura dentro de un botón, para que lo veas más claro:

- Necesitas meter un ListBox y un Button

Código (vbnet) [Seleccionar]

   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

       Dim PathMDB As String = "C:\Carpeta\Database1.accdb"                                            '//Nombre de la tabla
       Dim NombreTabla As String = "Direcciones"                                       '//La tabla se llama "Direcciones"

       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathMDB & ";"
       Dim DataSet_ As New DataSet                                                    '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)        '//Conexión con la base de datos
       Connection.Open()                                                              '//Abre la clase de datos
       Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                                 '//Instrucción SQL
       Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
       DataAdapter.Fill(DataSet_, NombreTabla)                                        '//Adapta la tabla (fila, columnas) al DataSet
       Connection.Close()                                                             '//Cierra conexión

       Dim Tabla As DataTable = DataSet_.Tables(NombreTabla)                           '//Crea una tabla e introduce los datos del DataSet
       Dim NumRows As Integer = Tabla.Rows.Count                                       '//Obtiene el número de filas de la tabla
       For Each Filas As DataRow In Tabla.Rows
           Dim Columna As Integer = 0                                                  '//La primera columna de la tabla
           ListBox1.Items.Add(Filas.Item(Columna))                                     '//Devuelve las filas de la primera columna
       Next

       '//Forma selectiva
       'Label1.Text = Tabla.Rows(FILA).Item(COLUMNA)
   End Sub


Lo que hace este código es meter todos los elementos de la primera fila de una tabla en un ListBox

[LECTURA DE ARCHIVOS XLS O XLSX]
Si quieres leer archivos XLS (Excel) solo tienes que reemplazar:
Código (vbnet) [Seleccionar]
Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";"

por esta otra línea:

Código (vbnet) [Seleccionar]
Dim MDBConnString_ As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileMDB & ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=0'"

Y como nombre de tabla:

Código (vbnet) [Seleccionar]
[Hoja1$]

Ejemplo:
Código (vbnet) [Seleccionar]
   Dim NúmeroDeFilas As Integer = Nothing          '//Variable para introducir el número de filas de la tabla
        Dim NúmeroDeColumnas As Integer = Nothing       '//Variable para introducir el número de columnas de la tabla
        Dim Valor1 As String = LeerDatosTabla("C:\Carpeta\Libro1.xls", "[Hoja1$]", 1, 0, NúmeroDeFilas, NúmeroDeColumnas) '//Devuelve el valor1
        Me.Text = Valor1


Sldos

arturoro

Muchas Gracias Lekim, en verdad me ayudaste mucho en vb.net 2010  ;-) :

Te comento que solo le hice pequeñas modificaciones, pero, hize pruebas y funciona muy bien, te paso completo el programa, esta en vb.net 2010 y lo posteo para que lo veas y si a alguien le pudiese servir.

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Mydir, Myrep As String
        Dim Reg As Integer = 0
        Mydir = CurDir() + "\" + "Datos.accdb"
        Myrep = CurDir() + "\"
        Dim NombreTabla1 As String = "L1"                                       '//La tabla se llama "L1"
        Dim NombreTabla2 As String = "L2"

        Dim query As String = "SELECT * FROM " & NombreTabla1
        Dim query2 As String = "SELECT * FROM " & NombreTabla2

        Dim MDBConnString_ As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=" & Mydir & ";"  En esta parte solo la modifique para que la reconociera access 2010, ya que me daba error de acceso con lo que me pusiste
        Dim DataSet_ As New DataSet                                             '//Caché de memoria interno de datos
        Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)        '//Conexión con la base de datos
        Connection.Open()                                                     '//Abre la clase de datos

        Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)      '//Instrucción SQL
        Dim cmd2 As New System.Data.OleDb.OleDbCommand(query2, Connection)

        Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
        Dim DataAdapter2 As New System.Data.OleDb.OleDbDataAdapter(cmd2)

        DataAdapter.Fill(DataSet_, NombreTabla1)                               '//Adapta la tabla (fila, columnas) al DataSet
        DataAdapter2.Fill(DataSet_, NombreTabla2)

        Connection.Close()                                                    '//Cierra conexión

        Dim Tabla2 As DataTable = DataSet_.Tables(NombreTabla2)
        Dim Tabla As DataTable = DataSet_.Tables(NombreTabla1)                 '//Crea una tabla e introduce los datos del DataSet

        Dim NumRows As Integer = Tabla.Rows.Count                             '//Obtiene el número de filas de la tabla
        Dim NumRows2 As Integer = Tabla2.Rows.Count

        Dim l1, l2 As String

        MsgBox(CStr(NumRows))
        MsgBox(CStr(NumRows2))

        For Each Filas1 As DataRow In Tabla.Rows
            Dim Columna1 As Integer = 0                                        '//La primera columna de la tabla
            l1 = Filas1.Item(Columna1)                                     'ListBox1.Items.Add(Filas.Item(Columna1))        '//Devuelve las filas de la primera columna
            For Each Filas2 As DataRow In Tabla2.Rows
                Dim Columna2 As Integer = 0                                        '//La primera columna de la tabla
                l2 = Filas2.Item(Columna2)
                If l1 = "Pedro" And l2 = "Marciano" Then
                    MsgBox("SE LOGRO REGISTRO. FIN")
                    End
                End If
            Next
        Next
        MsgBox("NO SE ENCONTRO CONCORDANCIA. ADIOS")
        End
    End Sub
End Class

Como te diste cuenta, solo agrege otro for next pero para la tabla 2

MUCHAS GRACIAS Y SI ESTAS DE ACUERDO LEKIM, SE DA POR CERRADO  ;-)  ;-)



Lekim

Hola

Gracias por comentar la actualización que has hecho para que fuera compatible con Acces 2010  ;-)

Creo que se puede simplificar el código obteniendo la tabla mediante una función y luego con la tabla haces lo que te de la gana.

He modificado la función que puse en el comentario anterior. Aquí no se obtiene sólo un elemento de una tabla sino toda la tabla entera para luego en otro evento hacer lo que se quiera con ella:

[FUNCIÓN PARA OBTENER TABLA ACCES]
Código (vbnet) [Seleccionar]
#Region "Lectura de base de dato ACCES ver. 12.0"
Module modGetDateTable

   Public Function LeerDatosTabla(ByVal PathFileMDB As String, ByVal NombreTabla As String) As DataTable
       Dim query As String = "SELECT * FROM " & NombreTabla
       Dim MDBConnString_ As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=" & PathFileMDB & ";"
       Dim DataSet_ As New DataSet       '//Caché de memoria interno de datos
       Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)       '//Conexión con la base de datos
       Dim Resultado As String = Nothing
       Dim Tabla As DataTable = Nothing
       Try
           Connection.Open()                                                                           '//Abre la clase de datos
           Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)                             '//Instrucción SQL
           Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
           DataAdapter.Fill(DataSet_, NombreTabla)                                                     '//Adapta la tabla (fila, columnas) al DataSet
           Connection.Close()                                                                          '//Cierra conexión
           Tabla = DataSet_.Tables(NombreTabla)                                       'Crea una tabla e introduce los datos del DataSet

       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
       Return Tabla
   End Function
End Module
#End Region


Ejemplo se uso:
Código (vbnet) [Seleccionar]

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim PhatFileMDB As String = System.Windows.Forms.Application.StartupPath & "\Datos.accdb"
       Dim dtTable As DataTable = LeerDatosTabla(PhatFileMDB, "L1")
       Try
           For Each dtrow As DataRow In dtTable.Rows
               ListBox1.Items.Add(dtrow.Item(0))
           Next
       Catch ex As Exception
           MessageBox.Show(ex.Message)
       End Try
   End Sub


Por otro lado yo no quitaría Try/Catch

Código (vbnet) [Seleccionar]
  Try '//Intenta ejecutar el siguiente código
           '1...Código
           '2...Código
           '3....
       Catch ex As Exception   '//si se produce una excepción
           '//Muestra un mensaje por ejemplo, Cierra la aplicación o puedes no poner nada
       End Try '//Fin de intento




[MODIFICACIÓN DE TU CÓDIGO]
En un principio dijiste:
después comparo esos dos valores si son iguales

Entiendo que lo que quieres es comparar las filas de unas tablas y comprobar que las dos NO tienen coincidencias ¿no?

He realizado otra forma  ya que, pueden haber coincidencias pero no estar en el mismo lugar es decir: {A, B, C} y {N, M, A} tienen en común A

Código (vbnet) [Seleccionar]
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim Mydir As String = System.Windows.Forms.Application.StartupPath & "\" & "\Datos.accdb"

       Try  '//Intenta ejectuar el código
           '//Importa las tablas
           Dim Tabla1 As DataTable = LeerDatosTabla(Mydir, "L1")
           Dim Tabla2 As DataTable = LeerDatosTabla(Mydir, "L2")
           Dim Columna As Integer = 0 '//columna que va a comparar

           '//compara las tablas (independientemente de su orden) ej: A= {X,Y,Z}  B= {Y,N,S} HayCoincidencias devuelve  TRUE EN 'Y'
           Dim ListItems1 As New List(Of String), ListItems2 As New List(Of String)
           '//Introduce los elementos de la columna 0 en las listas ListItems1 y ListItems2
           For Each dtRow As DataRow In Tabla1.Rows
               ListItems1.Add(dtRow(Columna))
           Next
           For Each dtRow As DataRow In Tabla2.Rows
               ListItems2.Add(dtRow(Columna))
           Next

           '//Comprueba  las coincidencias
           Dim HayCoincidencia As Boolean = False
           Dim Coincidencias As String = Nothing
           If ListItems1.Count = ListItems2.Count Then
               Dim Int As Integer = -1
               For Each Elemento As String In ListItems2
                   Int += 1
                   If ListItems1.Contains(Elemento) = True Then
                       HayCoincidencia = True
                       If Coincidencias = "" Then
                           Coincidencias &= String.Format("- {0}", Elemento)
                       Else
                           Coincidencias &= String.Format("{0}- {1}", Environment.NewLine, Elemento)
                       End If
                   End If
               Next
           Else
               MessageBox.Show("Las listas no tiene el mismo número de elementos.", "Atención", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
           End If
           '//Lanza mensaje
           If HayCoincidencia Then
               MessageBox.Show(String.Format("Hay coincidencias: {0}{1}", Environment.NewLine, Coincidencias), _
                               "Atención", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
           Else
               MessageBox.Show("No hay coincidencias.", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information)
           End If

           Me.Close()
       Catch ex As Exception  '//Si se produce una excepción"
           Me.Close() 'cierra
       End Try '//Fin de intento

   End Sub


Como ves llamando a la función LeerDatosTabla se obtiene el DataTable  y luego desde el evento de un botón por ejemplo puedes obtener la tabla y luego hacer lo que quieras, si no, es un lío tremendo. Así es más cómodo.

En un principio y para ahorrar código usé Lista1.Except(Lista2) para obtener una lista de elementos en los que no son iguales. Pero lo que interesaba es obtener los elementos que SI son iguales. En su lugar he usado Lista1.Contains(A) que devuelve TRUE si existe el elemento A en  la lista.

Estoy seguro que debe de haber alguna función o funciones NET para comparar listas que ahorre código pero como no la conozco lo he hecho a la cuenta de la vieja XD.




Otra cosa para la próxima puedes usar la lista de GeSHi que puedes ver en este foro cuando editas un comentario para pegar código y sea más legible.

[code=vbnet]...CÓDIGO...[/code]

Y por último decirte que este foro es para VB5 o VB6 y no para NET. Ya hay uno para net  ;)

http://foro.elhacker.net/net-b62.0/

Sl2s





arturoro

Hola nuevamente Lekim   :laugh: :

Excelente codigo que volviste a poner, excelente  ;-) , en relacion a las comparaciones fue el profe que nos hizo que si en la tabla1 y en la tabla2 habia registros duplicados, y nos puso de ejemplo "pedro" en tabla1 y "pedro" en tabla2 (creo que fumo de la mala hierba jejeje  :silbar: ).

Y gracias por decirme que hay un subforo para .net, ya lo guarde y gracias por decirme como poner el codigo entendible, lo vuelvo a poner para que se entienda jejeje!!!.

Código (vbnet) [Seleccionar]


Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Mydir, Myrep As String
        Dim Reg As Integer = 0
        Mydir = CurDir() + "\" + "Datos.accdb"
        Myrep = CurDir() + "\"
        Dim NombreTabla1 As String = "L1"                                       '//La tabla se llama "L1"
        Dim NombreTabla2 As String = "L2"

        Dim query As String = "SELECT * FROM " & NombreTabla1
        Dim query2 As String = "SELECT * FROM " & NombreTabla2

        Dim MDBConnString_ As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=" & Mydir & ";"  'En esta parte solo la modifique para que la reconociera
                                   'access 2010, ya que me daba error de acceso con lo que me
                                   ' pusiste
        Dim DataSet_ As New DataSet                                             '//Caché de memoria interno de datos
        Dim Connection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection(MDBConnString_)        '//Conexión con la base de datos
        Connection.Open()                                                     '//Abre la clase de datos

        Dim cmd As New System.Data.OleDb.OleDbCommand(query, Connection)      '//Instrucción SQL
        Dim cmd2 As New System.Data.OleDb.OleDbCommand(query2, Connection)

        Dim DataAdapter As New System.Data.OleDb.OleDbDataAdapter(cmd)
        Dim DataAdapter2 As New System.Data.OleDb.OleDbDataAdapter(cmd2)

        DataAdapter.Fill(DataSet_, NombreTabla1)                               '//Adapta la tabla (fila, columnas) al DataSet
        DataAdapter2.Fill(DataSet_, NombreTabla2)

        Connection.Close()                                                    '//Cierra conexión

        Dim Tabla2 As DataTable = DataSet_.Tables(NombreTabla2)
        Dim Tabla As DataTable = DataSet_.Tables(NombreTabla1)                 '//Crea una tabla e introduce los datos del DataSet

        Dim NumRows As Integer = Tabla.Rows.Count                             '//Obtiene el número de filas de la tabla
        Dim NumRows2 As Integer = Tabla2.Rows.Count

        Dim l1, l2 As String

        MsgBox(CStr(NumRows))
        MsgBox(CStr(NumRows2))

        For Each Filas1 As DataRow In Tabla.Rows
            Dim Columna1 As Integer = 0                                        '//La primera columna de la tabla
            l1 = Filas1.Item(Columna1)                                     'ListBox1.Items.Add(Filas.Item(Columna1))        '//Devuelve las filas de la primera columna
            For Each Filas2 As DataRow In Tabla2.Rows
                Dim Columna2 As Integer = 0                                        '//La primera columna de la tabla
                l2 = Filas2.Item(Columna2)
                If l1 = "Pedro" And l2 = "Marciano" Then
                    MsgBox("SE LOGRO REGISTRO. FIN")
                    End
                End If
            Next
        Next
        MsgBox("NO SE ENCONTRO CONCORDANCIA. ADIOS")
        End
    End Sub
End Class


Eleкtro

#5
Las preguntas sobre Vb.Net, publicarlas en la sección de .Net, y los demás, por favor reportar los mensajes siempre que podais... a ver si estamos a lo que estamos :P

Saludos!