Строка подключения для открытия связанной таблицы Access -> SQL server (vba) - PullRequest
2 голосов
/ 22 марта 2012

Я искал ответ, так как есть много похожих вопросов, но не нашел этот конкретный случай.

У меня есть сервер SQL и файл доступа (внешний интерфейс). Этот файл Access содержит связанные таблицы, связанные с сервером SQL, и каждый раз, когда я пытаюсь открыть одну таблицу, появляется запрос на ввод имени пользователя и пароля.

ОК, это прекрасно, так как это (почти) поведение, которое я хочу.

Кроме того, есть локальная таблица, в которой находятся пользователь / пароль с зашифрованными паролями. Каждый раз, когда пользователь открывает файл, его / ее пароль дешифруется, и я хотел бы открыть соединение, поэтому связанные таблицы не будут запрашивать пропуск.

Кто-нибудь знает, как закодировать это соединение?

Заранее спасибо!

Ответы [ 2 ]

5 голосов
/ 22 марта 2012

Я думаю, что вам нужно "DSN-LESS соединение" . Я делал нечто подобное в прошлом. По сути, при входе пользователя в систему вы заново связываете таблицы, используя строку подключения, созданную на основе учетных данных пользователя.

Взгляните на этот предыдущий ТА вопрос для более подробной информации.

Кроме того, вот несколько подпрограмм, которые я использовал в прошлом, которые вы можете использовать \ изменять. Вызовите их из процесса входа в систему.

Public Function RelinkDSNTables( _
      ByVal ServerName As String, _
      ByVal DatabaseName As String, _
      ByVal UserName As String, _
      ByVal Password As String) As Boolean
On Error GoTo Err_Handler

Dim dsn As String
dsn = GetDSNLink(ServerName, DatabaseName, UserName, Password)
Dim td As TableDef
Dim db As DAO.Database
Set db = CurrentDb
Dim rst As ADODB.Recordset

'Get a list of tables that need to be relinked'
If GetLocalRecordSet(rst, "SELECT * FROM TableMapping") < 1 Then
   Err.Raise 1000, "Missing Tables!", "Missing Table Mappings!"
End If

Dim fNeedToRefresh As Boolean

'See if we actually need to relink the tables'
For Each td In db.TableDefs
   If td.Connect <> vbNullString Then
      If td.Connect <> dsn Then
         fNeedToRefresh = True
         Exit For
      End If
   End If
Next td

If fNeedToRefresh = False Then
   RelinkDSNTables = True
   GoTo Err_Handler
End If

'Drop linked table in Access'
For Each td In CurrentDb.TableDefs
   If td.Connect <> vbNullString Then
      CurrentDb.TableDefs.Delete td.Name
   End If
Next td

'Create new linked table using new DSN'
rst.MoveFirst
Do Until rst.EOF
   Set td = db.CreateTableDef(rst!LocalTableName, dbAttachSavePWD, rst!RemoteTableName, dsn)
   db.TableDefs.Append td
   rst.MoveNext
Loop

'Because I am paranoid, refresh the link'
db.TableDefs.Refresh
For Each td In db.TableDefs
   If td.Connect <> "" Then td.RefreshLink
Next td

RelinkDSNTables = True

Err_Handler:
   If Err.Number = 3011 Then
      'Happens if user does not have permission in SQL Server; Nothing to see here, move along'
      Err.Clear
      Resume Next
   ElseIf Err.Number = 3010 Then
      'already exists; should not occur, but if it does eat the exception and move on'
      Err.Clear
      Resume Next
   ElseIf Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function

Private Function GetDSNLink( _
      ByVal ServerName As String, _
      ByVal DatabaseName As String, _
      ByVal UserName As String, _
      ByVal Password As String) As String
On Error GoTo Err_Handler

If ServerName = "" Or DatabaseName = "" Then
   Err.Raise -1220, "Missing Server \ DB", _
      "Unable to refresh table links because you are missing the server or database name!"
End If

Dim dsnLink As String

If UserName = "" Then
   'trusted connection'
   dsnLink = "ODBC;DRIVER=SQL Server;SERVER=" & ServerName & _
            ";DATABASE=" & DatabaseName & ";Trusted_Connection=Yes"
Else
   'MixedMode connection'
     '//WARNING: This will save the username and the password with the linked table information.
   dsnLink = "ODBC;DRIVER=SQL Server;SERVER=" & ServerName & _
            ";DATABASE=" & DatabaseName & ";UID=" & UserName & ";PWD=" & Password
End If

GetDSNLink = dsnLink

Err_Handler:
   If Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function

Редактировать: добавлен пример функции GetLocalRecordSet

Public Function GetLocalRecordSet(ByRef rs As ADODB.Recordset, ByVal sql As String) As Long
On Error GoTo Err_Handler

If sql = vbNullString Then
   Err.Raise vbObjectError + 1001, _
      "Empty SQL String", "Empty SQL String Passed to GetLocalRecordset Function!"
End If

Set rs = New ADODB.Recordset

rs.Open sql, CurrentProject.Connection, adOpenKeyset, adLockOptimistic

If rs Is Nothing Then
   GetLocalRecordSet = -1
   GoTo Err_Handler
End If

If rs.State = adStateOpen Then
   If Not rs.EOF Then
      rs.MoveLast
      GetLocalRecordSet = rs.RecordCount                 'store number of records
      rs.MoveFirst
   Else
      GetLocalRecordSet = 0
   End If
Else
   GetLocalRecordSet = -2
End If

Err_Handler:
   If Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function
0 голосов
/ 22 марта 2012

Вы можете написать код для программного подключения к базе данных SQL с именем пользователя / паролем, хранящимся в вашей локальной таблице. Это должно происходить при загрузке приложения Access (например, с помощью макроса Autoexec).

Вы можете прочитать о макросе Autoexec здесь: http://www.vb123.com/toolshed/05_map/ch04_autoexec.htm

Итак, у вас есть функция, например, OpenConnection (), который вызывается из макроса Autoexec при запуске приложения. Любые последующие открытия таблицы не должны запрашивать пароль.

Я не уверен, будет ли это работать с SQL-сервером. Надеюсь, так и будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...