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!