Olá pessoal,
Resolvi uma questão que incomodava há muito tempo e compartilho agora com o grupo a solução e está aberto a sugestões.
No meu sistema, multiusuário, o backend ficava sempre conectado, porque no frontend o formulário principal / inicial, lista as atividades destinadas à cada usuário. O Form era Bound com DAO numa Consulta (Query) devido a extensão e complexidade do SQL.
Então, através de recordset ADODB e Consulta (Query) consegui popular o Form Unbound, listar as atividades e o backend permanecer desconectado do frontend, aproveitado toda a facilidade da Query e ainda ficou mais rápido.
No lugar da QueryName pode ser uma expressão SQL.
Segue a solução:
Public Function fncADOconnection(ByVal QueryName As String, Optional FieldSort As String = "") As ADODB.Recordset
' by Fernando Lucas, 2023/12
On Error GoTo trataErro
Dim cnAdo As ADODB.Connection
Dim rsAdo As ADODB.Recordset
Set cnAdo = CurrentProject.AccessConnection
Set rsAdo = cnAdo.Execute(QueryName)
rsAdo.Sort = FieldSort
Set rsAdo.ActiveConnection = Nothing
Set fncADOconnection = rsAdo
cnAdo.Close
Sair:
Set rsAdo = Nothing: Set cnAdo = Nothing
Exit Function
trataErro:
MsgBox "Erro: " & Err.Number & vbCrLf & Err.Description, vbCritical, "Aviso", Err.HelpFile, Err.HelpContext
Resume Sair:
End Function
Depois coloquei no Form principal / inicial, no evento OnLoad ou em outro mais adequado:
Private Sub Form_Load()
' para ordem (opcional) decrescente: “FieldSort” & " DESC"
Set Me.Recordset = fncADOconnection("QueryName”, “FieldSort”)
Para ter certeza que o Form fique desvinculado uso o evento:
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Me.RecordSource = ""
Set Me.Recordset = Nothing
End Sub
Caso a Query (Consulta) tenha algum parâmetro/filtro dinâmico ( como variável ou referência) é necessário transformá-lo em uma Public Function, exemplo:
Public Function fncIdUsuario() As Long
On Error Resume Next
fncIdUsuario = [TempVars]![IdUsuario].Value
End Function
Obs.: Não há necessidade de transformar os parâmetros/filtros estáticos como: True, Null ....
Como o Form populado é Unbound e somente leitura, para atualiza-lo , é necessário que nos Forms que modifiquem os dados, por exemplo, num Form secundário, ao ser fechado, atualize o Form principal / inicial. No meu caso utilizo 2 eventos (poderia ser apenas um):
No evento num Form secundário, por exemplo, o de distribuição das atividades:
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Me.RecordSource = ""
Set Forms!seuFormName.Recordset = fncADOconnection("QueryName")
End Sub
Private Sub Form_Close()
On Error Resume Next
Form_seuFormName.Requery
End Sub
No Form principal / inicial, também coloquei um botão para atualizar a lista das atividades. Usei o evento OnClick do botão btnAtualizar:
Private Sub btnAtualizar_Click()
On Error Resume Next
Set Me.Recordset = fncADOconnection("QueryName")
Me.Form.Requery
End Sub
E por fim, para popular ListBox ou ComboBox, Unbound, é só usar:
Set Me!seuListBox.Recordset = fncADOconnection("QueryName")
Set Me!seuComboBox.Recordset = fncADOconnection("QueryName")
Aberto a comentários e sugestões.
Obrigado,
Fernando Lucas
Resolvi uma questão que incomodava há muito tempo e compartilho agora com o grupo a solução e está aberto a sugestões.
No meu sistema, multiusuário, o backend ficava sempre conectado, porque no frontend o formulário principal / inicial, lista as atividades destinadas à cada usuário. O Form era Bound com DAO numa Consulta (Query) devido a extensão e complexidade do SQL.
Então, através de recordset ADODB e Consulta (Query) consegui popular o Form Unbound, listar as atividades e o backend permanecer desconectado do frontend, aproveitado toda a facilidade da Query e ainda ficou mais rápido.
No lugar da QueryName pode ser uma expressão SQL.
Segue a solução:
Public Function fncADOconnection(ByVal QueryName As String, Optional FieldSort As String = "") As ADODB.Recordset
' by Fernando Lucas, 2023/12
On Error GoTo trataErro
Dim cnAdo As ADODB.Connection
Dim rsAdo As ADODB.Recordset
Set cnAdo = CurrentProject.AccessConnection
Set rsAdo = cnAdo.Execute(QueryName)
rsAdo.Sort = FieldSort
Set rsAdo.ActiveConnection = Nothing
Set fncADOconnection = rsAdo
cnAdo.Close
Sair:
Set rsAdo = Nothing: Set cnAdo = Nothing
Exit Function
trataErro:
MsgBox "Erro: " & Err.Number & vbCrLf & Err.Description, vbCritical, "Aviso", Err.HelpFile, Err.HelpContext
Resume Sair:
End Function
Depois coloquei no Form principal / inicial, no evento OnLoad ou em outro mais adequado:
Private Sub Form_Load()
' para ordem (opcional) decrescente: “FieldSort” & " DESC"
Set Me.Recordset = fncADOconnection("QueryName”, “FieldSort”)
Para ter certeza que o Form fique desvinculado uso o evento:
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Me.RecordSource = ""
Set Me.Recordset = Nothing
End Sub
Caso a Query (Consulta) tenha algum parâmetro/filtro dinâmico ( como variável ou referência) é necessário transformá-lo em uma Public Function, exemplo:
Public Function fncIdUsuario() As Long
On Error Resume Next
fncIdUsuario = [TempVars]![IdUsuario].Value
End Function
Obs.: Não há necessidade de transformar os parâmetros/filtros estáticos como: True, Null ....
Como o Form populado é Unbound e somente leitura, para atualiza-lo , é necessário que nos Forms que modifiquem os dados, por exemplo, num Form secundário, ao ser fechado, atualize o Form principal / inicial. No meu caso utilizo 2 eventos (poderia ser apenas um):
No evento num Form secundário, por exemplo, o de distribuição das atividades:
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Me.RecordSource = ""
Set Forms!seuFormName.Recordset = fncADOconnection("QueryName")
End Sub
Private Sub Form_Close()
On Error Resume Next
Form_seuFormName.Requery
End Sub
No Form principal / inicial, também coloquei um botão para atualizar a lista das atividades. Usei o evento OnClick do botão btnAtualizar:
Private Sub btnAtualizar_Click()
On Error Resume Next
Set Me.Recordset = fncADOconnection("QueryName")
Me.Form.Requery
End Sub
E por fim, para popular ListBox ou ComboBox, Unbound, é só usar:
Set Me!seuListBox.Recordset = fncADOconnection("QueryName")
Set Me!seuComboBox.Recordset = fncADOconnection("QueryName")
Aberto a comentários e sugestões.
Obrigado,
Fernando Lucas