ADO - Localizando informações


Vamos começar este novo milênio tratando de um assunto que creio vai interessar muita gente - Como localizar informações usando a ADO . Antes de mais nada devo informar que estou usando a versão 2.5 da ADO . Quer saber qual versão da ADO esta instalada na sua máquina ?  Use a ferramenta Component Checker (Comcheck.exe). Você pode fazer o download no endereço http://www.microsoft.com/data/download.htm . O resultado final da execução do Component Checker e mostrado abaixo:

 Naturalmente quando falamos a nível de dados (campos e registros) estamos tratando com o objeto Recordset . Vamos então mostrar como encontrar dados específicos em um Recordset ADO. Lembrando que um objeto Recordset possui muitas funções úteis. Dentre elas podemos citar as mais usadas: bookmark , Find , Seek , Filter , etc

Usando Bookmarks (marcadores).

Um bookmark de um recordset é como um cursor que aponta para um registro específico dentro do Recordset identificando-o de forma única.  Fazendo uma analogia , ao ler um livro você não costumar usar um marcador para indicar em qual página parou ? Sim , você põe o marcador na página para quando retornar a leitura localizar com rapidez onde parou a leitura. Assim funciona um bookmark. Para usá-lo em um objeto recordset as etapas são:

Mas tome cuidado , pois nem todos os registros suportam bookmarks. Para verificar se um recorset suporta bookmarks use a seguinte instrução:  blnmarcador = rs.Supports(adBookmark).

Assim o método Supports usando o argumento adBookmark retorna TRUE se o recordset suporta bookmarks e FALSE caso não suporte.

Localizando dados com ADO

Basicamente temos dois métodos para localizar dados em um recordset usando ADO:  Find e Seek.

1- ) Usando o método Find

O método Find é usado para encontrar um registro que contém um determinado valor em um determinado campo do registro. Você define um critério de busca e se o critério satisfeito o ponteiro do registro se posiciona no registro que atendeu o critério, se o critério não foi atendido o ponteiro se posiciona no fim do recordset. A sintaxe é a seguinte:

Find (criteria, SkipRows, searchDirection, start)

Parametros

criteria - Uma  String contendo o nome da coluna , o operador de comparação e o valor que desejamos localizar. Exemplos de strings de busca: 

Lembrando que os valores strings devem vir entre aspas simples ('Joao') e as datas devem estar iniciadas e terminadas com o símbolo (#). 

SkipRows   Define o deslocamento da linha atual ou o bookmark padrão para iniciar a busca. O padrão é começar na linha atual e terminar na última linha

searchDirection   Indica a direção em que o recordset é procurado. Os valores podem ser:  

start   Define um bookmark de início para a busca.

OBS : Se você não definir a posição do cursor na linha atual quando for iniciar a busca irá ocorrer um erro. Por isso antes de usar o método Find você pode mover o cursor para o inicio do arquivo usando o método MoveFirst.

Exemplo prático:

Vamos mostrar em um exemplo prático como usar o método Find.

    

A seguir insira o seguinte código no  projeto:

Dim cnn As New ADODB.connection
Dim rst As New ADODB.Recordset

Private Sub Form_Load()
Dim criterio As String

'Abre a conexão
cnn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=C:\teste\Northwind.mdb;"

'Abre o Recordset
rst.CursorLocation = adUseClient
rst.Open "Select * From Suppliers", cnn, adOpenKeyset, adLockOptimistic, adCmdText

'move-se para o primeiro registro
rst.MoveFirst

' define o criterio para busca
criterio = "Country Like 'A%'"
' inicia busca no recordset
rst.Find criterio, 0, adSearchForward

' percorre o recordset ate o seu final
While Not rst.EOF
   Debug.Print rs("CompanyName")
   marcador = rst.Bookmark  
   rs.Find criterio, 1, adSearchForward, marcador
Wend

End Sub

Vamos explicar passo a passo:

1-)  Dim cnn As New ADODB.connection
      Dim rst As New ADODB.Recordset
Define as variáveis objetos usada para a conexão e para o objeto Recordset

2-)  Abre a conexão
      cnn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=C:\teste\Northwind.mdb;"
 
      Abrimos uma conexão usando o provedor - Microsoft.Jet.OLEDB.3.51 e o Data Source - C:\teste\Nortwind.mdb

3-)  Abre o Recordset
      rst.CursorLocation = adUseClient
      rst.Open "Select * From Suppliers", cnn, adOpenKeyset, adLockOptimistic, adCmdText

      Definimos o tipo de cursor usado , no caso usamos o cursor do lado do cliente - AdUseClient e abrimos um recordset com os parâmetros AdOpenKeySet - Permite a alteração    e    adLockOptimistic - usa o bloqueio pessimista (mantém o bloqueio até usar o método para atualizar)

4-) ' define o criterio para busca
     criterio = "Country Like 'A%'"
     ' inicia busca no recordset
     rst.Find criterio, 0, adSearchForward

Definimos o critério para busca e iniciamos  a busca usando o método Find usando os parâmetros : skiprows =0 , e adSearchForward - busca do ínicio para o fim.

5-) While Not rst.EOF
       Debug.Print rs("CompanyName")
       marcador = rst.Bookmark  
       rs.Find criterio, 1, adSearchForward, marcador
     Wend

Percorremos o recordset , imprimindo o campo - CompanyName - e se posicionando a partir do bookmark anterior com avanço de um 1 registro para frente a partir do bookmark - marcador. Note que usamos o bookmark para armazenar a posição atual do registro  e usamos esta posição inicial para a próxima busca.

1- ) Usando o método Seek

O método Seek permite a procura em uma coluna. Ele só encontra os valores iguais ao valor da procura e vai precisar  de um provedor de dados que permita a utilização da propriedade Index e o método Seek. (Nem todos os provedores permitem). Além disso o método Seek vai requerer um cursor do lado do servidor .

Atualmente , somente alguns provedores permitem usar a propriedade Index e o método Seek do objeto Recordset  para procurar por valores em um índice de uma tabela. O provedor OLE DB - Provider for Microsoft Jet 4.0 - que é usado para se conectar a um banco de dados access permite a utilização do método Seek..

Para verificar se o provedor suporta a propriedade Index e o método Seek podemos usar o método Supports com os parâmetros adIndex e adSeek. Veja o exemplo abaixo:

If rs.Supports(adIndex) then
     msgbox "Este Provedor suporta a propriedade Index"
endif

If rs.Supports(adSeek) then
     msgbox "Este Provedor suporta a propriedade Seek"
endif

Você deve ter o cuidado de definir a propriedade Index assim que o Recordset for aberto para depois usar o método Seek. A propriedade Index  indica o nome do índice que estará ativo. Assim , supondo que você possua uma tabela chamada clientes e que queira fazer uma busca pela coluna Nome da tabela, vai precisar definir um índice para esta coluna na tabela dando a ele um nome. O nome do índice pode ser o mesmo nome da coluna . Para o nosso caso poderíamos ter criado um índice chamado Nome. (Você poderia ter usado qualquer outro nome para definir o índice.) Teriamos então:      rs.index = "nome"

Em muitos casos quando você usa um campo autonumeração no Access e define este campo como uma chave primária, o índice PrimaryKey será criado para esta coluna da tabela. Então se for usar esta coluna para fazer uma busca usando o Seek  , deverá usar a sintaxe:    rs.Index = "PrimaryKey"

Depois que a propriedade Index foi definida para o nome do índice existente na tabela,  podemos usar o método Seek para procurar na coluna desejada.  Quando o método seek encontrar o registro desejado o ponteiro irá se posicionar neste registro. Se nada for encontrado o ponteiro o ponteiro é definido para EOF. A sintaxe é a seguinte:

rs.Seek  Array(ValordaColuna)

Aqui você deve tomar cuidado. Como um índice pode ser constituído de uma ou mais colunas , o termo - ValordaColuna - indica os valores da coluna. Vamos supor que você quer tem uma tabela de clientes com um campo CodigoID definido como chave primária , que você quer fazer procurar pelo cliente cujo código seja igual 120.  Você deverá procurar pelo valor 120 na coluna CódigoID e deverá fazer:

rs.index="PrimaryKey"

rs.Seek Array(120)

Se o índice possuir mais de uma coluna , você deverá informar no vetor (array) os valores de todas as colunas contidas no índice.Por exemplo, se uma tabela pedidos  possuir um índice chamado - Primarykey - e for constituído pelos campos codigopedido e codigoproduto da tabela , ao usar o método Seek para procurar pelo pedido cujo código seja igual a 23 e código de produto igual a 50 você deverá fazer:

rs.index="PrimaryKey"

rs.Seek Array(23,50)

 

Vejamos agora um exemplo completo usando a propriedade Index e o método Seek :

 

Neste exemplo usaremos o banco de dados Northwind.mdb e a tabela Funcionários. A estrutura e os índices criados são dados abaixo:

 

 

Iremos usar o índice chave Primária - CódigoDoFuncionário - para localizar o funcionário e exibir o seu nome.  

O projeto usará um formulário , uma caixa de texto e um botão de comando ( ver figura abaixo).

 

 

Defina as variáveis objeto na seção General Declarations:

Dim cnn As New ADODB.connection
Dim rst As New ADODB.Recordset

O código do botão de comando segue abaixo:

 

Private Sub Command1_Click()

If Text1.Text = "" Then
    MsgBox " Informe um valor para busca "
Exit Sub
End If

'Abre a conexão
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\teste\Northwind.mdb;"

'Abre o Recordset
rst.CursorLocation = adUseServer
rst.Open "Funcionários", cnn, adOpenKeyset, adLockReadOnly, adCmdTableDirect

If rst.Supports(adIndex) And rst.Supports(adSeek) Then
   rst.Index = "CódigoDoFuncionário"
   rst.MoveFirst
   rst.Seek Array(CLng(Text1.Text))
    If rst.EOF Then
      MsgBox "Funcionário não localizado"
    Else
      MsgBox rst("CódigoDoFuncionário") & " - " & rst("nome") & vbCrLf
    End If
Else
    MsgBox " O provedor utilizado não suporta : Index e Seek "
End If

´Fechamos a conexão e o recordset
rst.Close
cnn.Close
Set rs = Nothing
Set cnn = Nothing

End Sub

 

Observe que antes de iniciar a busca verificamos se o provedor suporta a utilização de Index e de Seek. Se o método Supports é novo para você , vou dar uma canja....

 

 Você pode usar o método Supports com as seguintes constantes:

 

Constante Utilização
adAddNew Verifica se novos registros podem ser adicionados
adApproxPosition Verifica se as propriedades: AbsolutePage e AbsolutePosition estão disponíveis
adBookMark Verifica se podemos usar um marcador no Recordset
adDelete Verifica se os registros poderão ser excluídos
AdHoldRecords Verifica se podemos recuperar os registros sem submeter as alterações
adResync Verifica se o método Resynd esta disponível
adUpdate Verifica se o conjunto de registros permite a atualização
adUpdateBatch Verifica se o recordset permite a atualização em lote - via UpdateBatch

Bem , vou ficando por aqui... (terminei o artigo...)