Pergunta

Há alguma literatura disponível em troca de especialistas e em República de Teck Sobre o uso da propriedade ComboBox.RecordSet para preencher um ComboBox em um formulário de acesso.

Esses controles geralmente são preenchidos com uma string "Select *" nas propriedades 'RowSource' do controle, referenciando uma tabela ou consulta disponível no lado do cliente do aplicativo. Quando preciso exibir os dados laterais do servidor em um ComboBox, crio uma tabela local temporária e importo registros solicitados. Isso consome tempo, especialmente com tabelas grandes.

Ser capaz de usar um RecordSet para preencher um controle de ComboBox permitiria ao usuário exibir diretamente dados do lado do servidor.

Inspirado nos 2 exemplos anteriores, escrevi algum código da seguinte maneira:

Dim rsPersonne as ADODB.recordset
Set rsPersonne = New ADODB.Recordset

Set rsPersonne.ActiveConnection = connexionActive
rsPersonne.CursorType = adOpenDynamic
rsPersonne.LockType = adLockPessimistic
rsPersonne.CursorLocation = adUseClient

rsPersonne.Open "SELECT id_Personne, nomPersonne FROM Tbl_Personne"

fc().Controls("id_Personne").Recordset = rsPersonne

Onde:

  • ConnexionActive: é minha conexão ADO permanente com meu servidor de banco de dados
  • fc (): é meu formulário atual/ativo
  • Controles ("id_personne"): é o controle combos
  • Versão de acesso em 2003

Infelizmente, não funciona!

No modo de depuração, posso verificar se o RecordSet é criado corretamente, com colunas e dados solicitados e adequadamente associado ao controle ComboBox. Infelizmente, quando exibo o formulário, continuo recebendo um ComboBox vazio, sem registros! Qualquer ajuda é muito apreciada.

EDITAR:

Essa propriedade RecordSet está realmente disponível para o objeto ComboBox específico, não para o objeto de controle padrão, e fiquei muito surpreso ao descobri -lo há alguns dias. Eu já tentei usar a função de retorno de chamada da Combobox ou preencher uma lista com o método "additem" do ComboBox. Tudo isso consome tempo.

Foi útil?

Solução 3

Encontrei o truque ... a propriedade "RowSourcetype" do controle ComboBox deve ser definida como "tabela/list". A exibição agora está ok, mas agora tenho outro problema com a memória. Como eu uso esses registros ADO em meus formulários, o uso da memória do acesso está aumentando cada vez que navego em um formulário. A memória também não é liberada, interrompendo a navegação ou fechando o formulário, tornando o MS Access instável e congelando regularmente. Vou abrir uma pergunta se não puder resolver este problema

Outras dicas

Como foi dito, você deve fazer com que o RowSourcetype to "tabela/list" (ou "tabela/requenete" se em francês) para mostrar os resultados da consulta no Combobox.

Seus problemas de memória surgem ao abrir o RecordSet (Rspersonne) sem fechá -lo. Você deve fechá -los ao fechar/descarregar o formulário (mas, novamente, você teria problemas de escopo, pois o conjunto de registros é declarado na função e não no formulário).

Você também pode tentar criar e salvar uma consulta com o criador de consultas interno do Access e conectar a mesma consulta na linha de linha do seu ComboBox. Dessa forma, a consulta é validada e compilada no acesso.

Para definir um controle que aceita uma linha de rodapé para um conjunto de registros, você faz o seguinte:

Set recordset = currentDb.OpenRecordset("SELECT * FROM TABLE", dbOpenSnapshot)
Set control.recordset = recordset

Funciona com o Dao Recordets, com certeza, não experimentei os registros do ADO porque não tenho nenhum motivo real para usá -los.

Quando feito dessa maneira, um requisito simples não funcionará para atualizar os dados, você deve repetir a instrução Set.

Bom método com o uso da propriedade RecordSet, obrigado por essa dica!

Patrick, o método que você mostrou em sua página tem uma grande desvantagem (eu tentei isso por conta própria): a lista de valores pode ser apenas 32 kb, se você exceder esse limite, a função lançará um erro. O método de retorno de chamada tem a grande desvantagem de que é muito lento e é chamado uma vez para cada entrada, o que o torna inutilizável para uma lista mais longa. O uso do método RecordSet funciona muito bem. Eu precisava disso porque minha sequência SQL era superior a 32 kb (muitos valores de índice para onde o ID em (x, x, x, x, x ...)).

Aqui está uma função simples que usa essa ideia para definir um conjunto de registros para o ComboBox:

' Fills a combobox with the result of a recordset.
'
' Works with any length of recordset results (up to 10000 in ADP)
' Useful if strSQL is longer than 32767 characters
'
' Author: Christian Coppes
' Date: 16.09.2009
'
Public Sub fnADOComboboxSetRS(cmb As ComboBox, strSQL As String)
    Dim rs As ADODB.Recordset
    Dim lngCount As Long

   On Error GoTo fnADOComboboxSetRS_Error

    Set rs = fnADOSelectCommon(strSQL, adLockReadOnly, adOpenForwardOnly)

    If Not rs Is Nothing Then
        If Not (rs.EOF And rs.BOF) Then
            Set cmb.Recordset = rs
            ' enforces the combobox to load completely
            lngCount = cmb.ListCount
        End If
    End If

fnADOComboboxSetRS_Exit:
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then rs.Close
        Set rs = Nothing
    End If
    Exit Sub

fnADOComboboxSetRS_Error:
    Select Case Err
        Case Else
            fnErr "modODBC->fnADOComboboxSetRS", True
            Resume fnADOComboboxSetRS_Exit
    End Select
End Sub

(A função fnadoselectCommon abre um conjunto de registros ADO e o devolve. A função Fnerr mostra uma caixa de mensagem com o erro, se houve uma.)

À medida que essa função fecha o conjunto de registros aberto, não deve haver problema com a memória. Eu o testei e não vi nenhum aumento de memória que não foi liberado após fechar o formulário com os ComboBoxes.

No evento de descarga do formulário, você pode usar um "Definir rs = me.comboboxname.recordset" e feche -o. Isso não deve ser necessário em relação à memória, mas pode ser melhor liberar conexões abertas (se usadas com um servidor de banco de dados de back -end).

Saúde,

cristão

Um controle de caixa de combinação não possui uma propriedade RecordSet. Ele possui uma propriedade da RowSource, mas o acesso está esperando uma string SQL lá.

Você pode alterar o RowSourcetype para o nome de uma função "retorno de chamada" definida pelo usuário. A Help Access fornecerá mais informações, incluindo código de exemplo, posicionando -se no RowSourcetype e pressionando F1. Eu uso esse tipo de função quando quero dar aos usuários uma lista de relatórios disponíveis, letras de unidade ou outros dados que não estão disponíveis por meio de uma consulta SQL.

Não entendo o que você quer dizer com seu terceiro parágrafo com relação ao uso de dados diretamente do lado do servidor. Ou melhor, não entendo qual é o problema usando consultas padrão.

No MS Access, está tudo bem, mas no VB, você pode usar algo assim usando Adodc (Jet 4.0):

Private sub Form1_Load()
   with Adodc1
     .commandtype = adcmdtext
     .recordsource = "Select * from courses"
     .refresh

     while not .recordset.eof
           combo1.additem = .recordset.coursecode
           .recordset.movenext
     wend
   end with
End Sub
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top