Condividi tramite

Errore con il relink automatico delle tabelle access

Anonimo
2017-11-07T19:16:46+00:00

Buonasera a tutti,

sto lavorando ad un database con BE e FE e sebbene mi renda conto di essermi addentrato in una situazione abbastanza complicata (vista la mia poca conoscenza VBA) ho voluto provare a fare il relink delle tabelle automatico tramite vba, spronato anche dal codice che ho trovato in libera distribuzione su questo sito e che metto in calce. 

Il primo problema che sorge al debug è il seguente messaggio di errore alla riga che vi ho evidenziato in rosso:

"Errore di compilazione: Previsto tipo definito dall'utente e non progetto."

Ho pensato che fosse un problema di riferimenti e ho provato ad inserire la libreria DAO 3.6 ma chiaramente il vba mi dice che la libreria è già presente, poi se provo a spostare il progetto su un sistema a 64bit trovo dei problemi diversi, ma vorrei soffermarmi solo sull'errore di cui sopra perchè è un progetto per un'ambiente 32bit.

L'insieme di funzioni sotto richiamano un'altra funzione "GetOpenFileName" che apre la finestra di dialogo dove selezionare la nuova posizione del BE e che al debug non mi da errore.

PS.: Ci tengo a riportare i commenti originali cosi come li ha messi l'autore.

Spero di essere stato chiaro nell'esposizione e ringrazio in anticipo tutti coloro che vorranno aiutarmi.

Buona serata 

'***************** Code Start ***************

' This code was originally written by Dev Ashish.

' It is not to be altered or distributed,

' except as part of an application.

' You are free to use it in any application,

' provided the copyright notice is left unchanged.

'

' Code Courtesy of

' Dev Ashish

'

Function fRefreshLinks() As Boolean

Dim strMsg As String, collTbls As Collection

Dim i As Integer, strDBPath As String, strTbl As String

Dim dbCurr As Database, dbLink As Database

Dim tdfLocal As TableDef

Dim varRet As Variant

Dim strNewPath As String

Const cERR_USERCANCEL = vbObjectError + 1000

Const cERR_NOREMOTETABLE = vbObjectError + 2000

    On Local Error GoTo fRefreshLinks_Err

    If MsgBox("Are you sure you want to reconnect all Access tables?", _

            vbQuestion + vbYesNo, "Please confirm...") = vbNo Then Err.Raise cERR_USERCANCEL

    'First get all linked tables in a collection

    Set collTbls = fGetLinkedTables

    'now link all of them

    Set dbCurr = CurrentDb

    strMsg = "Do you wish to specify a different path for the Access Tables?"

    If MsgBox(strMsg, vbQuestion + vbYesNo, "Alternate data source...") = vbYes Then

        strNewPath = fGetMDBName("Please select a new datasource")

    Else

        strNewPath = vbNullString

    End If

    For i = collTbls.Count To 1 Step -1

        strDBPath = fParsePath(collTbls(i))

        strTbl = fParseTable(collTbls(i))

        varRet = SysCmd(acSysCmdSetStatus, "Now linking '" & strTbl & "'....")

        If Left$(strDBPath, 4) = "ODBC" Then

            'ODBC Tables

            'ODBC Tables handled separately

           ' Set tdfLocal = dbCurr.TableDefs(strTbl)

           ' With tdfLocal

           '     .Connect = pcCONNECT

           '     .RefreshLink

           '     collTbls.Remove (strTbl)

           ' End With

        Else

            If strNewPath <> vbNullString Then

                'Try this first

                strDBPath = strNewPath

            Else

                If Len(Dir(strDBPath)) = 0 Then

                    'File Doesn't Exist, call GetOpenFileName

                    strDBPath = fGetMDBName("'" & strDBPath & "' not found.")

                    If strDBPath = vbNullString Then

                        'user pressed cancel

                        Err.Raise cERR_USERCANCEL

                    End If

                End If

            End If

            'backend database exists

            'putting it here since we could have

            'tables from multiple sources

            Set dbLink = DBEngine(0).OpenDatabase(strDBPath)

            'check to see if the table is present in dbLink

            strTbl = fParseTable(collTbls(i))

            If fIsRemoteTable(dbLink, strTbl) Then

                'everything's ok, reconnect

                Set tdfLocal = dbCurr.TableDefs(strTbl)

                With tdfLocal

                    .Connect = ";Database=" & strDBPath

                    .RefreshLink

                    collTbls.Remove (.Name)

                End With

            Else

                Err.Raise cERR_NOREMOTETABLE

            End If

        End If

    Next

    fRefreshLinks = True

    varRet = SysCmd(acSysCmdClearStatus)

    MsgBox "All Access tables were successfully reconnected.", _

            vbInformation + vbOKOnly, _

            "Success"

fRefreshLinks_End:

    Set collTbls = Nothing

    Set tdfLocal = Nothing

    Set dbLink = Nothing

    Set dbCurr = Nothing

    Exit Function

fRefreshLinks_Err:

    fRefreshLinks = False

    Select Case Err

        Case 3059:

        Case cERR_USERCANCEL:

            MsgBox "No Database was specified, couldn't link tables.", _

                    vbCritical + vbOKOnly, _

                    "Error in refreshing links."

            Resume fRefreshLinks_End

        Case cERR_NOREMOTETABLE:

            MsgBox "Table '" & strTbl & "' was not found in the database" & _

                    vbCrLf & dbLink.Name & ". Couldn't refresh links", _

                    vbCritical + vbOKOnly, _

                    "Error in refreshing links."

            Resume fRefreshLinks_End

        Case Else:

            strMsg = "Error Information..." & vbCrLf & vbCrLf

            strMsg = strMsg & "Function: fRefreshLinks" & vbCrLf

            strMsg = strMsg & "Description: " & Err.Description & vbCrLf

            strMsg = strMsg & "Error #: " & Format$(Err.Number) & vbCrLf

            MsgBox strMsg, vbOKOnly + vbCritical, "Error"

            Resume fRefreshLinks_End

    End Select

End Function

Function fIsRemoteTable(dbRemote As Database, strTbl As String) As Boolean

Dim tdf As TableDef

    On Error Resume Next

    Set tdf = dbRemote.TableDefs(strTbl)

    fIsRemoteTable = (Err = 0)

    Set tdf = Nothing

End Function

Function fGetMDBName(strIn As String) As String

'Calls GetOpenFileName dialog

Dim strFilter As String

    strFilter = ahtAddFilterItem(strFilter, _

                    "Access Database(*.mdb;*.mda;*.mde;*.mdw) ", _

                    "*.mdb; *.mda; *.mde; *.mdw")

    strFilter = ahtAddFilterItem(strFilter, _

                    "All Files (*.*)", _

                    "*.*")

    fGetMDBName = ahtCommonFileOpenSave(Filter:=strFilter, _

                                OpenFile:=True, _

                                DialogTitle:=strIn, _

                                Flags:=ahtOFN_HIDEREADONLY)

End Function

Function fGetLinkedTables() As Collection

'Returns all linked tables

    Dim collTables As New Collection

    Dim tdf As TableDef, db As Database

    Set db = CurrentDb

    db.TableDefs.Refresh

    For Each tdf In db.TableDefs

        With tdf

            If Len(.Connect) > 0 Then

                If Left$(.Connect, 4) = "ODBC" Then

                '    collTables.Add Item:=.Name & ";" & .Connect, KEY:=.Name

                'ODBC Reconnect handled separately

                Else

                    collTables.Add Item:=.Name & .Connect, Key:=.Name

                End If

            End If

        End With

    Next

    Set fGetLinkedTables = collTables

    Set collTables = Nothing

    Set tdf = Nothing

    Set db = Nothing

End Function

Function fParsePath(strIn As String) As String

    If Left$(strIn, 4) <> "ODBC" Then

        fParsePath = Right(strIn, Len(strIn) _

                        - (InStr(1, strIn, "DATABASE=") + 8))

    Else

        fParsePath = strIn

    End If

End Function

Function fParseTable(strIn As String) As String

    fParseTable = Left$(strIn, InStr(1, strIn, ";") - 1)

End Function

'***************** Code End ***************

Microsoft 365 e Office | Access | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

Risposta accettata dall'autore della domanda

Anonimo
2017-11-07T19:39:31+00:00

ciao Michele.

di fronte a cotanto autore mi inchino, ma ti consiglio questa soluzione :

https://answers.microsoft.com/it-it/msoffice/forum/msoffice\_access-mso\_win10-mso\_365hp/problemi-fe-tabelle-collegate-risolto/97887864-cabe-4fe7-ba53-28dad97bb9be

prendi la routine che trovi nell'ultimo post del link qui sopra.

Per collegare eo/o ricollegare le tabelle trovi molte soluzioni, quella che ti suggerisco è semplice non si appoggia ad api e/o ad oggetti esterni e tutti i problemi ad esso connessi circa le declare in ambiente 64 bit.

ciao, Sandro.

La risposta è stata utile?

1 persona ha trovato utile questa risposta.
0 commenti Nessun commento

1 risposta aggiuntiva

Ordina per: Più utili
  1. Anonimo
    2017-11-14T12:24:51+00:00

    Ciao Sandro;

    Perdonami il ritardo nel rispondere ma ho voluto risolvere prima il tutto per poi darti un feedback completo.

    La tua soluzione funziona benissimo, ma io cercavo qualcosa che rilevasse le tabelle scollegate per poi propormi il filedialog per la scelta del database backend, per cui ho provato ad integrare le due routine, quella proposta da me  in questo post è quella che mi hai consigliato tu. Poi non riuscendoci ho optato di "giocare" con la gestione errori, che all'errore 3024 fa partire la tua routine, che sebbene sia una soluzione un Po rudimentale mi rende abbastanza soddisfatto per come funziona.

    Grazie mille per la tua disponibilitá.

    Saluti Michele.

    La risposta è stata utile?

    0 commenti Nessun commento