Nota del autor: Esta es la parte 2 de una serie sobre tablas sin DSN en Access.
Puedes revisar la primera parte aquí. Tercera parte aquí. Cuarta parte aquí.

En la publicación anterior hablé sobre el uso de una sola tabla en su base de datos de SQL Server para administrar fácilmente la seguridad, en la publicación de hoy voy a ir un paso más allá y usar esa misma tabla para crear todos los enlaces necesarios necesarios para su aplicación en puesta en marcha.
Use ADODB para recorrer la tabla y crear enlaces
La técnica utiliza un conjunto de registros ADODB para recorrer todos los registros en tblTablePermissions y crear los enlaces al inicio. Almacenamos el nombre y la contraseña del usuario con el enlace, por lo que utilizamos un formulario de inicio de sesión personalizado para almacenar el nombre y la contraseña del usuario, que luego se utilizan para crear los enlaces.
Paso 1: Capture la información de inicio de sesión del usuario y pruebe para ver si pueden conectarse con SQL Server
Aquí está el código que usamos cuando el usuario hace clic en el botón de inicio de sesión en nuestro formulario de inicio de sesión:
Visual Basic Private Sub cmdLogin() If IsNull(Me.txtUserID) Or IsNull(Me.txtPassword) Then MsgBox "You must supply both your user name and password", vbInformation, "Can't Login" Exit Sub End If 'Store login credentials in memory TempVars.Add "UserID", Me.txtUserID.Value TempVars.Add "Password", Me.txtPassword.Value If InStr(1, CurrentProject.Name, "Beta") > 0 Then TempVars.Add "IsBeta", True Else TempVars.Add "IsBeta", False End If If Not OpenMyConnection Then MsgBox "Connection to SQL Server failed, please verify your user name and/or password", vbInformation, "Login Failed" Exit Sub End If RelinkAllTablesADOX End Sub Private Sub cmdLogin() If IsNull(Me.txtUserID) Or IsNull(Me.txtPassword) Then MsgBox "You must supply both your user name and password", vbInformation, "Can't Login" Exit Sub End If 'Store login credentials in memory TempVars.Add "UserID", Me.txtUserID.Value TempVars.Add "Password", Me.txtPassword.Value If InStr(1, CurrentProject.Name, "Beta") > 0 Then TempVars.Add "IsBeta", True Else TempVars.Add "IsBeta", False End If If Not OpenMyConnection Then MsgBox "Connection to SQL Server failed, please verify your user name and/or password", vbInformation, "Login Failed" Exit Sub End If RelinkAllTablesADOX End Sub
Cambiar entre bases de datos beta y de producción
Al incluir el nombre «Beta» en el nombre del proyecto, el código apuntará a la base de datos Beta en lugar de a la de producción. Explicaré más sobre esto más adelante en la serie.
OpenMyConnection
Observe el uso de OpenMyConnection, que uso en mis métodos Easy ADODB. Aquí está la definición de la función:
Public Function OpenMyConnection() As Boolean
On Error GoTo OpenMyConnection_Error
10 If con.State = adStateOpen Then
20 con.Close
30 End If
40 con.ConnectionString = conConnection & "User ID =" & TempVars!UserID & ";Password=" & TempVars!Password
50 con.Open
60 If Not con.State = adStateOpen Then
70 OpenMyConnection = False
80 Else
90 OpenMyConnection = True
100 End If
On Error GoTo 0
Exit Function
OpenMyConnection_Error:
MsgBox "Error " & Err.Number & " Line " & Erl & " (" & Err.Description & ") in procedure OpenMyConnection of Module mdlConnect"
End Function
Procedimiento RelinkAllTablesADOX
Este procedimiento es donde se disparan los fuegos artificiales:
Function RelinkAllTablesADOX() As Boolean
Dim cat As Object
Dim tbl As Object
Dim fLink As Boolean
Dim strSQL As String
Dim strTableName As String
Dim strField As String
Dim strDriver As String
Dim strLocalTableName As String
Dim rs As ADODB.Recordset
Dim strCatalog As String
Const conCatalog As String = "DataBE"
Const conServer As String = "ServerName"
On Error GoTo HandleErr
Set cat = CreateObject("ADOX.Catalog")
cat.ActiveConnection = CurrentProject.Connection
strDriver = "SQL Server"
For Each tbl In cat.Tables
With tbl
' Delete any linked tables
If .Type = "PASS-THROUGH" Then
CurrentDb.TableDefs.Delete .Name
End If
End With
Next tbl
30 strSQL = "Select * from tblTablePermissions Where DontLink = 0"
<a href="https://accessexperts.com/blog/2011/01/21/easy-adodb-recordsets-and-commands-in-access/" target="_blank" rel="noopener noreferrer">OpenMyRecordset</a> rs, strSQL
If TempVars!IsBeta Then
strCatalog = conCatalog & "Beta"
Else
strCatalog = conCatalog
End If
With rs
Do While .EOF = False
strTableName = !Table_Name
35 If IsNull(!Access_Name) Then
strLocalTableName = strTableName
Else
strLocalTableName = !Access_Name
End If
40 fLink = AttachDSNLessTable(strLocalTableName, strTableName, conServer, strCatalog, strDriver, _
TempVars!UserID, TempVars!Password)
50 'Is it a view? If so check if index needed
If Left(strTableName, 2) = "vw" And fLink Then
strField = Nz(DLookup("KeyField", "tblLinkViews", "[View] = '" & strTableName & "'"), "")
If Not strField = "" Then
strSQL = "Create Index IX_" & strLocalTableName & " On " & strLocalTableName & " (" & strField & ") WITH PRIMARY"
CurrentDb.Execute strSQL
End If
End If
.MoveNext
Loop
End With
RelinkAllTablesADOX = fLink
ExitHere:
Set cat = Nothing
Exit Function
HandleErr:
RelinkAllTablesADOX = False
If Not fLink Then
'MsgBox "Linking failed, please contact tech support.", vbInformation, "Error Linking Table"
Resume ExitHere
End If
MsgBox _
Prompt:=Err & ": " & Err.Description, _ Title:="Error in RelinkAllTablesADOX"
Resume ExitHere
End Function
Solo enlazar tablas donde DontLink = 0
Observe que en la línea 30 anterior solo vinculamos tablas que tienen DontLink configurado t Falso. Quizás se pregunte por qué nos molestamos incluso en colocar una tabla en tblTablePermissions cuando no se usa en Access como tabla vinculada. Recuerde en mi primera publicación que lo usamos para configurar la seguridad de todas las tablas, y si alguna vez es necesario usar ADODB e ir directamente a la tabla en SQL Server a través de nuestro código de access o consulta de paso, entonces necesitamos esa tabla listada en tblTablePermissions.
¿View necesita índice?
En la línea 50 anterior, el código verifica si la tabla que se está vinculando es una vista y, de ser así, crea el índice en Access utilizando una tabla local llamada tblLinkViews. Probablemente podría eliminar este concepto en su código y simplemente agregar otra columna a tblTablePermissions llamada ViewIndex, luego simplemente use! ViewIndex en el código anterior para leer la sintaxis SQL en strSQL.
Cambiar el nombre de la tabla del servidor SQL?
Observe que en la línea 35 anterior, el sistema usará un nombre diferente para la tabla de Access si así se especifica. Esta técnica puede ser útil cuando se trata de una aplicación heredada y desea utilizar nombres en SQL Server que se adapten mejor a usted, pero no se pueden usar en Access debido a un código heredado.
AttachDSNLess Table Code
El procedimiento anterior llama a este sub para hacer realmente la vinculación:
'Note: Code adapted from <a href="http://support.microsoft.com/kb/892490">http://support.microsoft.com/kb/892490</a> Function AttachDSNLessTable(stLocalTableName As String, stRemoteTableName As String, stServer As String, stDatabase As String, strDriver As String, _ Optional stUserName As String, Optional stPassword As String) As Boolean 10 On Error GoTo AttachDSNLessTable_Err Dim td As TableDef Dim stConnect As String 20 If stLocalTableName = "" Then 30 stLocalTableName = stRemoteTableName 40 End If 50 Application.Echo True, "Linking table " & stLocalTableName 'Stop '//WARNING: This will save the username and the password with the linked table information. 60 stConnect = "ODBC;DRIVER=" & strDriver & ";SERVER=" & stServer & ";DATABASE=" & stDatabase & ";UID=" & stUserName & ";PWD=" & stPassword 70 Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, stConnect) 80 CurrentDb.TableDefs.Append td 90 AttachDSNLessTable = True 100 Exit Function AttachDSNLessTable_Err: 110 If Err.Number = 3265 Or Err.Number = 3011 Then 'Table does not exist, continue anyway 120 Resume Next 130 End If 140 AttachDSNLessTable = False 150 Stop 160 MsgBox "AttachDSNLessTable encountered an unexpected error: " & Err.Description End Function
En mi próxima publicación, hablaré sobre cómo destruir los enlaces cuando salgas de la aplicación.


Deja tu comentario