Dicas do OsmarJr

Revinculando tabelas via código


(P) No meu front-end uso diversas tabelas vinculadas, de diversos bancos de dados back-end. Como posso ter certeza que todas as tabelas sejam conectadas quando o front-end é aberto?

Autor: Dev Hashish

(R) Vove pode percorrer a coleção Tabledefs para ver quais tabelas estão com a propriedade Connect ativa. Se Connect estiver preenchida, reconecte a tabela usando o banco de dados especificado na string.

Aqui está uma função (fRefreshLinks) que deve ser executada na abertura do banco de dados. A função verifica cada tabela no banco de dados no qual o código está sendo executado e tenta localizar a fonte de dados para a tabela se a propriedade Connect estiver preenchida.

Se o banco de dados especificado para a tabela vinculada não estiver presente, o código abre a caixa de diálogo GetOpenFileName para que o usuário possa selecionar uma fonte alternativa.

Nota28-Oct-2005 19:59plicativo.

 

'***************** Início do Código ***************
' Este código foi originalmente escrito por Dev Ashish.
' Ele não deve ser alterado ou distribuído,
' exceto como parte de um aplicativo.
' Use-o livremente em qualquer aplicativo,
'28-Oct-2005  19:59Código cortesia de 
' 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("Tem certeza que quer reconectar todas as tabelas Access?", _
            vbQuestion + vbYesNo, "Por favor, confirme...") = vbNo Then Err.Raise cERR_USERCANCEL

    'Primeiro pega todas as tabelas vinculadas em uma coleção
    Set collTbls = fGetLinkedTables

    'agora vinculo todas elas
    Set dbCurr = CurrentDb

    strMsg = "Deseja especificar um caminho diferente para as tabelas Access?"
    
    If MsgBox(strMsg, vbQuestion + vbYesNo, "Fonte de dados alternativa...") = vbYes Then
        strNewPath = fGetMDBName("Por favor, selecione a nova fonte de dados.")
    Else
        strNewPath = vbNullString
    End If

    For i = collTbls.Count To 1 Step -1
        strDBPath = fParsePath(collTbls(i))
        strTbl = fParseTable(collTbls(i))
        varRet = SysCmd(acSysCmdSetStatus, "Vinculando '" & strTbl & "'....")
        If Left$(strDBPath, 4) = "ODBC" Then
            'Tabelas ODBC
            'Tabelas ODBC são tratadas em separado
           ' Set tdfLocal = dbCurr.TableDefs(strTbl)
           ' With tdfLocal
           '     .Connect = pcCONNECT
           '     .RefreshLink
           '     collTbls.Remove (strTbl)
           ' End With
        Else
            If strNewPath <> vbNullString Then
                'Tenta desta forma primeiro
                strDBPath = strNewPath
            Else
                If Len(Dir(strDBPath)) = 0 Then
                    'O arquivo não existe. Chama GetOpenFileName
                    strDBPath = fGetMDBName("'" & strDBPath & "' não encontrado.")
                    If strDBPath = vbNullString Then
                        'O usuário clicou em Cancelar
                        Err.Raise cERR_USERCANCEL
                    End If
                End If
            End If

            'O banco de dados back-end existe
            'Colocado aqui já que podemos ter
            'tabelas de diversas fontes de dados
            Set dbLink = DBEngine(0).OpenDatabase(strDBPath)

            'Verifica se a tabela está presente em in dbLink
            strTbl = fParseTable(collTbls(i))
            If fIsRemoteTable(dbLink, strTbl) Then
                'Tudo em ordem. Revincula.
                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 "Todas as tabelas Access foram reconectadas com sucesso.", _
            vbInformation + vbOKOnly, _
            "Sucesso"

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 "Nenhum banco de dados foi especificado. Impossível vincular as tabelas.", _
                    vbCritical + vbOKOnly, _
                    "Erro ao recuperar vínculos."
            Resume fRefreshLinks_End
        Case cERR_NOREMOTETABLE:
            MsgBox "A tabela '" & strTbl & "' não foi encontrada no banco de dados." & _
                    vbCrLf & dbLink.Name & ". Impossível recuperar vínculos.", _
                    vbCritical + vbOKOnly, _
                    "Erro ao r4ecuperar vínculos."
            Resume fRefreshLinks_End
        Case Else:
            strMsg = "Informação de erro..." & vbCrLf & vbCrLf
            strMsg = strMsg & "Função: fRefreshLinks" & vbCrLf
            strMsg = strMsg & "Descrição: " & Err.Description & vbCrLf
            strMsg = strMsg & "Erro nº: " & Format$(Err.Number) & vbCrLf
            MsgBox strMsg, vbOKOnly + vbCritical, "Erro"
            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, _
                    "Bancos Access(*.mdb;*.mda;*.mde;*.mdw) ", _
                    "*.mdb; *.mda; *.mde; *.mdw")
    strFilter = ahtAddFilterItem(strFilter, _
                    "Todos os arquivos (*.*)", _
                    "*.*")

    fGetMDBName = ahtCommonFileOpenSave(Filter:=strFilter, _
                                OpenFile:=True, _
                                DialogTitle:=strIn, _
                                Flags:=ahtOFN_HIDEREADONLY)
End Function

Function fGetLinkedTables() As Collection
'Devolve todas as tabelas vinculadas
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 tratado separadamente
                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
'***************** Final do Código ***************
Home

Contato | Copyright©Osmar José Correia Júnior | 24-Nov-2005 18:23