Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    Error ExecuteDataReader: Importazione da Excel ad Access

    Salve a tutti, ho un problemino riguardante importazione di dati da un foglio excel ad un database access. Vado subito al punto e vi spiego i miei parametri di programmazione.
    I passi che esegue il mio software sono i seguenti:

    1) Tramite un form prelevo il file excel in cui sono inseriti i dati da importare, analizzo il file e mi porto sul primo foglio del file per esaminare la tabella.
    2) Accedo al foglio Excel tramite OleDb Connection, impostando in prima riga le intestazioni delle colonne
    3) Prelevo i nomi delle colonne di Excel e le metto a confronto con le colonne del database facendo scegliere all'utente quali devono essere importate e quali campi del database devono popolare
    4) Fatto ciò eseguo una SELECT ALL sul foglio excel e tramite un OleDbDataReader.Read faccio scorrere riga per riga, controllo che ci sia un duplicato nel mio database e quindi inserisco. In questa fase ho inserito un Application.DoEvents che fa in modo che mi mostri, passo per passo a video, a che punto si è arrivati, impostando anche un Threading.Thread.Sleep(1500) nella fase di inserimento.

    Il problema sorge al punto 4: nella fase di prelevamento dei dati, quando vado a fare un controllo sul database e un eventuale inserimento, dopo 62 (o forse 63) iterazioni il programma si blocca con 2 messaggi di errore:
    1) "Errore non specificato"
    2) "Excecute Reader richiede una connessione aperta e disponibile. Lo stato della connessione è chiuso"

    Ma non è possibile che sia chiuso, in quanto ad ogni controllo apro e chiudo la connessione, ad ogni aggiunta al database apro e chiudo la connessione. Di seguito vi posto il codice

    Fuzione DBImport
    Parametri in input:
    1) Type: Stringa che stabilisce il tipo di importazione
    2) Filename: Stringa che stabilisce il nome del file excel da cui importare i dati
    3) Relation: Hashtab relazioni tra le colonne del db e le colonne excel
    4) l : listbox dove verranno visualizzati i passi per ogni riga del foglio excel
    5) lblinseriti: label num di righe excel inserite nel database
    6) lblduplicati: label num di righe excel già presenti nel database (controllo su un campo indicizzato)
    7) lelerrori: label d num di righe excel che non possono essere aggiunte al database.

    codice:
    Public Sub DBImport(ByVal type As String, ByVal filename As String, ByVal relation As Hashtable, ByRef l As ListBox, ByRef labelInseriti As Label, ByRef labelDuplicati As Label, ByRef labelErrori As Label)              
    Dim sheet As String         
    Dim log As String          
    Select Case type             
        Case "EXCEL"                 
            sheet = ExcelSheetName(filename)          
    End Select            
    
    Dim cn2 As OleDbConnection         
    cn2 = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;FirstRowHasNames=1';")          
    
    Try             
        cn2.Open()              
        Dim sql As String = "select * from [" + sheet + "]"               
        Dim cmd As New OleDbCommand(sql, cn2)             
        Dim reader2 As OleDbDataReader = cmd.ExecuteReader             
        Dim i = 0            
        Dim dup As Integer             
        Dim ins As Integer            
        Dim err As Integer            
        While reader2.Read                    
            log = ""                    
            Dim t As New Tesserato                 
            t.CodiceFiscale = reader2(relation("CodiceFiscale")).ToString.ToUpper        
            t.Cognome = reader2(relation("Cognome")).ToString.ToUpper               
            t.Nome = reader2(relation("Nome")).ToString.ToUpper              
    
            Application.DoEvents()                 
            If (t.CodiceFiscale.Length <> 16 Or t.Cognome.Length = 0 Or t.Nome.Length = 0) Then
                err = err + 1                    
                l.Items.Add("Errore. Dati obbligatori non corretti - " + t.CodiceFiscale + " " + t.Cognome + " " + t.Nome)                     
                labelErrori.Text = err.ToString                
            Else 
                If CFControl(t.CodiceFiscale) = True Then 
                    dup = dup + 1                       
                    l.Items.Add("Già esistente in database - " + t.CodiceFiscale + " " + t.Cognome + " " + t.Nome)                       
                    labelDuplicati.Text = dup.ToString                     
                Else                            
                    Dim ok As Integer = DBadd(t)                             
                    Threading.Thread.Sleep(1500)    
                    ins = ins + 1                         
                    l.Items.Add("Inserito in database: " + t.CodiceFiscale + " " + t.Cognome + " " + t.Nome + " - LOG:" + log)                         labelInseriti.Text = ins.ToString                      
                End If
          End if                
    End While               
    
    cn2.Close()             
    cn2.Dispose()            
    
    Catch ex As Exception          
    
    End Try       
    
    End Sub
    codice:
    Public Function ExcelSheetName(ByVal filename As String) As String         Dim cn2 As OleDbConnection         cn2 = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;FirstRowHasNames=1';")         Dim dtTables As DataTable         Dim colonne As New ArrayList         Dim tablename As String         cn2.Open()         dtTables = cn2.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)          Dim i As Integer = 0           For Each row As DataRow In dtTables.Rows             If i = 0 Then                 tablename = row("TABLE_NAME").ToString()                 i = 1             End If          Next         cn2.Close()         cn2.Dispose()         Return tablename     End Function      Private Function NTControl(ByVal ntessera As Int64) As Boolean         Dim t As New Tesserato          Dim reader As OleDbDataReader = DBsearchFor("NTessera", ntessera, DbType.Int64, False)         While reader.Read             readerToTesser(reader, t)         End While          If t.CodiceFiscale.Length <> 0 Then             Return True         Else             Return False         End If     End Function
    codice:
    Public Function CFControl(ByVal cf As String) As Boolean         Dim t As New Tesserato          Dim reader As OleDbDataReader = DBsearchFor("CodiceFiscale", cf, DbType.String, False)         While reader.Read             readerToTesser(reader, t)         End While            If t.CodiceFiscale.Length <> 0 Then             Return True         Else             Return False         End If      End Function
    codice:
    Public Function DBsearchFor(ByRef criteria As String, ByRef content As Object, ByVal type As DbType, ByVal amplia As Boolean) As OleDbDataReader          Connetti()         Dim cmd As OleDbCommand          If amplia Then             cmd = New OleDbCommand("SELECT * FROM Tesseramenti WHERE " + criteria + " LIKE '%" + content + "%' ORDER BY Cognome", cn)          Else             cmd = New OleDbCommand("SELECT * FROM Tesseramenti WHERE " + criteria + "=? ORDER BY Cognome", cn)              Dim prm As New OleDbParameter             prm.DbType = type             prm.Value = content             cmd.Parameters.Add(prm)         End If           Dim reader As OleDbDataReader          Try             reader = cmd.ExecuteReader          Catch ex As Exception             MsgBox(ex.ToString)         End Try          Return reader         Disconnetti()     End Function
    codice:
    Public Function DBadd(ByRef t As Tesserato) As Integer         Connetti()          Dim cmd As New OleDbCommand("INSERT INTO Tesseramenti([CodiceFiscale],[Cognome],[Nome],[DataNascita],[LuogoNascita],[Categoria],[Azienda],[Via],[NCivico],[Cap],[Citta],[Provincia],[Telefono],[Cellulare],[Email],[NTessera],[DataTesseramento]) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", cn)          Dim prm As New OleDbParameter          prm.DbType = DbType.String         prm.Value = t.CodiceFiscale         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Cognome         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Nome         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.Date         prm.Value = t.DataNascita         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.LuogoNascita         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Categoria         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Azienda         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Via         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.NCivico         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Cap         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Citta         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Provincia         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Telefono         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Cellulare         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.String         prm.Value = t.Email         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.Int32         prm.Value = t.NTessera         cmd.Parameters.Add(prm)          prm = New OleDbParameter         prm.DbType = DbType.Date         prm.Value = t.DataTesseramento         cmd.Parameters.Add(prm)          Dim result As Integer          Try             Connetti()             result = cmd.ExecuteNonQuery         Catch ex As Exception             MsgBox(ex.ToString)         End Try             Return result            Disconnetti()       End Function
    Grazie a tutti!

  2. #2
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    E' inutile postare codice 'formattato a caso' come hai fatto tu.
    E' illeggibile, quindi non si capisce un granché.

    A parte questo, da quello che mi pare di aver capito l'unico controllo che devi fare è sul CF: esiste o non esiste, per cui:

    1. prima verifico il CF, e valorizzo una colonna del foglio ESISTE con 1=se esiste, 0=se non esiste
    2. inserisco solo i record il cui valore di ESISTE è 0

  3. #3
    Si, ho notato dopo che era formattato malissimo. Mi dispiace. Comunque ora ho capito quale è il problema ma ancora non ho risolto: effettuo il controllo sul codice fiscale, se non c'è inserisco, se c'è inserisco. Nel momento in cui non c'è, effettuo due volte l'accesso al database nello stesso blocco di istruzioni e, siccome ho applicato un Application.doEvent, la connessione e disconnessione al database può andare in contrasto. Ora, volevo sapere, come faccio a dirgli di fermarsi se sto inserendo e poi effettuare il controllo sul nuovo record?

  4. #4
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Non devi connettere/disconnettere ad ogni iterazione (mi sembra di aver capito che fai così) perchè non ha senso, dato che NON sei sul web, ma in locale (o al massimo in una rete LAN).

    Seconda cosa, non hai capito, o mio sono espresso male...

    Prima scorri tutte le righe ed imposti il flag di controllo in una colonna del foglio ESISTE (0 o 1)
    Poi fai l'inserimento delle sole righe che hanno ESISTE=0

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.