[Risolto]Problema tabelle collegate BE-FE

di il
12 risposte

[Risolto]Problema tabelle collegate BE-FE

Buonasera a tutti, come da titolo ho questo problema...
Volevo evitare ogni qualvolta di dover linkare manualmente le tabelle del FE con il BE con una funzione...ho scaricato anche un database di prova e...quello di prova funziona ed il mio no...
La funzione è la seguente
Option Compare Database

' ------------------------------------------
' Funzione che ricollega FE a BE
' ------------------------------------------
' RICOLLEGA TABELLE AL DB QUANDO IL BE SI TROVA NELLA STESSA CARTELLA DELL' FE
' E SOLO SE LA CARTELLA DEL PROGETTO E DIVERSA RISPETTO ALL'ULTIMO RICOLLEGAMENTO DELLE TABELLE

Public Function myRicollegaTabelleCurrentFolder()

'Stop
Dim myDb As DAO.Database
Dim myTbl As DAO.TableDef
Dim iInt As Integer

' set db name BE - impostare il nome del BE
Dim strDatabase As String
' Impostare qui il nome del database BE
strDatabase = CurrentProject.Path & "\prova.accdb"

' strDatabase = CurrentProject.FullName

' password default
Dim linkPassword As String
linkPassword = "qui inserisci la password di accesso al db"

' test db BE
If Dir(strDatabase, vbArchive) = "" Then
    MsgBox "Non trovato BE.  Impossibile eseguire il ricollegamento tabelle per :" & vbCrLf & strDatabase, vbCritical, "Error"
    Exit Function
End If

' db connection and source folder database
' occurs if db password protected
On Error Resume Next
Set myDb = OpenDatabase(strDatabase, False, True)
If Err.Number = 3031 Then
    ' password request
    Do While Err.Number = 3031
        linkPassword = InputBox(Err.Description & vbCrLf & vbCrLf & "Inseri la Password per il Db: " & Dir(strDatabase, vbArchive), "Password")
        If linkPassword = "" Then Exit Function
        On Error GoTo 0
        On Error Resume Next
        Set myDb = OpenDatabase(strDatabase, False, True, "; PWD=" & linkPassword)
    Loop
End If
On Error GoTo 0

' read table defs
For iInt = 0 To myDb.TableDefs.Count - 1
    ' retrieve name table
    Set myTbl = myDb.TableDefs(iInt)
    If myTbl.Attributes = 0 Then
        ' verifica se ricollegare le tabelle al BE solo nel caso sia cambiata la cartella
        Dim varGet As Variant
        varGet = DLookup("Database", "MSysObjects", "Name='" & myTbl.Name & "'")
        If Not IsNull(varGet) Then
             If CurrentProject.Path <> Left(varGet, InStrRev(varGet, "\") - 1) Then
                 ' eliminazione tabella da ricollegare
                 On Error Resume Next
                 CurrentDb.Execute "Drop Table [" & myTbl.Name & "];"
                 On Error GoTo 0
                 ' loop di attesa fino a quando non è aggiornato il db con la cancellazione della tabella dal vecchio link
                 While Not IsNull(DLookup("Database", "MSysObjects", "Name='" & myTbl.Name & "'"))
                     DoEvents
                 Wend
                 ' ricollegamento tabella MsAccess
                 On Error Resume Next
                 DoCmd.TransferDatabase acLink, "Microsoft Access", strDatabase, acTable, myTbl.Name, myTbl.Name
                 ' errore ricollegamento tabelle
                 If Err.Number <> 0 Then
                     MsgBox "Errore ricollegamento tabelle al db:" & vbCrLf & Err.Description, vbCritical, "Error"
                     GoTo endErr0
                 End If
                 On Error GoTo 0
             End If
        End If
    End If
Next iInt

endErr0:
' close adox
myDb.Close
Set myDb = Nothing
Set myTbl = Nothing
End Function

sul caricamento della maschera "Tabella1" (lasciata così per la prova ma è una form) sull'evento load ho messo la call alla funzione
Private Sub Form_Load()
Call myRicollegaTabelleCurrentFolder
End Sub
il risultato è che non funziona...come mai lo stesso db dove ho preso l'esempio funge? Il db di esempio è in formato mdb ma ho provato a convertire l'accdb in mdb ma il risultato non cambia...

12 Risposte

  • Re: [Risolto]Problema tabelle collegate BE-FE

    Dire non funge, rende impraticabile fornire indicazioni, magari se si descrivono nel dettaglio le attività condotte (sul passaggio effettuato da MDB ad ACCDB, sui riferimenti alle librerie impiegate, sui controlli effettuati, e su dove e quando si riscontra l'inconveniente) potrebbe essere utile a superare le difficoltà.

    Inoltre se si allega del codice, preso pari pari, è sempre corretto citarne la fonte (forse questa?)
    https://forum.ialweb.it/forum_posts.asp?TID=1625712
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Ciao Willy, grazie per la risposta. Non sapevo si potesse citare la fonte ma confermo che la fonte è proprio quella da te segnalata.

    Per i riferimenti attivi vi sono:
    -Visual Basic for Applications
    -Microsoft Access 12.0 Object Library
    -OLE Automation
    Microsoft AcriveX Data Object 2.1 Library
    Microsoft DAO 3.6 Object Library.

    Ho creato un accdb, creato una tabella "Tabella1" ed una form "Tabella1". Diviso l'accdb tramite la procedura guidata ed inserito nel FE il codice sopra descritto. Impostato la form "Tabella1" come form principale all'apetura del db e nell'evento Form_Load il richiamo al codice con la Call

    Se possono essere utili altre info chiedi pure
  • Re: [Risolto]Problema tabelle collegate BE-FE

    zio Ken ha scritto:


    ..
    Per i riferimenti attivi vi sono:
    ...
    Microsoft AcriveX Data Object 2.1 Library
    ...
    Salvo codice molto particolare non dovresti aver bisogno del riferimento a questa libreria che, tra le altre cose, nell'ordine viene prima di DAO 3.6 quindi in presenza di dichiarazioni non disambugue, gli oggetti tipo Database, Recordset ecc sarebbero stati presi da quella libreria.
    L'informazione più importante che manca in generale è: cosa significa che non funziona? Dà errore? Se sì, che tipo? Non fa quello che dovrebbe fare?
    Visto che devi accedere ad un db accdb, forse dovresti sostituire il riferimento di DAO 3.6 con Microsoft Office 12.0 Access database engine
    La maschera che si carica all'apertura è associata?
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Philcattivocarattere ha scritto:


    zio Ken ha scritto:


    ..
    Per i riferimenti attivi vi sono:
    ...
    Microsoft AcriveX Data Object 2.1 Library
    ...
    Salvo codice molto particolare non dovresti aver bisogno del riferimento a questa libreria che, tra le altre cose, nell'ordine viene prima di DAO 3.6 quindi in presenza di dichiarazioni non disambugue, gli oggetti tipo Database, Recordset ecc sarebbero stati presi da quella libreria.
    L'informazione più importante che manca in generale è: cosa significa che non funziona? Dà errore? Se sì, che tipo? Non fa quello che dovrebbe fare?
    Visto che devi accedere ad un db accdb, forse dovresti sostituire il riferimento di DAO 3.6 con Microsoft Office 12.0 Access database engine
    La maschera che si carica all'apertura è associata?
    Ciao Phil, quando ho diviso il database, aprendolo non mi dava alcun errore, spostando la cartella sul desktop per verificare se effettivamente la connessione automatica fungesse, (be e fe nella stessa cartella) mi da errore: "C:\..."non è un percorso valido. Assicurarsi che il nome del percorso sia corretto e di essere collegati al server in cui si trova il file.
    la voce "Microsoft Office 12.0 Access database engine" non la trovo nell'elenco dei riferimenti...
    EDIT. voce trovata, ho deselezionato la DAO 3.6 e selezionato quella da te indicata però estesso problema
    P.S. in che senso la maschera associata? l'ho impostata come form di apertura quando apro il db tramite "Opzioni di Access\Database corrente\Visualizza maschera
  • Re: [Risolto]Problema tabelle collegate BE-FE

    zio Ken ha scritto:


    la voce "Microsoft Office 12.0 Access database engine" non la trovo nell'elenco dei riferimenti...
    Questo è molto strano. Hai Office/Access 2007, da quanto intuisco, vero? Ho visto l'edit. A posto.

    zio Ken ha scritto:


    ... spostando la cartella sul desktop ... mi da errore: "C:\..."non è un percorso valido. Assicurarsi che il nome del percorso sia corretto e di essere collegati al server in cui si trova il file.
    Nell'errore che compare, togliendo eventualmente nomi propri o altro (ma lasciando eventualmente spazi e caratteri strani), qual è il percorso segnalato?
    Il desktop forse è un percorso un po' accidentato. Prova con qualcosa di più semplice del tipo C:\Test\

    zio Ken ha scritto:


    P.S. in che senso la maschera associata? l'ho impostata come form di apertura quando apro il db tramite "Opzioni di Access\Database corrente\Visualizza maschera
    Ok, quello è come si lancia una maschera all'avvio, il mio discorso era volto ad un altro aspetto: visto che si tratta di lanciare una funzione che ha lo scopo di "sistemare" le tabelle collegate, meglio non disturbare alcuna origine dati (tabella o query che sia), ecco perché a mio avviso sarebbe preferibile usare per questa cosa una maschera non associata.
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Ciao Phil, ho provato a spostare la cartella in C ma ancora nessun esito positivo..ho eliminato l'associazione alla maschera all'apertura, apro il db, apro il database ma mi da ancora errore. All'interno dell'errore mi riporta la directory di quando ho diviso il db...come se il codice non fungesse proprio...
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Se hai scaricato il demo presente nel link citato:
    https://forum.ialweb.it/forum_posts.asp?TID=16257129&PN=3&title=risolto-spostare-file-access-collegati

    avrai notato che esiste una macro (Autoexec) che viene eseguita all'avvio, ed effettua solo due operazioni:
    - EseguiCodice --> myRicollegaTabelleCurrentFolder
    - ApriMaschera --> Menu_Principale

    Ora l'esecuzione del codice non fa altro che richiamare la seguente funzione:
    
    ' ------------------------------------------
    ' Funzione che ricollega FE a BE
    ' ------------------------------------------
    ' (By65Franco) 
    ' RICOLLEGA TABELLE AL DB QUANDO IL BE SI TROVA NELLA STESSA CARTELLA DELL' FE
    ' E SOLO SE LA CARTELLA DEL PROGETTO E DIVERSA RISPETTO ALL'ULTIMO RICOLLEGAMENTO DELLE TABELLE
    
    Public Function myRicollegaTabelleCurrentFolder()
    
    Dim myDb As DAO.Database
    Dim myTbl As DAO.TableDef
    Dim iInt As Integer
    
    ' set db name BE - impostare il nome del BE
    Dim strDatabase As String
    ' Impostare qui il nome del database BE (nell'esempio GAS_Dati.mdb)
    strDatabase = CurrentProject.Path & "\GAS_Dati.mdb"
    
    ' strDatabase = CurrentProject.FullName
    
    ' password default
    Dim linkPassword As String
    linkPassword = "qui inserisci la password di accesso al db dati.mdb"
    
    ' test db BE
    If Dir(strDatabase, vbArchive) = "" Then
        MsgBox "Non trovato BE.  Impossibile eseguire il ricollegamento tabelle per :" & vbCrLf & strDatabase, vbCritical, "Error"
        Exit Function
    End If
    
    ' db connection and source folder database
    ' occurs if db password protected
    On Error Resume Next
    Set myDb = OpenDatabase(strDatabase, False, True)
    If Err.Number = 3031 Then
        ' password request
        Do While Err.Number = 3031
            linkPassword = InputBox(Err.Description & vbCrLf & vbCrLf & "Inseri la Password per il Db: " & Dir(strDatabase, vbArchive), "Password")
            If linkPassword = "" Then Exit Function
            On Error GoTo 0
            On Error Resume Next
            Set myDb = OpenDatabase(strDatabase, False, True, "; PWD=" & linkPassword)
        Loop
    End If
    On Error GoTo 0
    
    ' read table defs
    For iInt = 0 To myDb.TableDefs.Count - 1
        ' retrieve name table
        Set myTbl = myDb.TableDefs(iInt)
        If myTbl.Attributes = 0 Then
            ' verifica se ricollegare le tabelle al BE solo nel caso sia cambiata la cartella
            Dim varGet As Variant
            varGet = DLookup("Database", "MSysObjects", "Name='" & myTbl.Name & "'")
            If Not IsNull(varGet) Then
                 If CurrentProject.Path <> Left(varGet, InStrRev(varGet, "\") - 1) Then
                     ' eliminazione tabella da ricollegare
                     On Error Resume Next
                     CurrentDb.Execute "Drop Table [" & myTbl.Name & "];"
                     On Error GoTo 0
                     ' loop di attesa fino a quando non è aggiornato il db con la cancellazione della tabella dal vecchio link
                     While Not IsNull(DLookup("Database", "MSysObjects", "Name='" & myTbl.Name & "'"))
                         DoEvents
                     Wend
                     ' ricollegamento tabella MsAccess
                     On Error Resume Next
                     DoCmd.TransferDatabase acLink, "Microsoft Access", strDatabase, acTable, myTbl.Name, myTbl.Name
                     ' errore ricollegamento tabelle
                     If Err.Number <> 0 Then
                         MsgBox "Errore ricollegamento tabelle al db:" & vbCrLf & Err.Description, vbCritical, "Error"
                         GoTo endErr0
                     End If
                     On Error GoTo 0
                 End If
            End If
        End If
    Next iInt
    
    endErr0:
    ' close adox
    myDb.Close
    Set myDb = Nothing
    Set myTbl = Nothing
    End Function
    
    Il cui funzionamento si basa, come riportato nelle note:
    ricollega tabelle al db quando il BE si trova nella stessa cartella dell' FE e solo se la cartella del progetto e diversa rispetto all'ultimo ricollegamento delle tabelle
    quindi deve esistere il collegamento fra FE ed BE, al fine di controllare se vi sia diversità fra i path ed in tal caso ricostruire il percorso alle linked-table.
    L'operazione di collegamento alle tabelle linkate avviene attraverso la lettura della tabella di sistema MSysObjects, ricostruendo il nuovo path per ciascuna tabella precedentemente linkata ed è possibile notare tale operazione quando si sposta FE e BE in una nuova directory.

    Come suggerito da Phil non impiegare come path il desktop (che è legato all'utente) ma piuttosto un percorso compatto nella stringa costitutiva in modo da controllare più semplicemente le operazioni che puoi segeuire anche con il debug in base al codice della suddetta funzione.
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Eccolo lì, vedi? (io non avevo scaricato il demo e non avevo guardato tutto il thread quindi non avevo notato cosa)

    willy55 ha scritto:


    ...
    avrai notato che esiste una macro (Autoexec) che viene eseguita all'avvio, ed effettua solo due operazioni:
    - EseguiCodice --> myRicollegaTabelleCurrentFolder
    - ApriMaschera --> Menu_Principale
    ...
    Ti sei accertato che ci sia questa Macro con queste caratteristiche?
    Devi togliere la maschera "Tabella1" (o come l'hai mai chiamata) dall'apertura automatica come avevi fatto tu. La funzione va quindi scritta in un modulo generale (se già non lo era) e non chiamata al Load della maschera.
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Perfetto, con la macro quasi funziona, nel senso che imposto la password ma all'apertura del db, la funzione resituisce l'errore di password non corretta
    ' db connection and source folder database
    ' occurs if db password protected
    On Error Resume Next
    Set myDb = OpenDatabase(strDataBase, False, True)
    If Err.Number = 3031 Then
        ' password request
        Do While Err.Number = 3031
            linkPassword = InputBox(Err.Description & vbCrLf & vbCrLf & "Inseri la Password per il Db: " & Dir(strDataBase, vbArchive), "Password")
            If linkPassword = "" Then Exit Function
            On Error GoTo 0
            On Error Resume Next
            Set myDb = OpenDatabase(strDataBase, False, True, "; PWD=" & linkPassword)
        Loop
    End If
    On Error GoTo 0
    anche se ho impostato la password dell'accdb ad "123" infatti, se la reinserisco nel campo relativo all'errore mi si apre
    ' password default
    Dim linkPassword As String
    linkPassword = "123"
    come potrei evitare di reinserirla e passarla tramite la stringa?
  • Re: [Risolto]Problema tabelle collegate BE-FE

    zio Ken ha scritto:


    Perfetto, con la macro quasi funziona, nel senso che imposto la password ma all'apertura del db, la funzione resituisce l'errore di password non corretta
    ...
    anche se ho impostato la password dell'accdb ad "123" infatti, se la reinserisco nel campo relativo all'errore mi si apre
    ' password default
    Dim linkPassword As String
    linkPassword = "123"
    come potrei evitare di reinserirla e passarla tramite la stringa?
    Non ho capito.
    Puoi inserire la password direttamente nel codice, come hai fatto valorizzando la variabile linkPassword. La funzione poi verifica se con questa password riesce ad accedere al BE; se non ci riesce apre una inputbox per digitarne un'altra.
    Qual è delle due la strada che vuoi seguire?
    Potresti avere problemi se il db deriva da una conversione da un vecchio formato. In questo caso ti conviene "resettare tutto", con un decrypt e poi riapplicare la password.
    Segui bene le indicazioni qui: Encrypt a database by using a database password che è specifico per A2007 (da A2010 in avanti la procedura è cambiata)
    (tieni sempre una copia di sicurezza di FE e BE senza password, sai mai che tra una prova a l'altra non succeda il disastro)
  • Re: [Risolto]Problema tabelle collegate BE-FE

    Phil ti ringrazio per la disponibilità ma pare che prima era un falso allarme, nel senso che, ho inserito la password tramite la inputbox, la schermata di chiudeva e credevo che avesse effettuato il collegamento ma, non è così...la schermata si chiude ma non effettua la connessione...
    l'ho decryptato ed inserito la password "prova" nel BE. Aggiornato il FE con la nuova password
    ' password default
    Dim linkPassword As String
    linkPassword = "prova"
    ma all'apertura, mi si ripropone lo stesso la schermata con la inbox per inserire la password corretta, digito prova, si chiude la schermata come se fosse la password corretta ma, se provo ad aprire la maschera o la tabella mi da l'errore "C:\..."non è un percorso valido. Assicurarsi che il nome del percorso sia corretto e di essere collegati al server in cui si trova il file.
    Ma forse mi sfugge qualcos'altro?
  • Re: [Risolto]Problema tabelle collegate BE-FE

    La funzione è stato realizzata in modo che qualora il BE abbia una password di accesso, dal FE, il tentativo di accedervi determina l'errore 3031 ("Not a valid password" - "Password non valida") con conseguente richiesta di immetterla (nella InputBox) e se questa corretta si apre il DB con l'istruzione:
    
    Set myDb = OpenDatabase(strDatabase, False, True, "; PWD=" & linkPassword)
    
    Nel caso BE e FE vengano spostati in altro folder viene richiesta la password per ciascuna tabella che deve essere linkata.
    Ciò è dovuto alla istruzione:
    
    DoCmd.TransferDatabase acLink, "Microsoft Access", strDatabase, acTable, myTbl.Name, myTbl.Name
    
    in quanto vi è necessita della password per tale operazione.
    Se non si vuole che l'utente debba digitare la password, si deve rivedere il codice sfruttando diverse soluzioni.
    Fra le alternative si può agire sulla proprietà Connect dell'oggetto TableDef, con le diverse implementazioni adottate che si possono ricavare dalle seguenti discussioni:
    access.mvps.org/access/tables/tbl0007.htm
    accessjitsu.com/2015/12/23/microsoft-access-split-databases-connection-strings/
    https://blogs.office.com/en-us/2012/08/03/automatically-relink-microsoft-access-tables/
    https://social.msdn.microsoft.com/Forums/office/en-US/91212577-e23a-4153-80ef-be1da13e6353/cant-relink-tables-if-password-protected-be-database?forum=accessdev

    oppure togliere, temporaneamente, la password in modo da non avere messaggi di richiesta e dopo l'assegnazione della tabella collegata procedere al ripristino della password stessa:
    https://www.access-programmers.co.uk/forums/showthread.php?t=108655
    https://www.devhut.net/2012/09/10/ms-access-vba-change-database-password/

    Con l'occasione si possono vedere ulteriori discussioni sulla tematica in oggetto:
    https://www.iprogrammatori.it/forum-programmazione/access/link-tabelle-con-password-t16044.html
Devi accedere o registrarti per scrivere nel forum
12 risposte