Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30

    [VB.NET] Chiusura Access.ApplicationClass

    Ciao a tutti,
    ho un problemino con la gestione apertura/chiusura un database access.

    Da VB.NET apro il DB con la seguente funzione:
    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
    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:
     
    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
    Alla fine c'è la funzione ChiudiFileAccess che dovrebbe chiudere l'applicazione aperta accApp:

    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
    PROBLEMA:
    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

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30
    Ciao a tutti,
    ho intuito dove potrebbe essere il problema... ma non sono ancora arrivato alla soluzione...

    Quando eseguo solo questa funzione il database viene chiuso correttamente:

    codice:
    Private Sub cmdEseguiMacro_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEseguiMacro.Click
            Dim id As Integer
            Dim i, j As Integer
            Dim strApp As String
    
            If dgvMacro.Rows.Count = 0 Then
                MsgBox("Attenzione!!! Lista macro vuota!!!", MsgBoxStyle.Critical, TitoloApp)
                Exit Sub
            End If
    
            id = dgvMacro.Rows(dgvMacro.CurrentRow.Index).Cells(0).Value()
            pnlAttesa.Visible = True
            lblTitolo.Text = ListaMacro(id).NomeMacro
    
            ' Apro il file access visibile
            lblAttesaOperazione.Text = "Connessione al db in corso"
            Me.Update()
            ApriFileAccess(accApp, ProprietaFile.PercorsoLocale & ProprietaFile.NomeFile, True)
            For i = 0 To ListaMacro(id).ContAzioni - 1
                Select Case ListaMacro(id).ListaAzioni(i).TipoAzione
                    Case AZIONE_SETWARNING
                        If ListaMacro(id).ListaAzioni(i).ListaArgument(0) = "0" Then
                            strApp = "Off"
                        Else
                            strApp = "On"
                        End If
                        lblAttesaOperazione.Text = "Esecuzione: " & ListaMacro(id).ListaAzioni(i).NomeAzione & " " & strApp
                        Me.Update()
                        accApp.DoCmd.SetWarnings(ListaMacro(id).ListaAzioni(i).ListaArgument(0))
                    Case AZIONE_OPENQUERY
                        lblAttesaOperazione.Text = "Esecuzione: " & ListaMacro(id).ListaAzioni(i).NomeAzione & " - " & ListaMacro(id).ListaAzioni(i).ListaArgument(0)
                        Me.Update()
                        accApp.DoCmd.OpenQuery(ListaMacro(id).ListaAzioni(i).ListaArgument(0))
                    Case AZIONE_MSGBOX
                        lblAttesaOperazione.Text = "Esecuzione: " & ListaMacro(id).ListaAzioni(i).NomeAzione
                        MsgBox(ListaMacro(id).ListaAzioni(i).ListaArgument(0), ListaMacro(id).ListaAzioni(i).ListaArgument(2), ListaMacro(id).ListaAzioni(i).ListaArgument(3))
                End Select
            Next
    
            pnlAttesa.Visible = False
    
            ' Chiudo il file access
            ChiudiFileAccess(accApp)
        End Sub
    Il problema allora è nella funzione DammiDatiDataBase che non rilascia tutte le risorse.
    E' come se i comandi
    codice:
    System.Runtime.InteropServices.Marshal.ReleaseComObject(Documento)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(Contenitore)
    non venissero minimamente calcolati dal programma.


    Andrea

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30
    Risolto!!!!!!!!!!!!!

    codice:
            ApriFileAccess(accApp, ProprietaFile.PercorsoLocale & ProprietaFile.NomeFile, False)
            DammiListaTabelle()
            DammiListaQuery()
            DammiListaMacro()
            ChiudiFileAccess(accApp)
    Se spezzetto le varie funzioni il programma si chiude correttamente!!!!

    Ciaoooooooooooo

    Andrea

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.