Compartilhar via


Trabalhar com conjuntos de registros

O objeto Recordset tem recursos internos que permitem reorganizar a ordem dos dados no conjunto de resultados, pesquisar um registro específico com base nos critérios fornecidos e até mesmo otimizar essas operações de pesquisa usando índices. Se esses recursos estão disponíveis para uso ou não depende do provedor e, em alguns casos, como o da propriedade Index, da estrutura da própria fonte de dados.

Organizando dados

Com frequência, a maneira mais eficiente de ordenar os dados em seu Recordset é especificando uma cláusula ORDER BY no comando SQL usado para retornar resultados. No entanto, talvez seja necessário alterar a ordem dos dados em um Recordset que já foi criado. Você pode usar a propriedade Sort para estabelecer a ordem na qual linhas de um Recordset são percorridas. Além disso, a propriedade Filter determina quais linhas podem ser acessadas ao percorrer linhas.

A propriedade Sort define ou retorna um valor String que indica os nomes de campo no Recordset a ser classificado. Cada nome é separado por uma vírgula e, opcionalmente, é seguido por um espaço e pela palavra-chave ASC (que classifica o campo em ordem crescente) ou DESC (que classifica o campo em ordem decrescente). Por padrão, se nenhuma palavra-chave for especificada, o campo será classificado em ordem ascendente.

A operação de classificação é eficiente porque os dados não são reorganizados fisicamente, mas acessados na ordem especificada por um índice.

A propriedade Sort requer que a propriedade CursorLocation seja definida como adUseClient. Um índice temporário será criado para cada campo especificado na propriedade Sort se um índice ainda não existir.

A definição da propriedade Sort como uma cadeia de caracteres vazia redefinirá as linhas em sua ordem original e excluirá índices temporários. Os índices existentes não serão excluídos.

Suponha que um Recordset contenha três campos chamados firstName, middleInitial e lastName. Defina a propriedade Sort como a cadeia de caracteres "lastName DESC, firstName ASC", que ordenará o Recordset por sobrenome em ordem decrescente e, em seguida, por nome em ordem crescente. A inicial do meio é ignorada.

Nenhum campo referenciado em uma cadeia de caracteres de critérios de classificação pode ser chamado de "ASC" ou "DESC" porque esses nomes entram em conflito com as palavras-chave ASC e DESC. Forneça ao campo que tem um nome conflitante um alias com a palavra-chave AS na consulta que retorna o Recordset.

Para saber mais sobre a filtragem de Recordset, confira "Filtrando os resultados" mais adiante neste tópico.

Localizando um registro específico

O ADO fornece os métodos Find e Seek para localizar um registro específico em um Recordset. O método Find é compatível com uma variedade de provedores, mas está limitado a um único critério de pesquisa. O método Seek dá suporte à pesquisa com vários critérios, mas não tem suporte de muitos provedores.

Índices em campos podem melhorar consideravelmente o desempenho do método Find e as propriedades Sort e Filter do objeto Recordset. Você pode criar um índice interno para um objeto Field definindo sua propriedade dinâmica Optimize. Essa propriedade dinâmica é adicionada à coleção Properties do objeto Field quando você define a propriedade CursorLocation como adUseClient. Lembre-se de que esse índice é interno ao ADO; você não pode obter acesso a ele ou usá-lo para nenhuma outra finalidade. Além disso, esse índice é distinto da propriedade Index do objeto Recordset.

O método Find localiza rapidamente um valor dentro de uma coluna (campo) de um Recordset. Com frequência, você pode melhorar a velocidade do método Find em uma coluna usando a propriedade Optimize para criar um índice nela.

O método Find limita sua pesquisa ao conteúdo de um campo. O método Seek requer que você tenha um índice e tenha outras limitações também. Se você precisar pesquisar em vários campos que não são a base de um índice, ou se o provedor não der suporte a índices, poderá limitar seus resultados usando a propriedade Filter do objeto Recordset.

Find

O método Find pesquisa um Recordset da linha que atende a um critério especificado. Opcionalmente, a direção da pesquisa, a linha inicial e o deslocamento da linha inicial podem ser especificados. Se o critério for atendido, a posição da linha atual será definida no registro encontrado; caso contrário, a posição é definida como o final (ou início) do Recordset, dependendo da direção da pesquisa.

Somente um nome de coluna única pode ser especificado para o critério. Em outras palavras, esse método não dá suporte a pesquisas multicolunas.

O operador de comparação do critério pode ser ">" (maior que), "<" (menor que), "=" (igual), ">=" (maior ou igual), "<=" (menor ou igual), "<>" (não igual) ou "LIKE" (correspondência de padrões).

O valor do critério pode ser uma cadeia de caracteres, um número de ponto flutuante ou uma data. Os valores de cadeia de caracteres são delimitados com aspas simples ou marcas "#" (tecla jogo da velha) (por exemplo, "state = 'WA"" ou "state = #WA#"). Os valores de data são delimitados com marcas "#" (tecla jogo da velha) (por exemplo, "start_date > #22/7/97#").

Se o operador de comparação for "like", o valor da cadeia de caracteres poderá conter um asterisco (*) para localizar uma ou mais ocorrências de um caractere ou substring. Por exemplo, "state like 'M*'" corresponde a Maine e Massachusetts. Você também pode usar asteriscos à esquerda e à direita para encontrar uma substring contida nos valores. Por exemplo, "state like '*as*'" corresponde ao Alasca, Arkansas e Massachusetts.

Os asteriscos só podem ser usados no final de uma cadeia de caracteres de critérios ou juntos no início e no final de uma cadeia de caracteres de critérios, conforme mostrado anteriormente. Você não pode usar o asterisco como um curinga à esquerda ('*str') ou curinga inserido ('s*r'). Isso causará um erro.

Buscar e Indexar

Use o método Seek junto com a propriedade Index se o provedor subjacente der suporte a índices no objeto Recordset. Use o método Supports(adSeek) para determinar se o provedor subjacente dá suporte ao método Seek e o método Supports(adIndex) para determinar se o provedor dá suporte a índices. (Por exemplo, o Provedor OLE DB para Microsoft Jet dá suporte a Seek e Index.)

Se Seek não encontrar a linha desejada, nenhum erro ocorrerá e a linha será posicionada no final do Recordset. Defina a propriedade Index como o índice desejado antes de executar esse método.

Esse método tem suporte apenas com cursores do lado do servidor. O Seek não tem suporte quando o valor da propriedade CursorLocation do objeto Recordset é adUseClient.

Esse método só pode ser usado quando o objeto Recordset foi aberto com um valor CommandTypeEnum de adCmdTableDirect.

Filtrando os resultados

O método Find limita sua pesquisa ao conteúdo de um campo. O método Seek requer que você tenha um índice e tenha outras limitações também. Se você precisar pesquisar em vários campos que não são a base de um índice, ou se o provedor não der suporte a índices, poderá limitar seus resultados usando a propriedade Filter do objeto Recordset.

Use a propriedade Filter para exibir seletivamente os registros em um objeto Recordset. O Recordset filtrado torna-se o cursor atual, o que significa que os registros que não atendem aos critérios de Filter não estão disponíveis no Recordset até que Filter seja removido. Outras propriedades que retornam valores com base no cursor atual são afetadas, como AbsolutePosition, AbsolutePage, RecordCount e PageCount. Isso ocorre porque a definição da propriedade Filter como um valor específico moverá o registro atual para o primeiro registro que satisfaz o novo valor.

A propriedade Filter usa um argumento variante. Esse valor representa um dos três métodos para usar a propriedade Filter: uma cadeia de caracteres de critérios, uma constante FilterGroupEnum ou uma matriz de indicadores. Para saber mais, confira Filtragem com uma cadeia de caracteres de critérios, Filtragem com uma constante e Filtragem com indicadores mais adiante neste tópico.

Observação

Quando você conhece os dados que deseja selecionar, geralmente é mais eficiente abrir um Recordset com uma instrução SQL que filtra efetivamente o conjunto de resultados, em vez de depender da propriedade Filter .

Para remover um filtro de um Recordset, use a constante adFilterNone. A definição da propriedade Filter como uma cadeia de caracteres de comprimento zero ("") tem o mesmo efeito de usar a constante adFilterNone.

Filtragem com uma cadeia de caracteres de critérios

A cadeia de caracteres de critérios consiste em cláusulas no valor do operador FieldName do formulário (por exemplo, "LastName = 'Smith'"). Você pode criar cláusulas compostas concatenando cláusulas individuais com AND (por exemplo, "LastName = 'Smith' AND FirstName = 'John'") e OR (por exemplo, "LastName = 'Smith' OR LastName = 'Jones'"). Use as diretrizes abaixo para as cadeias de caracteres de critérios:

  • FieldName precisa ser um nome de campo válido do Recordset. Se o nome do campo contém espaços, você precisa colocar o nome dentro de colchetes.

  • O operador precisa ser um dos seguintes: <, >, <=, >=, <>, = ou LIKE.

  • Value é o valor com o qual você comparará os valores de campo (por exemplo, 'Smith', #8/24/95#, 12.345 ou $50.00). Use aspas simples (') com cadeias de caracteres e sinais de libra (#) com datas. Em números, você pode usar pontos decimais, sinais de dólar e notação científica. Se Operator for LIKE, Value poderá usar caracteres curinga. Somente os caracteres curinga de asterisco (*) e sinal percentual (%) são permitidos e precisam ser o último caractere na cadeia de caracteres. Value não pode ser nulo.

    Observação

    Para incluir aspas simples (') no Value do filtro, use duas aspas simples para representar uma. Por exemplo, para filtrar por O'Malley, a cadeia de caracteres de critérios deve ser "col1 = 'O''Malley'". Para incluir aspas simples no início e no final do valor do filtro, coloque a cadeia de caracteres em sinais de libra (#). Por exemplo, para filtrar por '1', a cadeia de caracteres de critérios deve ser "col1 = #'1'#".

Não há precedência entre AND e OR. As cláusulas podem ser agrupadas entre parênteses. No entanto, você não pode agrupar cláusulas unidas por um OR e, em seguida, unir o grupo em outra cláusula com um AND, desta forma.

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'  

Você deveria construir o filtro desta forma.

(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')  

Em uma cláusula LIKE, você pode usar um curinga no início e no final do padrão (por exemplo, LastName Like '*mit*') ou somente no final do padrão (por exemplo, LastName Like 'Smit*').

Filtragem com uma constante

As constantes a seguir estão disponíveis para filtrar Recordsets.

Constante Descrição
adFilterAffectedRecords Filtros para exibir apenas registros afetados pela última chamada Delete, Resync, UpdateBatch ou CancelBatch.
adFilterConflictingRecords Filtra para exibir os registros que falharam na última atualização em lote.
adFilterFetchedRecords Filtros para exibir os registros no cache atual, ou seja, os resultados da última chamada para recuperar registros do banco de dados.
adFilterNone Remove o filtro atual e restaura todos os registros para exibição.
adFilterPendingRecords Filtros para exibir apenas registros que foram alterados, mas ainda não foram enviados para o servidor. Aplicável somente para o modo de atualização em lote.

As constantes de filtro facilitam a resolução de conflitos de registro individuais durante o modo de atualização em lote permitindo que você exiba, por exemplo, apenas os registros que foram afetados durante a última chamada de método UpdateBatch, conforme mostrado no exemplo a seguir.

Attribute VB_Name = "modExaminingData"

Filtragem com indicadores

Por fim, você pode transmitir uma matriz variante de indicadores à propriedade Filter. O cursor resultante conterá apenas os registros cujo indicador foi transmitido à propriedade. O exemplo de código a seguir cria uma matriz de indicadores dos registros em um Recordset que tem um "B" no campo ProductName. Em seguida, ele transmite a matriz à propriedade Filter e exibe informações sobre o Recordset filtrado resultante.

'BeginFilterBkmk  
Dim vBkmkArray() As Variant  
Dim i As Integer  
  
'Recordset created using "SELECT * FROM Products" as command.  
'So, we will check to see if ProductName has a capital B, and  
'if so, add to the array.  
i = 0  
Do While Not objRs.EOF  
    If InStr(1, objRs("ProductName"), "B") Then  
        ReDim Preserve vBkmkArray(i)  
        vBkmkArray(i) = objRs.Bookmark  
        i = i + 1  
        Debug.Print objRs("ProductName")  
    End If  
    objRs.MoveNext  
Loop  
  
'Filter using the array of bookmarks.  
objRs.Filter = vBkmkArray  
  
objRs.MoveFirst  
Do While Not objRs.EOF  
    Debug.Print objRs("ProductName")  
    objRs.MoveNext  
Loop  
'EndFilterBkmk  

Criando um clone de um conjunto de registros

Use o método Clone para criar vários objetos Recordset duplicados, especialmente se desejar manter mais de um registro atual em determinado conjunto de registros. O uso do método Clone é mais eficiente do que criar e abrir um novo objeto Recordset com a mesma definição que o original.

O registro atual de um clone recém-criado é originalmente definido como o primeiro registro. O ponteiro de registro atual em um Recordset clonado não é sincronizado com o original ou vice-versa. Você pode navegar independentemente em cada Recordset.

As alterações feitas em um objeto Recordset são visíveis em todos os seus clones, independentemente do tipo de cursor. No entanto, depois que você executar Requery no Recordset original, os clones não serão mais sincronizados com o original.

O fechamento do Recordset original não fecha as cópias dele, nem o fechamento de uma cópia fecha o original ou uma das outras cópias.

Você só poderá clonar um objeto Recordset se ele der suporte a indicadores. Os valores de indicadores são intercambiáveis, ou seja, uma referência de indicador de um objeto Recordset refere-se ao mesmo registro em um dos respectivos clones.