PDA

View Full Version : [VB.NET] Problema rilascio instanza excel con backgroundworker..


jackk87
21-05-2011, 16:54
Buongiorno a tutti,
dalla mia applicazione vb devo importare i dati di un file excel che contiene i comuni quindi circa 10000 record.
L'importazione la eseguo tramite il backgroundworker in modo che l'applicazione non si blocchi. L'importazione funziona correttamente solo che al termine della stessa mi rimane il processo di excel in memoria (task manager) e non viene rilasciato.

il codice che uso è:

Private Sub ImportaFileExcel()
Dim FileExcel As Microsoft.Office.Interop.Excel.Workbook
Dim FoglioExcel As Microsoft.Office.Interop.Excel.Worksheet

Try
FileExcel = excelApp.Workbooks.Open(tbDirectory.Text) 'cartella di lavoro Excel

excelApp.Visible = False 'Nascondo l'applicazione Excel
FileExcel.Activate() 'Attivo il file
FoglioExcel = FileExcel.Worksheets(1) 'Seleziono il primo foglio

Dim numcolonna As Integer = 1 'Variabile per scansionare tutte le colonne
Dim ColonnaComune As Integer = 0 'Variabile per memorizzare la colonna del Comune
Dim ColonnaCap As Integer = 0 'Variabile per memorizzare la colonna del Cap
Dim ColonnaProvincia As Integer = 0 'Variabile per memorizzare la colonna della Provincia

'Ciclo per trovare gli indici di colonna
For numcolonna = 1 To 50
If FoglioExcel.Cells(1, numcolonna).value = "Descrizione" Then
ColonnaComune = numcolonna
ElseIf FoglioExcel.Cells(1, numcolonna).value = "CAP" Then
ColonnaCap = numcolonna
ElseIf FoglioExcel.Cells(1, numcolonna).value = "Codice_Provincia" Then
ColonnaProvincia = numcolonna
End If
If (FoglioExcel.Cells(1, numcolonna).value = Nothing) And (ColonnaComune <> 0) And (ColonnaCap <> 0) And (ColonnaProvincia <> 0) Then
Exit For
End If
Next

If ColonnaCap = 0 Or ColonnaComune = 0 Or ColonnaProvincia = 0 Then
FoglioExcel = Nothing
FileExcel.Close(False)
FileExcel = Nothing
excelApp.Quit()
excelApp = Nothing

MessageBox.Show("Errore: Impossibile trovare le colonne interessate (Descrizione,CAP,Codice_Provincia)..", "Ricerca colonne nel file excel", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

ErroreColonne = True
Exit Sub
End If

Dim numriga As Integer = 2 'Variabile per scansionare tutte le riche
Dim Comune, Cap, Provincia As String 'Variabile per memorizzare il destinatario e l'indirizzo
Dim percentuale As Integer = 0 'Variabile per memorizzare la percentuale dell'avanzamento
Dim numerorighe As Integer = FoglioExcel.UsedRange.Rows.Count 'Variabile che contiene il numero di righe totali
Dim idcategoria As Integer = 0 'variabile dove memorizzo l'ID della categoria
Dim DR As SqlDataReader

Dim TR As SqlClient.SqlTransaction 'Variabile della Transazione SQL
Try
Cn.Open() 'Apro la connessione al DB

TR = Cn.BeginTransaction(IsolationLevel.ReadCommitted) 'Inizio della Transazione
Dim CMD As New SqlCommand("", Cn, TR) 'SqlCommand con la transazione

'Codice SQL
CMD.CommandText = "DELETE FROM comuni"

CMD.ExecuteNonQuery() 'Eseguo il codice SQL

TR.Commit() 'Effettuo le modifiche nel DB
Cn.Close() 'Chiudo la connessione al DB
Catch ex As Exception
FoglioExcel = Nothing
FileExcel.Close(False)
FileExcel = Nothing
excelApp.Quit()
excelApp = Nothing
MessageBox.Show("Errore: " & ex.Message, "Svuotamento tabella comuni nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Try
TR.Rollback() 'Non effettuo le modifiche nel DB mandando un errore
Catch exRollback As Exception
MessageBox.Show("Errore: " & exRollback.Message, "Svuotamento tabella comuni nel DB con RollBack", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
If Cn.State = ConnectionState.Open Then 'Se la connessione al DB è aperta
Cn.Close() 'Chiudo la connessione al DB
End If
Exit Sub
End Try

'Ciclo per memorizzare i dati nel DB
For numriga = 2 To numerorighe
Try
Comune = FoglioExcel.Cells(numriga, ColonnaComune).value
Cap = FoglioExcel.Cells(numriga, ColonnaCap).value
Provincia = FoglioExcel.Cells(numriga, ColonnaProvincia).value

If String.IsNullOrEmpty(Comune) Then
Exit Try
End If

Cn.Open() 'Apro la connessione al DB

TR = Cn.BeginTransaction(IsolationLevel.ReadCommitted) 'Inizio della Transazione
Dim CMD As New SqlCommand("", Cn, TR) 'SqlCommand con la transazione

'Codice SQL
CMD.CommandText = "INSERT INTO comuni(descrizione,cap,provincia) " & _
"VALUES(@descrizione,@cap,@provincia)"

CMD.Parameters.Add("@descrizione", SqlDbType.VarChar) 'Parameters
CMD.Parameters.Add("@cap", SqlDbType.Int) 'Parameters
CMD.Parameters.Add("@provincia", SqlDbType.VarChar) 'Parameters

'Assegnazione Parametri :
CMD.Parameters("@descrizione").Value = Comune
If String.IsNullOrEmpty(Cap) Then
CMD.Parameters("@cap").Value = 0
Else
CMD.Parameters("@cap").Value = Cap
End If

If String.IsNullOrEmpty(Provincia) Then
CMD.Parameters("@provincia").Value = ""
Else
CMD.Parameters("@provincia").Value = Provincia
End If

CMD.ExecuteNonQuery() 'Eseguo la query

percentuale = percentuale + 1

bwImportaExcel.ReportProgress(percentuale * 100 / numerorighe)

TR.Commit() 'Effettuo le modifiche nel DB
Cn.Close() 'Chiudo la connessione al DB
Catch ex As Exception
FoglioExcel = Nothing
FileExcel.Close(False)
FileExcel = Nothing
excelApp.Quit()
excelApp = Nothing
MessageBox.Show("Errore: " & ex.Message, "Inserimento comune importato nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Try
TR.Rollback() 'Non effettuo le modifiche nel DB mandando un errore
Catch exRollback As Exception
MessageBox.Show("Errore: " & exRollback.Message, "Inserimento comune importato nel DB con RollBack", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
If Cn.State = ConnectionState.Open Then 'Se la connessione al DB è aperta
Cn.Close() 'Chiudo la connessione al DB
End If
Exit Sub
End Try
Next

FoglioExcel = Nothing
FileExcel.Close(False)
FileExcel = Nothing
excelApp.Quit()
excelApp = Nothing
Catch ex As Exception
FoglioExcel = Nothing
FileExcel.Close(False)
FileExcel = Nothing
excelApp.Quit()
excelApp = Nothing
MessageBox.Show("Errore: " & ex.Message, "Inserimento file Excel nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
End Sub

'*******BACKGROUND WORKER***********
Private Sub bwImportaExcel_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwImportaExcel.DoWork
ImportaFileExcel() 'Chiamo la procedura
End Sub

Private Sub bwImportaExcel_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwImportaExcel.ProgressChanged
pbPercentuale.Value = e.ProgressPercentage
lbPercentuale.Text = e.ProgressPercentage & " %"
End Sub

Private Sub bwImportaExcel_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwImportaExcel.RunWorkerCompleted
If e.Cancelled Then
'Una cancellazione?
MessageBox.Show("Importazione annullata!", "Errore..", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
btSalva.Enabled = True
btAnnulla.Enabled = True
ElseIf e.Error IsNot Nothing Then
'Un'eccezione?
MessageBox.Show("Si è verificato un errore!", "Errore..", MessageBoxButtons.OK, MessageBoxIcon.Error)
btSalva.Enabled = True
btAnnulla.Enabled = True
Else
frmOpzioni.CaricaDGW_Comuni()
If ErroreColonne = False Then
MsgBox("Importazione effettuata con successo!", MsgBoxStyle.Information, "Avviso..")
Else
MessageBox.Show("Importazione annullata!", "Errore..", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
abilitachiusura = True
Me.Close()
End If
bwImportaExcel.Dispose()
End Sub


ho provato anche con oledb ma il problema rimane il codice è:

Private Sub ImportaFileExcelConOleDB()
Dim CnFileExcel As OleDbConnection
Try
CnFileExcel = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tbDirectory.Text & ";Extended Properties='Excel 8.0'")

Dim sql As String

sql = "select Descrizione,CAP,Codice_Provincia from Comuni_ISTAT"

CnFileExcel.Open()

Dim CMDExcel As OleDbCommand = New OleDbCommand(sql, CnFileExcel)
Dim DA As OleDbDataAdapter = New OleDbDataAdapter(CMDExcel)
Dim DT As DataTable = New DataTable()
DA.Fill(DT)

CMDExcel.Dispose()

CnFileExcel.Close()

Dim TR As SqlClient.SqlTransaction 'Variabile della Transazione SQL
Try
Cn.Open() 'Apro la connessione al DB

TR = Cn.BeginTransaction(IsolationLevel.ReadCommitted) 'Inizio della Transazione
Dim CMD As New SqlCommand("", Cn, TR) 'SqlCommand con la transazione

'Codice SQL
CMD.CommandText = "DELETE FROM comuni"

CMD.ExecuteNonQuery() 'Eseguo il codice SQL

TR.Commit() 'Effettuo le modifiche nel DB
Cn.Close() 'Chiudo la connessione al DB
Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message, "Svuotamento tabella comuni nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Try
TR.Rollback() 'Non effettuo le modifiche nel DB mandando un errore
Catch exRollback As Exception
MessageBox.Show("Errore: " & exRollback.Message, "Svuotamento tabella comuni nel DB con RollBack", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
If Cn.State = ConnectionState.Open Then 'Se la connessione al DB è aperta
Cn.Close() 'Chiudo la connessione al DB
End If
Exit Sub
End Try

Dim Comune, Cap, Provincia As String 'Variabile per memorizzare il destinatario e l'indirizzo
Dim percentuale As Integer = 0 'Variabile per memorizzare la percentuale dell'avanzamento

For i = 0 To DT.Rows.Count - 1
Try
Comune = DT.Rows(i).Item(0).ToString
Cap = DT.Rows(i).Item(1).ToString
Provincia = DT.Rows(i).Item(2).ToString

If String.IsNullOrEmpty(Comune) Then
Exit Try
End If

Cn.Open() 'Apro la connessione al DB

TR = Cn.BeginTransaction(IsolationLevel.ReadCommitted) 'Inizio della Transazione
Dim CMD As New SqlCommand("", Cn, TR) 'SqlCommand con la transazione

'Codice SQL
CMD.CommandText = "INSERT INTO comuni(descrizione,cap,provincia) " & _
"VALUES(@descrizione,@cap,@provincia)"

CMD.Parameters.Add("@descrizione", SqlDbType.VarChar) 'Parameters
CMD.Parameters.Add("@cap", SqlDbType.Int) 'Parameters
CMD.Parameters.Add("@provincia", SqlDbType.VarChar) 'Parameters

'Assegnazione Parametri :
CMD.Parameters("@descrizione").Value = Comune
If String.IsNullOrEmpty(Cap) Then
CMD.Parameters("@cap").Value = 0
Else
CMD.Parameters("@cap").Value = Cap
End If

If String.IsNullOrEmpty(Provincia) Then
CMD.Parameters("@provincia").Value = ""
Else
CMD.Parameters("@provincia").Value = Provincia
End If

CMD.ExecuteNonQuery() 'Eseguo la query

percentuale = percentuale + 1

bwImportaExcel.ReportProgress(percentuale * 100 / DT.Rows.Count)

TR.Commit() 'Effettuo le modifiche nel DB
Cn.Close() 'Chiudo la connessione al DB
Catch ex As Exception
MessageBox.Show("Errore: " & ex.Message, "Inserimento comune importato nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Try
TR.Rollback() 'Non effettuo le modifiche nel DB mandando un errore
Catch exRollback As Exception
MessageBox.Show("Errore: " & exRollback.Message, "Inserimento comune importato nel DB con RollBack", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
If Cn.State = ConnectionState.Open Then 'Se la connessione al DB è aperta
Cn.Close() 'Chiudo la connessione al DB
End If
Exit Sub
End Try
Next
Catch ex As Exception
If CnFileExcel.State = ConnectionState.Open Then
CnFileExcel.Close()
End If
MessageBox.Show("Errore: " & ex.Message, "Inserimento file Excel nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
End Sub


grazie in anticipo a tutti :help: