none
Importación de datos de Excel a Access 2007 RRS feed

  • Pregunta

  • Hola a todos:

    Precisaría que al hacer una importación de datos desde cualquier versión de Excel a un datagridview en vb.net, la primera columna que lleva números y números con una letra, la pudiera transformar en formato de texto a través de código. Es decir, el usuario tiene su primera columna de la hoja de Excel como:

    100

    110

    112M

    Cuando la importo, los valores que llevan número y letra "112M" no me las importa ya que trata la columna como numérica y el problema lo tengo ahí con esos valores, por lo que si puede ser necesitaría poner código para que desde vb.net transforme esa primera columna en texto para que me pueda coger todos los valores. He de comentar que aunque el valor sea "100" en mi tabla de Access ese valor o mejor dicho ese campo, tiene formato de texto.

    La importación la hago de la siguiente manera:

     Private Sub Importar(ByVal rut As String, ByVal ruc As String)
            Dim noi As New System.Text.StringBuilder
            Using acc As New OleDbConnection(Me.CadenaConexion)
                acc.Open()
                Using cnx As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""")
                    cnx.Open()
                    Dim hoj As String = Me.NombrePrimeraHoja(cnx)
                    Using cmd As New OleDbCommand("SELECT * FROM [" & hoj & "]", cnx)
                        Using rst As OleDbDataReader = cmd.ExecuteReader(CommandBehavior.SingleResult)
                            If rst.HasRows Then
                                Dim fil As Integer = 1I
                                Dim tot As Integer = 0I
                                Dim ccc As String = String.Empty
    
                                Me.Cursor = Cursors.WaitCursor
    
                                VarGlobal.bolActivadoCuadroContable = True
                                Dim frmPreparandoInforme = New frmPreparandoInforme
                                frmPreparandoInforme.Show()
    
                                Application.DoEvents()
    
                                While rst.Read
                                    fil += 1I
                                    If rst.IsDBNull(0I) Then
                                        noi.AppendFormat("NULL (fila {0:N0}){1}", fil, Environment.NewLine)
                                    ElseIf rst.FieldCount.Equals(13I) Then '------ Estamos importando 12 ejercicios
                                        If rst.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                            ccc = rst.GetDouble(0I).ToString("R")
                                        ElseIf rst.GetFieldType(0I).Equals(GetType(System.String)) Then
                                            ccc = rst.GetString(0I)
                                        End If
                                        Using bal As New OleDbCommand("UPDATE Balances SET Ejer_01 = @ej1, Ejer_02 = @ej2, Ejer_03 = @ej3, Ejer_04 = @ej4, Ejer_05 = @ej5, Ejer_06 = @ej6, Ejer_07 = @ej7, Ejer_08 = @ej8, Ejer_09 = @ej9, Ejer_10 = @e10, Ejer_11 = @e11, Ejer_12 = @e12 WHERE IdEmpresa = '" & VarGlobal.StrCodEmpresa & "' AND Cód_GC = '" & ccc & "'", acc)
                                            With bal.Parameters
                                                .Add("@ej1", OleDbType.Double).Value = rst.GetDouble(1I)
                                                .Add("@ej2", OleDbType.Double).Value = rst.GetDouble(2I)
                                                .Add("@ej3", OleDbType.Double).Value = rst.GetDouble(3I)
                                                .Add("@ej4", OleDbType.Double).Value = rst.GetDouble(4I)
                                                .Add("@ej5", OleDbType.Double).Value = rst.GetDouble(5I)
                                                .Add("@ej6", OleDbType.Double).Value = rst.GetDouble(6I)
                                                .Add("@ej7", OleDbType.Double).Value = rst.GetDouble(7I)
                                                .Add("@ej8", OleDbType.Double).Value = rst.GetDouble(8I)
                                                .Add("@ej9", OleDbType.Double).Value = rst.GetDouble(9I)
                                                .Add("@e10", OleDbType.Double).Value = rst.GetDouble(10I)
                                                .Add("@e11", OleDbType.Double).Value = rst.GetDouble(11I)
                                                .Add("@e12", OleDbType.Double).Value = rst.GetDouble(12I)
                                            End With
                                            If bal.ExecuteNonQuery.Equals(0I) Then noi.AppendFormat("{0} (fila {1:N0}){2}", ccc, fil, Environment.NewLine)
                                        End Using
                                        tot += 1I
                                    ElseIf rst.FieldCount.Equals(6I) Then '------ Estamos importando 5 ejercicios
                                        If rst.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                            ccc = rst.GetDouble(0I).ToString("R")
                                        ElseIf rst.GetFieldType(0I).Equals(GetType(System.String)) Then
                                            ccc = rst.GetString(0I)
                                        End If
                                        Using bal As New OleDbCommand("UPDATE Balances SET Ejer_01 = @ej1, Ejer_02 = @ej2, Ejer_03 = @ej3, Ejer_04 = @ej4, Ejer_05 = @ej5 WHERE IdEmpresa = '" & VarGlobal.StrCodEmpresa & "' AND Cód_GC = '" & ccc & "'", acc)
                                            With bal.Parameters
                                                .Add("@ej1", OleDbType.Double).Value = rst.GetDouble(1I)
                                                .Add("@ej2", OleDbType.Double).Value = rst.GetDouble(2I)
                                                .Add("@ej3", OleDbType.Double).Value = rst.GetDouble(3I)
                                                .Add("@ej4", OleDbType.Double).Value = rst.GetDouble(4I)
                                                .Add("@ej5", OleDbType.Double).Value = rst.GetDouble(5I)
                                            End With
                                            If bal.ExecuteNonQuery.Equals(0I) Then noi.AppendFormat("{0} (fila {1:N0}){2}", ccc, fil, Environment.NewLine)
                                        End Using
                                        tot += 1I
                                    ElseIf rst.FieldCount.Equals(3I) Then '------ Estamos importando 2 ejercicios
                                        If rst.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                            ccc = rst.GetDouble(0I).ToString("R")
                                        ElseIf rst.GetFieldType(0I).Equals(GetType(System.String)) Then
                                            ccc = rst.GetString(0I)
                                        End If
                                        Using bal As New OleDbCommand("UPDATE Balances SET Ejer_01 = @ej1, Ejer_02 = @ej2 WHERE IdEmpresa = '" & VarGlobal.StrCodEmpresa & "' AND Cód_GC = '" & ccc & "'", acc)
                                            With bal.Parameters
                                                .Add("@ej1", OleDbType.Double).Value = rst.GetDouble(1I)
                                                .Add("@ej2", OleDbType.Double).Value = rst.GetDouble(2I)
                                            End With
                                            If bal.ExecuteNonQuery.Equals(0I) Then noi.AppendFormat("{0} (fila {1:N0}){2}", ccc, fil, Environment.NewLine)
                                        End Using
                                        tot += 1I
                                    ElseIf rst.FieldCount.Equals(2I) Then '------ Estamos importando 1 ejercicio
                                        If rst.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                            ccc = rst.GetDouble(0I).ToString("R")
                                        ElseIf rst.GetFieldType(0I).Equals(GetType(System.String)) Then
                                            ccc = rst.GetString(0I)
                                        End If
                                        Using bal As New OleDbCommand("UPDATE Balances SET " & rst.GetName(1I) & " = @ej1 WHERE IdEmpresa = '" & VarGlobal.StrCodEmpresa & "' AND Cód_GC = '" & ccc & "'", acc)
                                            bal.Parameters.Add("@ej1", OleDbType.Double).Value = rst.GetDouble(1I)
                                            If bal.ExecuteNonQuery.Equals(0I) Then noi.AppendFormat("{0} (fila {1:N0}){2}", ccc, fil, Environment.NewLine)
                                        End Using
                                        tot += 1I
                                    End If
                                End While
    
                                Me.CargaDatagridView1()
    
                                frmPreparandoInforme.Close()
                                VarGlobal.bolActivadoCuadroContable = False
    
                                'Dim Cód_GC As String
    
                                If noi.Length.Equals(0I) Then
                                    System.Windows.Forms.MessageBox.Show("Importación finalizada" & Environment.NewLine & "Se han importado " & tot.ToString("N0") & " filas del archivo «" & ruc & "»", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
                                Else
                                    'Dim msg As String = String.Format("Importación finalizada.{0}Se han importado {1} filas del archivo «{2}» con el código contable {3}", Environment.NewLine, tot.ToString("N0"), ruc, & 'Cód_GC')
                                    'MessageBox.Show(msg, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
                                    System.Windows.Forms.MessageBox.Show("Importación finalizada" & Environment.NewLine & "Se han importado " & tot.ToString("N0") & " filas del archivo «" & ruc & "». Las siguientes cuentas no han sido importadas:" & Environment.NewLine & Environment.NewLine & noi.ToString, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
                                End If
                            Else
                                System.Windows.Forms.MessageBox.Show("La hoja de cálculo «" & hoj & "» no contiene datos para importar", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                            End If
                            rst.Close()
    
                            Me.Cursor = Cursors.Default
    
                        End Using
                    End Using
                    cnx.Close()
                End Using
                acc.Close()
            End Using
    
            Me.CuadreBalances()
        End Sub

    Tampoco se si de esta forma puedo importar desde cualquier versión de Excel, ya que con un Excel 2016 me está saliendo un mensaje de error: "Error de conversión", pero le doy a Aceptar al mensaje y al final me importa las cuentas y sus valores.

    Un saludo a todos y gracias.

    Gemma

    martes, 8 de diciembre de 2015 8:23

Respuestas

  • "gemma_campillo" escribió:

    > Es decir, el usuario tiene su primera columna de la hoja de Excel como:
    >
    > 100
    >
    > 110
    >
    > 112M

    ¡Vamos a ver que no me entero! ¿El usuario es el que genera el archivo de Excel? Si es así, va a ser complicado que te indiquemos lo que tienes que hacer, porque puede suceder que ciertos usuarios construyan bien la hoja de cálculo de Excel que deseas importar y otros no lo hagan tan bien.

    ¿O la hoja de Excel se genera desde tu programa? ¿Por casualidad tu programa exporta a Excel datos en formato *.csv? Si es así, deberías de saber que el clásico archivo con extensión *.csv es un simple archivo de texto sin formato separado por comas, que normalmente se puede abrir con Microsoft Excel, pero en NINGÚN CASO se trata de un archivo con formato Microsoft Excel (*.xlsx, *.xls, etc.). Te pregunto esto porque desde tu programa he realizado una exportación de datos a Excel y me he encontrado con un archivo con extensión *.csv y su contenido es texto plano con campos separados por punto y coma (que para una configuración regional de español de España es como si fuera un archivo separado por comas) que se puede leer perfectamente con el Bloc de Notas de Windows.

    ¿Dónde puedo ver el código fuente que utilizas para exportar los datos a un archivo separado por comas (*.csv) o de Excel (*.xlsx)? ¿Este archivo *.csv o *.xlsx es el que posteriormente deseas importar sus datos a tu aplicación?

    > "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";
    >      Extended Properties=""Excel 12.0;HDR=YES;IMEX=1"""

    Si hablamos que deseas importar un archivo binario de Excel 2007 o superior con extensión *.xlsb, me parece estupendo que utilices el ISAM 'Excel 12.0'. Pero si hablamos de un archivo de Excel 2007 o superior con extensión *.xlsx, entonces deberás de utilizar el siguiente formato de ISAM:

      "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";
      "Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1'"

    Es decir, tienes que añadir Xml al formato del ISAM de Excel.

    En fin, respóndeme a las preguntas y posteriormente veré lo que se puede hacer, aunque por lo que ahora estoy observando, la cosa tiene mala pinta. :-(


    Enrique Martínez Montejo
            [MS MVP - VB]

    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.

    • Marcado como respuesta gemma_campillo martes, 8 de diciembre de 2015 15:18
    martes, 8 de diciembre de 2015 10:48
    Moderador
  • "gemma_campillo" escribió:

    > el usuario es el que genera la hoja de Excel, ... Por otro lado, exporto en
    > fichero "csv" y el usuario después lo "guarda como", "xls o xlsx".

    Pues ahí es donde está el problema, ya que los usuarios generarán el archivo de Excel como les venga en gana, y no saben que la primera columna (aquella que tiene datos numéricos y alfanuméricos entremezclados), TIENEN QUE DECLARARLA EN EL ARCHIVO DE EXCEL CON EL FORMATO TEXTO. Si se limitan a abrir con Excel el archivo *.csv, modificar los datos y guardar la hoja con formato de Excel (*.xlsx o *.xls), la primera columna tendrá por defecto el formato GENERAL, con lo que tendrás problemas a la hora de importar los datos a Access, SQL Server, a un objeto DataTable o donde quieras llevártelos, por mucho que especifiques el valor IMEX=1 en las propiedades extendidas de la cadena de conexión, ya que las filas que contienen valores alfanuméricos son las menos, siendo más numerosas aquellas que tienen valores numéricos exclusivos, de ahí que el ISAM de Excel tome la columna como numérica, ya que te comento que "milagros" tampoco hace el ISAM de Excel. ;-)

    Pues como te dije al final de mi anterior mensaje, por ahora no le veo yo una solución al problema, salvo que la primera columna de la hoja de cálculo del archivo de Excel tenga establecido el formato Texto. Si deseas hacer una prueba, abre el libro de Excel que deseas importar, selecciona la primera columna, y abre el cuadro de diálogo Formato de celdas. Selecciona la pestaña Número y dentro del control ListBox llamado Categoría, selecciona Texto. Guarda los cambios y cierra el libro de Excel.

    Si rellenas un objeto DataTable mediante el valor devuelto por la siguiente función:

        ''' <summary>
        ''' Devuelve un objeto DataTable con los datos existentes
        ''' en la hoja de cálculo de Excel especificada.
        ''' </summary>
        ''' <param name="fileName">Ruta del archivo de Excel.</param>
        ''' <param name="nombreHoja">Nombre de la hoja de cálculo.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend Shared Function GetDataExcel(fileName As String, nombreHoja As String) As DataTable
    
            If ((String.IsNullOrEmpty(fileName)) OrElse (fileName.Trim() = String.Empty)) Then
                Throw New ArgumentNullException("fileName", "No se ha especificado el archivo de Excel.")
            End If
    
            If ((String.IsNullOrEmpty(nombreHoja)) OrElse (nombreHoja.Trim() = String.Empty)) Then
                Throw New ArgumentException("nombreHoja", "No se ha especificado el nombre de la hoja de cálculo.")
            End If
    
            Dim cadenaConexion As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;" &
                                                         "Extended Properties='Excel 12.0 Xml;IMEX=1;HDR=Yes;';" &
                                                         "Data Source={0}", fileName)
            ' Creamos un nuevo objeto DataTable.
            Dim dt As New DataTable(nombreHoja)
    
            Using cnn As New OleDbConnection(cadenaConexion)
    
                Dim cmd As OleDbCommand = cnn.CreateCommand()
                cmd.CommandText = String.Format("SELECT * FROM [{0}$]", nombreHoja)
    
                Dim da As New OleDbDataAdapter(cmd)
    
                ' Rellenamos el objeto DataTable.
                '
                da.Fill(dt)
            End Using
    
            ' Devolvemos el objeto DataTable.
            '
            Return dt
    
        End Function

    podrás observar que ahora sí aparecen en la primera columna los valores alfanuméricos 100, 110, 112M, etc., si enlazas el objeto DataTable obtenido con un control DataGridView.

    A la función simplemente le tienes que especificar la ruta completa del archivo de Excel al que deseas conectarte y el nombre de la hoja de cálculo que contiene los datos (Hoja1, Hoja2, NombreHoja, o como se llame).

                               


    Enrique Martínez Montejo
            [MS MVP - VB]

    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.


    martes, 8 de diciembre de 2015 16:22
    Moderador

Todas las respuestas

  • "gemma_campillo" escribió:

    > Es decir, el usuario tiene su primera columna de la hoja de Excel como:
    >
    > 100
    >
    > 110
    >
    > 112M

    ¡Vamos a ver que no me entero! ¿El usuario es el que genera el archivo de Excel? Si es así, va a ser complicado que te indiquemos lo que tienes que hacer, porque puede suceder que ciertos usuarios construyan bien la hoja de cálculo de Excel que deseas importar y otros no lo hagan tan bien.

    ¿O la hoja de Excel se genera desde tu programa? ¿Por casualidad tu programa exporta a Excel datos en formato *.csv? Si es así, deberías de saber que el clásico archivo con extensión *.csv es un simple archivo de texto sin formato separado por comas, que normalmente se puede abrir con Microsoft Excel, pero en NINGÚN CASO se trata de un archivo con formato Microsoft Excel (*.xlsx, *.xls, etc.). Te pregunto esto porque desde tu programa he realizado una exportación de datos a Excel y me he encontrado con un archivo con extensión *.csv y su contenido es texto plano con campos separados por punto y coma (que para una configuración regional de español de España es como si fuera un archivo separado por comas) que se puede leer perfectamente con el Bloc de Notas de Windows.

    ¿Dónde puedo ver el código fuente que utilizas para exportar los datos a un archivo separado por comas (*.csv) o de Excel (*.xlsx)? ¿Este archivo *.csv o *.xlsx es el que posteriormente deseas importar sus datos a tu aplicación?

    > "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";
    >      Extended Properties=""Excel 12.0;HDR=YES;IMEX=1"""

    Si hablamos que deseas importar un archivo binario de Excel 2007 o superior con extensión *.xlsb, me parece estupendo que utilices el ISAM 'Excel 12.0'. Pero si hablamos de un archivo de Excel 2007 o superior con extensión *.xlsx, entonces deberás de utilizar el siguiente formato de ISAM:

      "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";
      "Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1'"

    Es decir, tienes que añadir Xml al formato del ISAM de Excel.

    En fin, respóndeme a las preguntas y posteriormente veré lo que se puede hacer, aunque por lo que ahora estoy observando, la cosa tiene mala pinta. :-(


    Enrique Martínez Montejo
            [MS MVP - VB]

    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.

    • Marcado como respuesta gemma_campillo martes, 8 de diciembre de 2015 15:18
    martes, 8 de diciembre de 2015 10:48
    Moderador
  • Hola maestro:

    Gracias por responder como siempre.

    Bueno, el usuario es el que genera la hoja de Excel, aunque para facilitarle el tema, puede exportar el Datagridview para poder utilizar la misma cabecera que hará servir para la importación, la cabcera es simple: Cód_GC que es campo de texto, Ejer_01, Ejer_02 ... que se corresponden con las columnas del Datagridview o de la tabla Balances y los mismos con campos numéricos del tipo "double". 

    Por otro lado, exporto en fichero "csv" y el usuario después lo "guarda como", "xls o xlsx".

    Enrique, este es el procedimiento que utilizo para exportar desde Access2007 a Excel.

      Private Function Exportar_Excel() As Boolean
            Dim cadenaubicacion As String
            Dim directorio As New FolderBrowserDialog
            If directorio.ShowDialog = System.Windows.Forms.DialogResult.OK Then
                cadenaubicacion = directorio.SelectedPath
    
                Dim stream As Stream
                Dim escritor As StreamWriter
                Dim fila = DataGridView1.Rows.Count
                Dim columnas = DataGridView1.Columns.Count
                Dim archivo As String = cadenaubicacion & "\" & archivoGuardar & ".csv"
                Dim linea As String = ""
                Dim filadata, column As Int32
                'Borramos el archivo si existe
                File.Delete(archivo)
                stream = File.OpenWrite(archivo)
                escritor = New StreamWriter(stream, System.Text.Encoding.UTF8)
    
                'cabecera
                'linea = "Primera línea"
                'escritor.WriteLine(linea)
                ' linea = ""
                'linea = DataGridView1.Columns("Cód_GC").Name
                'linea = DataGridView1.Columns("Ejer_01").Name
                For column = 1 To 1
                    linea = linea & DataGridView1.Columns(column).Name & ";"
                    'Aquí agregamos el nombre de las columnas a la hoja
                Next
                For column = 4 To columnas - 1
                    linea = linea & DataGridView1.Columns(column).Name & ";"
                    'Aquí agregamos el nombre de las columnas a la hoja
                Next
    
    
                linea = Mid(CStr(linea), 1, linea.ToString.Length - 1)
                escritor.WriteLine(linea)
                linea = Nothing
                'filas
                For filadata = 0 To fila - 1
                    For column = 1 To 1
                        linea = linea & CStr(DataGridView1.Item(column, filadata).Value) & ";"
                    Next
                    For column = 4 To columnas - 1
                        linea = linea & CStr(DataGridView1.Item(column, filadata).Value) & ";"
                    Next
    
                    linea = Mid(CStr(linea), 1, linea.ToString.Length - 1)
                    escritor.WriteLine(linea)
                    linea = Nothing
                Next
    
    
                linea = Nothing
                'linea = "Fue una prueba para exportar a excel;"
                escritor.WriteLine(linea)
                escritor.Close()
    
                Try
                    Process.Start(archivo) 'ejecutamos el archivo
                    Return True
                Catch ex As Exception
                    MsgBox(ex.Message)
                    Return False
                End Try
            End If
            Return False
        End Function

    En fin, esos son los dos procesos que utilizo para exportar e importar datos. De todas formas, exportar habrás visto que lo hace sin problemas a Excel aunque la columna "Cód_GC" que es de texto, lleve números y/o números con letras.

    Voy a proceder a arreglar lo del ISAM que me has hecho notar.

    Maestro, el otro día  al final se arregló el tema de la consolidación si lo recuerdas.

    Bueno Enrique, muchas gracias por tu ayuda.

    Gemma

    martes, 8 de diciembre de 2015 15:17
  • "gemma_campillo" escribió:

    > el usuario es el que genera la hoja de Excel, ... Por otro lado, exporto en
    > fichero "csv" y el usuario después lo "guarda como", "xls o xlsx".

    Pues ahí es donde está el problema, ya que los usuarios generarán el archivo de Excel como les venga en gana, y no saben que la primera columna (aquella que tiene datos numéricos y alfanuméricos entremezclados), TIENEN QUE DECLARARLA EN EL ARCHIVO DE EXCEL CON EL FORMATO TEXTO. Si se limitan a abrir con Excel el archivo *.csv, modificar los datos y guardar la hoja con formato de Excel (*.xlsx o *.xls), la primera columna tendrá por defecto el formato GENERAL, con lo que tendrás problemas a la hora de importar los datos a Access, SQL Server, a un objeto DataTable o donde quieras llevártelos, por mucho que especifiques el valor IMEX=1 en las propiedades extendidas de la cadena de conexión, ya que las filas que contienen valores alfanuméricos son las menos, siendo más numerosas aquellas que tienen valores numéricos exclusivos, de ahí que el ISAM de Excel tome la columna como numérica, ya que te comento que "milagros" tampoco hace el ISAM de Excel. ;-)

    Pues como te dije al final de mi anterior mensaje, por ahora no le veo yo una solución al problema, salvo que la primera columna de la hoja de cálculo del archivo de Excel tenga establecido el formato Texto. Si deseas hacer una prueba, abre el libro de Excel que deseas importar, selecciona la primera columna, y abre el cuadro de diálogo Formato de celdas. Selecciona la pestaña Número y dentro del control ListBox llamado Categoría, selecciona Texto. Guarda los cambios y cierra el libro de Excel.

    Si rellenas un objeto DataTable mediante el valor devuelto por la siguiente función:

        ''' <summary>
        ''' Devuelve un objeto DataTable con los datos existentes
        ''' en la hoja de cálculo de Excel especificada.
        ''' </summary>
        ''' <param name="fileName">Ruta del archivo de Excel.</param>
        ''' <param name="nombreHoja">Nombre de la hoja de cálculo.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend Shared Function GetDataExcel(fileName As String, nombreHoja As String) As DataTable
    
            If ((String.IsNullOrEmpty(fileName)) OrElse (fileName.Trim() = String.Empty)) Then
                Throw New ArgumentNullException("fileName", "No se ha especificado el archivo de Excel.")
            End If
    
            If ((String.IsNullOrEmpty(nombreHoja)) OrElse (nombreHoja.Trim() = String.Empty)) Then
                Throw New ArgumentException("nombreHoja", "No se ha especificado el nombre de la hoja de cálculo.")
            End If
    
            Dim cadenaConexion As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;" &
                                                         "Extended Properties='Excel 12.0 Xml;IMEX=1;HDR=Yes;';" &
                                                         "Data Source={0}", fileName)
            ' Creamos un nuevo objeto DataTable.
            Dim dt As New DataTable(nombreHoja)
    
            Using cnn As New OleDbConnection(cadenaConexion)
    
                Dim cmd As OleDbCommand = cnn.CreateCommand()
                cmd.CommandText = String.Format("SELECT * FROM [{0}$]", nombreHoja)
    
                Dim da As New OleDbDataAdapter(cmd)
    
                ' Rellenamos el objeto DataTable.
                '
                da.Fill(dt)
            End Using
    
            ' Devolvemos el objeto DataTable.
            '
            Return dt
    
        End Function

    podrás observar que ahora sí aparecen en la primera columna los valores alfanuméricos 100, 110, 112M, etc., si enlazas el objeto DataTable obtenido con un control DataGridView.

    A la función simplemente le tienes que especificar la ruta completa del archivo de Excel al que deseas conectarte y el nombre de la hoja de cálculo que contiene los datos (Hoja1, Hoja2, NombreHoja, o como se llame).

                               


    Enrique Martínez Montejo
            [MS MVP - VB]

    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.


    martes, 8 de diciembre de 2015 16:22
    Moderador
  • Hola Enrique:

    Muchísimas gracias por tu ayuda, ahora funciona perfectamente. En la ayuda del programa donde está el apartado de Importación de Datos, comentaré el proceso que tiene que hacer el usuario y solucionado.

    Me he sacado un problema de encima sobre todo para algunos países hispanos que tienen el mismo número de grupo contable para el corto y largo plazo, entonces se diferencia por CP y LP.

    Bueno, eso era lo que me faltaba y como siempre con yu ayuda y sabiduría me los ha solucionado.

    Maestroooooooo, muchas gracias.

    Cuídate mucho y ten envío un fuertísimo abrazo. Ah!.  Mañana te envío una actualización.

    Gemma

    martes, 8 de diciembre de 2015 16:52