Curitiba, Paraná, Brasil
+55 41 98418-8866
jose.coltro@jcoltro.com.br

Usando MS-Access com tabelas SQL Server sem necessidade de criar um DSN

"Nós confiamos em Deus."

Usando MS-Access com tabelas SQL Server sem necessidade de criar um DSN

Uma das dificuldades enfrentadas pelo desenvolvedor, após criar um front-end MS-Access que usa tabelas vinculadas, é explicar para o pessoal responsável pela instalação nas estações dos usuários, a necessidade de criar um DSN (Data Source Name) para acesso ao banco de dados.

É mais um motivo para torcerem o nariz e dizerem “eu falei que não deviam usam MS-Access”.

Recentemente eu encontrei uma solução que nos livra do DSN e da pouca receptividade de alguns para soluções baseadas em MS-Access. Por enquanto, até onde sei, funciona apenas se as tabelas forem SQL Server. A solução que encontrei está em:
https://docs.microsoft.com/pt-br/office/troubleshoot/access/create-dsn-less-connection-linkted-table

Dos dois métodos lá descritos, utilizei a criando da função AttachDSNLessTable:

'//Name : AttachDSNLessTable
'//Purpose : Vincula tabela do SQL Server sem DSN
'//Parameters
'// stLocalTableName: Nome da tabela no front-end MS Access
'// stRemoteTableName: Nome da tabela no banco SQL Server
'// stServer: Nome do servidor SQL Server que armazena a tabela
'// stDB: Nome do banco de dados no servidor SQL Server
'// stUsername: Nome do usuário no banco de dados SQL Server (deixe em branco para usar Trusted Authentication )
'// stPassword: Senha do usuário no SQL Server
Function AttachDSNLessTable(stLocalTableName As String, stRemoteTableName As String, stServer As String, stDB As String, Optional stUsername As String, Optional stPassword As String)
  On Error GoTo AttachDSNLessTable_Err
  Dim td As TableDef, stConnect As String
  For Each td In CurrentDb.TableDefs
    If td.Name = stLocalTableName Then
      CurrentDb.TableDefs.Delete stLocalTableName
    End If
  Next
  If Len(stUsername) = 0 Then
    '//Usará Trusted Authentication se o nome do usuário não for fornecido.
    stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDB & ";Trusted_Connection=Yes"
  Else
    '//CUIDADO: Isto salvará o nome do usuário do banco de dados e sua senha nas informações da tabela vinculada.
    stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDB & ";UID=" & stUsername & ";PWD=" & stPassword
  End If
  Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, stConnect)
  CurrentDb.TableDefs.Append td
  AttachDSNLessTable = True
  Exit Function
AttachDSNLessTable_Err:
  AttachDSNLessTable = False
  MsgBox "A função de vinculação de tabelas sem DSN encontrou um erro inesperado: " & Err.Description
End Function

Para facilitar a rotina de abertura do front-end, criei uma tabela interna no MS-Access e nela coloquei todos os nomes de tabelas a serem vinculadas, da forma que a função espera receber (nome atribuído à tabela no front-end e nome da tabela no banco SQL Server). Para finalizar, coloquei a chamada da função dentro de um loop que percorre os registros da tabela que acabei de citar:

...
Dim rs_tabelas As Recordset, tot_tabelas As Integer
Set rs_tabelas = CurrentDb.OpenRecordset("SELECT * FROM tblODBCDataSources;")
If rs_tabelas.EOF Then
    MsgBox "Impossível vincular as tabelas do banco de dados. Acione o suporte.", vbCritical, "SCF"
    DoCmd.Quit
Else
    rs_tabelas.MoveLast: rs_tabelas.MoveFirst
End IfFor tot_tabelas = 1 To rs_tabelas.RecordCount
    If AttachDSNLessTable(rs_tabelas("LOCALTABLENAME"), rs_tabelas("ODBCTABLENAME"), "brcwbsql", "scf", "scf_user", "scf@rauco!!") Then
    Else
      MsgBox "Impossível vincular a tabela de banco de dados " & rs_tabelas("LOCALTABLENAME") & ". Impossível prosseguir. Acione o suporte.", vbCritical, "SCF"
    End If
    rs_tabelas.MoveNext
Next
...

Desta forma, conseguimos simplificar o processo de “instalação” do front-end. Basta copiar o arquivo .accdb ou .accde para o computador do futuro usuário.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *