none
Importación de datos desde Excel a factoría de proveedores RRS feed

  • Pregunta

  • Hola a todos, buenos días:

    Tengo el siguiente código para importar desde Excel a una tabla de SqlServer express en este caso, pero la misma me sirve para Access y para slcompact.

    La he copiado y cambiado de la que tenía para importar desde Access que me funcionaba perfectamente, pero ahora me está dando problemas al importar los 5 ejercicios, indicando el error indicado, donde va marcado en negrita en el código:

    El nombre de variable '@ej1' ya se ha declarado. Los nombres de variable deben ser únicos en cada lote de consultas o procedimiento almacenado.
     Private Sub Importar(ByVal rut As String, ByVal ruc As String)
            ' Creamos el acceso a datos mediante el nombre de la cadena de conexión existente en el archivo de configuración de la aplicación.
            Dim da As DataAccessInvariant = DataAccessInvariant.GetDataAccessInvariant(Configuracion.CadenaConexion)
    
            Dim noi As New System.Text.StringBuilder
    
    
            Try
                ' Declaramos una variable Connection
                Using cnn As DbConnection = da.CreateConnection()
    
                    ' Creamos el Commando
                    Dim cmd As DbCommand = cnn.CreateCommand()
    
                    cnn.Open()
    
                    'Conexión Excel
                    Using cnx As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & rut & ";Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1'")
    
                        cnx.Open()
    
                        Dim hoj As String = NombrePrimeraHoja(cnx)
                        Using cmdx As New OleDb.OleDbCommand("SELECT * FROM [" & hoj & "]", cnx)
                            Using dr As OleDb.OleDbDataReader = cmdx.ExecuteReader(CommandBehavior.SingleResult)
                                If dr.HasRows Then
                                    Dim fil As Integer = 1I
                                    Dim tot As Integer = 0I
                                    Dim ccc As String = String.Empty
    
                                    Cursor = Cursors.WaitCursor
    
                                    VarGlobal.bolActivadoCuadroContable = True
                                    Dim frmPreparandoInforme = New frmPreparandoInforme
                                    frmPreparandoInforme.Show()
    
                                    Application.DoEvents()
    
                                    While dr.Read
                                        fil += 1I
                                        If dr.IsDBNull(0I) Then
                                            noi.AppendFormat("NULL (fila {0:N0}){1}", fil, Environment.NewLine)
                                        ElseIf dr.FieldCount.Equals(13I) Then '------ Estamos importando 12 ejercicios
                                            If dr.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                                ccc = dr.GetDouble(0I).ToString("R")
                                            ElseIf dr.GetFieldType(0I).Equals(GetType(System.String)) Then
                                                ccc = dr.GetString(0I)
                                            End If
    
                                                                                If dr.FieldCount.Equals(6I) Then '------ Estamos importando 5 ejercicios
                                            If dr.GetFieldType(0I).Equals(GetType(System.Double)) Then
                                                ccc = dr.GetDouble(0I).ToString("R")
                                            ElseIf dr.GetFieldType(0I).Equals(GetType(System.String)) Then
                                                ccc = dr.GetString(0I)
                                            End If
                                            cmd.CommandText = ("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 & "'")
                                            With cmd.Parameters
                                                .Add(Configuracion.CreateParameter(cmd, "@ej1", dr.GetDouble(1I)))
                                                .Add(Configuracion.CreateParameter(cmd, "@ej2", dr.GetDouble(2I)))
                                                .Add(Configuracion.CreateParameter(cmd, "@ej3", dr.GetDouble(3I)))
                                                .Add(Configuracion.CreateParameter(cmd, "@ej4", dr.GetDouble(4I)))
                                                .Add(Configuracion.CreateParameter(cmd, "@ej5", dr.GetDouble(5I)))
                                            End With
                                            If cmd.ExecuteNonQuery.Equals(0I) Then noi.AppendFormat("{0} (fila {1:N0}){2}", ccc, fil, Environment.NewLine)
                                            tot += 1I
                                    end while
                                                                               
                                    frmPreparandoInforme.Close()
    
                                    CargaDatagridView1()
    
                                    '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 & "»", 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, 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, Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
                                    End If
                                Else
                                    System.Windows.Forms.MessageBox.Show("La hoja de cálculo «" & hoj & "» no contiene datos para importar", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                                End If
                                dr.Close()
    
                                Cursor = Cursors.Default
    
                            End Using
                        End Using
    
                    End Using
                End Using
    
                bolCambiosDatagridView = True 'Para activar la carga de fórmulas.
                CuadreBalances()
    
            Catch ex As Exception
                MsgBox(ex.Message)
    
            End Try
        End Sub

    Os agradezco las sugerencias de corrección de código que me puedan ayudar a solucionarlo.

    Un cordial saludo.

    Gemma

    miércoles, 22 de junio de 2016 10:34

Respuestas

  • "gemma_campillo" escribió:

    > La he copiado y cambiado de la que tenía para importar desde Access que me funcionaba
    > perfectamente, pero ahora me está dando problemas al importar los 5 ejercicios, indicando
    > el error indicado, donde va marcado en negrita en el código:
    >
    > El nombre de variable '@ej1' ya se ha declarado. Los nombres de variable deben ser únicos
    > en cada lote de consultas o procedimiento almacenado.

    Gemma, de éste tema creo recordar que ya hemos hablado en anteriores ocasiones, y el mensaje de error parece ser que se debe a que estás duplicando los parámetros en la colección Parameters del objeto DBCommand llamado 'cmd', ya que estás recorriendo un bucle While ... End While para ejecutar el método ExecuteNonQuery del comando anterior.

    Y la solución pasa por ejecutar el método Clear de la colección Parameters antes de la instrucción End While:

        While dr.Read
    
             ' ...
    
             ' ...
             
             ' Limpiamos la coleccion de parámetros
             cmd.Parameters.Clear()
    
        End While
    

    Ten en cuenta que SQL Server los parámetros son por nombre, no por posición, por lo que no puede haber dos parámetros con el mismo nombre.

    Por cierto, ignoro si has copiado/pegado bien el código del procedimiento llamado Importar, pero me ha dado por copiarlo en un módulo y obtengo un error de compilación de que faltan instrucciones End If. Espero que en el procedimiento de tu proyecto no falte ninguna. ;-)


    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.

    • Marcado como respuesta gemma_campillo miércoles, 22 de junio de 2016 15:39
    miércoles, 22 de junio de 2016 15:20
    Moderador

Todas las respuestas

  • "gemma_campillo" escribió:

    > La he copiado y cambiado de la que tenía para importar desde Access que me funcionaba
    > perfectamente, pero ahora me está dando problemas al importar los 5 ejercicios, indicando
    > el error indicado, donde va marcado en negrita en el código:
    >
    > El nombre de variable '@ej1' ya se ha declarado. Los nombres de variable deben ser únicos
    > en cada lote de consultas o procedimiento almacenado.

    Gemma, de éste tema creo recordar que ya hemos hablado en anteriores ocasiones, y el mensaje de error parece ser que se debe a que estás duplicando los parámetros en la colección Parameters del objeto DBCommand llamado 'cmd', ya que estás recorriendo un bucle While ... End While para ejecutar el método ExecuteNonQuery del comando anterior.

    Y la solución pasa por ejecutar el método Clear de la colección Parameters antes de la instrucción End While:

        While dr.Read
    
             ' ...
    
             ' ...
             
             ' Limpiamos la coleccion de parámetros
             cmd.Parameters.Clear()
    
        End While
    

    Ten en cuenta que SQL Server los parámetros son por nombre, no por posición, por lo que no puede haber dos parámetros con el mismo nombre.

    Por cierto, ignoro si has copiado/pegado bien el código del procedimiento llamado Importar, pero me ha dado por copiarlo en un módulo y obtengo un error de compilación de que faltan instrucciones End If. Espero que en el procedimiento de tu proyecto no falte ninguna. ;-)


    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.

    • Marcado como respuesta gemma_campillo miércoles, 22 de junio de 2016 15:39
    miércoles, 22 de junio de 2016 15:20
    Moderador
  • Hola Enrique:

    Ya está solucionado. Ese era el error, no se me había pasado por la cabeza y mira que en las formulas siempre tengo el clear antes de leer los parámetros.

    Maestro, el tema de los if es correcto, es que ese procedimiento es más largo, y hay if si son para 5 ejercicios, 4, 3, 2 y 1.

    Por otro lado me quiero mirar con tiempo una importación que hiciste a través de un datatable, lo tengo impreso y en cuanto pueda me voy a poner a estudiarla, porque creo que es mucho mas simple que como yo lo hago.

    Bueno, genio un fuerte abrazo como siempre y muchas gracias. Ya está todo, solo me tengo que leer lo de sql, de adjuntar la base, hacer copia por código de la base sql y ver si existe el servidor o la instancia, bueno, me lo tengo que leer esta tarde.

    Un fuerte abrazo querido amigo.

    Gemma

    miércoles, 22 de junio de 2016 15:39