Ciao a tutti,
ho un problemino con la gestione apertura/chiusura un database access.
Da VB.NET apro il DB con la seguente funzione:
Dopo aver aperto correttamente il file scarico l'elenco di tutte le tabelle, query e macro presenti nel file con questa funzione (posto tutto il codice, magari puo' interessare a qualcuno):codice:Public Sub ApriFileAccess(ByRef accApp As Access.Application, ByVal file As String, ByVal visibile As Boolean) accApp = New Access.ApplicationClass() accApp.OpenCurrentDatabase(file, True) accApp.Visible = visibile End Sub
Alla fine c'è la funzione ChiudiFileAccess che dovrebbe chiudere l'applicazione aperta accApp:codice:Dim connessione As ADOX.Catalog = New ADOX.Catalog Dim contRighe As Integer Dim xlsApp As Excel.Application Dim xlsBook As Excel.Workbook Dim accApp As Access.Application Public Const PercorsoMacro As String = "C:\ChannelStrategy\MacroTestuali\" Public Structure Tabella Dim Nome As String Dim Link As String End Structure Public Const QUERY_SELECT As Integer = 1 Public Const QUERY_CROSS As Integer = 2 Public Const QUERY_DELETE As Integer = 3 Public Const QUERY_UPDATE As Integer = 4 Public Const QUERY_APPEND As Integer = 5 Public Const QUERY_MAKE As Integer = 6 Public Structure Query Dim Nome As String Dim SQL As String Dim Tipo As Integer End Structure Public Const AZIONE_SETWARNING As Integer = 1 Public Const AZIONE_OPENQUERY As Integer = 2 Public Const AZIONE_CLOSE As Integer = 3 Public Const AZIONE_TRANSFERSPREADSHEET As Integer = 4 Public Const AZIONE_SENDOBJECT As Integer = 5 Public Const AZIONE_MSGBOX As Integer = 6 Public Structure Azione Dim NomeAzione As String Dim TipoAzione As Integer Dim ListaArgument() As Object Dim ContArgument As Integer End Structure Public Structure Macro Dim NomeMacro As String Dim ListaAzioni() As Azione Dim ContAzioni As Integer End Structure Public ListaTabelle() As Tabella Public ListaQuery() As Query Public ListaMacro() As Macro Public contTabelle As Integer Public contQuery As Integer Public contMacro As Integer Public contAzioni As Integer Public contArgument As Integer Private Sub DammiDatiDataBase() Dim Contenitore As Container Dim Documento As Document Dim sr As StreamReader = Nothing Dim riga As String Dim arrRiga() As String Dim i, j As Integer ' Apro il file access invisibile lblAttesaOperazione.Text = "Connessione al db in corso" Me.Update() ApriFileAccess(accApp, ProprietaFile.PercorsoLocale & ProprietaFile.NomeFile, False) accApp.Visible = False ' Ottengo la lista di tutte le tabelle lblAttesaOperazione.Text = "Ottengo la lista di tutte le tabelle" Me.Update() contTabelle = 0 For i = 0 To accApp.CurrentDb.TableDefs.Count - 1 If Not accApp.CurrentDb.TableDefs(i).Name.StartsWith("MSys") Then contTabelle = contTabelle + 1 Array.Resize(ListaTabelle, contTabelle) ListaTabelle(contTabelle - 1).Nome = accApp.CurrentDb.TableDefs(i).Name If accApp.CurrentDb.TableDefs(i).Connect = "" Then ListaTabelle(contTabelle - 1).Link = "" Else arrRiga = accApp.CurrentDb.TableDefs(i).Connect.Split("=") If arrRiga(0).StartsWith("Text") Then ListaTabelle(contTabelle - 1).Link = arrRiga(arrRiga.GetUpperBound(0)) & ".txt" Else ListaTabelle(contTabelle - 1).Link = arrRiga(arrRiga.GetUpperBound(0)) End If End If End If Next ' Ottengo la lista di tutte le query lblAttesaOperazione.Text = "Ottengo la lista di tutte le query" Me.Update() contQuery = accApp.CurrentDb.QueryDefs.Count Array.Resize(ListaQuery, contQuery) For i = 0 To contQuery - 1 ListaQuery(i).Nome = accApp.CurrentDb.QueryDefs(i).Name ListaQuery(i).SQL = accApp.CurrentDb.QueryDefs(i).SQL If StrComp("SELECT", ListaQuery(i).SQL.Substring(0, 6)) Then ListaQuery(i).Tipo = QUERY_SELECT ElseIf StrComp("TRANSFORM", ListaQuery(i).SQL.Substring(0, 9)) Then ListaQuery(i).Tipo = QUERY_CROSS ElseIf StrComp("DELETE", ListaQuery(i).SQL.Substring(0, 6)) Then ListaQuery(i).Tipo = QUERY_DELETE ElseIf StrComp("UPDATE", ListaQuery(i).SQL.Substring(0, 6)) Then ListaQuery(i).Tipo = QUERY_UPDATE ElseIf StrComp("INSERT", ListaQuery(i).SQL.Substring(0, 6)) Then ListaQuery(i).Tipo = QUERY_APPEND ElseIf ListaQuery(i).SQL.Contains("INTO") Then ListaQuery(i).Tipo = QUERY_MAKE End If Next ' Scarico i contenuti di tutte le macro presenti lblAttesaOperazione.Text = "Ottengo la lista di tutte le macro" Me.Update() Directory.CreateDirectory(PercorsoMacro) contMacro = 0 Contenitore = accApp.CurrentDb.Containers("Scripts") For j = 0 To Contenitore.Documents.Count - 1 Documento = Contenitore.Documents(j) If Not Documento.Name.StartsWith("~") Then contAzioni = 0 contMacro = contMacro + 1 Array.Resize(ListaMacro, contMacro) ' Salvo la macro come file di testo accApp.Application.SaveAsText(Access.AcObjectType.acMacro, Documento.Name, PercorsoMacro & Documento.Name & ".txt") ListaMacro(contMacro - 1).NomeMacro = Documento.Name sr = New StreamReader(PercorsoMacro & Documento.Name & ".txt") riga = sr.ReadLine() While Not riga Is Nothing If riga = "Begin" Then contArgument = 0 contAzioni = contAzioni + 1 Array.Resize(ListaMacro(contMacro - 1).ListaAzioni, contAzioni) riga = sr.ReadLine() arrRiga = riga.Split("=") riga = arrRiga(1).Substring(1, arrRiga(1).Length - 2) ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).NomeAzione = riga Select Case riga Case "SetWarnings" ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_SETWARNING contArgument = 1 ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument) Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While Not arrRiga(0).Contains("Argument") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(contArgument - 1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) 'vado fino a end Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While arrRiga(0) <> "End" Case "OpenQuery" ' mi interessa solamente il primo Argument ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_OPENQUERY contArgument = 1 ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument) Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While Not arrRiga(0).Contains("Argument") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(contArgument - 1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) 'vado fino a end Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While arrRiga(0) <> "End" Case "Close" Case "MsgBox" ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).TipoAzione = AZIONE_OPENQUERY contArgument = 4 ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ContArgument = contArgument Array.Resize(ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument, contArgument) Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While Not arrRiga(0).Contains("Argument") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(0) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) riga = sr.ReadLine() arrRiga = riga.Split("=") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(1) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) riga = sr.ReadLine() arrRiga = riga.Split("=") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(2) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) riga = sr.ReadLine() arrRiga = riga.Split("=") ListaMacro(contMacro - 1).ListaAzioni(contAzioni - 1).ListaArgument(3) = arrRiga(1).Substring(1, arrRiga(1).Length - 2) 'vado fino a end Do riga = sr.ReadLine() arrRiga = riga.Split("=") Loop While arrRiga(0) <> "End" End Select End If riga = sr.ReadLine() End While ListaMacro(contMacro - 1).ContAzioni = contAzioni sr.Close() sr = Nothing End If System.Runtime.InteropServices.Marshal.ReleaseComObject(Documento) Documento = Nothing Next j Directory.Delete(PercorsoMacro, True) ' Chiudo il file access lblAttesaOperazione.Text = "Chiusura DataBase" Me.Update() System.Runtime.InteropServices.Marshal.ReleaseComObject(Contenitore) Contenitore = Nothing ChiudiFileAccess(accApp) End Sub
PROBLEMA:codice:Public Sub ChiudiFileAccess(ByRef accApp As Access.Application) accApp.CurrentDb.Close() accApp.CloseCurrentDatabase() accApp.Quit(Access.AcQuitOption.acQuitSaveNone) System.Runtime.InteropServices.Marshal.ReleaseComObject(accApp) accApp = Nothing GC.Collect() GC.WaitForPendingFinalizers() End Sub
Quando arrivo al comando GC.Collect() viene visualizzata la schermata di access senza nessun DB aperto e se controllo nel Task Manager il processo MSACCESS è ancora in uso.
Quindi quando ritento per qualche ragione a riaprire il file (sono in modalità esclusiva) ovviamente mi da errore.
Cosa sbaglio? Grazie in anticipo
Andrea

Rispondi quotando
