ADO - Trabalhando com Recordsets sem uma base de dados
Qual seria sua reação se alguém dissesse que pode trabalhar com Recordsets ADO sem utilizar qualquer fonte de dados externa ? Espanto ? Descrença ? Curiosidade ? ...
Qualquer que seja a sua reação vou logo dizer que isto é perfeitamente possível e viável e com algumas vantagens . Quer saber quais são elas ?
Bem , se você ainda esta incrédulo , e , é daqueles que precisa ver para crer , vamos mostrar uma aplicação completa com um recordset ADO sem usar um banco de dados. ( se quiser pode dar uma olhada no artigo - Retornando dados com GetRows - onde já arranhamos o assunto...)
Vamos criar um pequeno programa , uma agenda pessoal , para armazenar os endereços dos amigos , parentes , etc... Estaremos trabalhando com as opções de incluir , alterar e excluir os registros do nosso arquivo de dados, tudo isto sem usar um banco de dados...
Criando a aplicação - Agenda
Você deve estar se perguntando - Como vamos usar um Recordset sem um banco de dados ?
Se você ainda não sabe , a ADO permite utilizar um recordset desconectado . É este conceito que vamos usar. Podemos desconectar e mais tarde fazer a conexão com uma base de dados , mas este não vai ser nosso caso. Simplesmente vamos usar o recordset desconectado. Para definir um recordset desconectado podemos dizer que: "Um recordset desconectado é um recordset do lado do cliente que não tem uma conexão ativa a uma fonte de dados ou banco de dados."
Só para você ter uma idéia da utilidade desta técnica , imagine um servidor de banco de dados que pode lidar com apenas um certo número limitado de conexões ativas ao mesmo tempo. Assim quando um aplicativo precisa esperar a entrada do usuário ou qualquer outra ação do usuário , porque manter a conexão aberta por todo este tempo ?
Você pode , no caso acima, recuperar os dados de uma fonte de dados , armazenar os dados em um recordset e desconectar o recordset da fonte de dados para libera recursos da conexão. O aplicativo altera os dados ou incluir novos dados ao recordset e depois se reconecta e a fonte de dados e escreve as mudanças ocorridas. Entendeu ???
As duas principais técnicas para criar um recordset desconectado são :
A primeira coisa a fazer para gerar um recordset (rsagenda) desconectado é :
Pronto , já temos nosso recordset desconectado e pronto para ser usado. Precisamos no entanto fazer os ajustes finais , os quais sejam :
E a estrutura do Recordset ? de onde virá ?
Bem . como não estamos usando um banco de dados vamos ter que criar a estrutura do recordset. Para fazer isto usamos o método Append da coleção Fields e incluímos a definição de cada campo ao recordset. Para fazer isto vamos precisar conhecer o nome , tamanho e o tipo de dados de cada campo.
A sintaxe para para o método Append é :
objetoRecordset.Fields .Append NomeCampo , TipoCampo , TamanhoCampo , Atributos
O nome e o tamanho dos campos são definidos com base nas informações que desejamos armazenar. Assim, para o nosso caso , vamos armazenar : o nome , endereço ,cidade , cep , uf , telefone e email. Podemos definir o nome e o tamanho conforme a tabela abaixo :
Nome |
Tamanho |
AgNome |
50 |
AgEndereco | 50 |
AgCidade | 40 |
AgCep | 15 |
Aguf | 2 |
Agtelefone | 15 |
Agemail | 250 |
E o tipo de dados , como vamos definir ? Abaixo temos os principais tipos de dados suportados na ADO :
Constant | Description |
adBinary | Um valor binário (DBTYPE_BYTES). |
adBoolean | Um valor Boleano (DBTYPE_BOOL). |
adBSTR | Um caractere string terminado em null-(Unicode) (DBTYPE_BSTR). |
adChar | Um valor String fixo. (DBTYPE_STR). |
adCurrency | Um valor monetário (DBTYPE_CY). |
adDate | Um valor Data (DBTYPE_DATE). |
adDBDate | Um valor Data (yyyymmdd) (DBTYPE_DBDATE). |
adDBTime | Um valor para horas (hhmmss) (DBTYPE_DBTIME). |
adDecimal | Um valor numérico exato com precisao defnida.(DBTYPE_DECIMAL). |
adDouble | Valores de precisao dupla (DBTYPE_R8). |
adEmpty | Um valor não definido (DBTYPE_EMPTY). |
adInteger | Um inteiro de 4 bytes (DBTYPE_I4). |
adNumeric | Um valor numerico (DBTYPE_NUMERIC). |
adSingle | Precisão simples (DBTYPE_R4). |
adVarChar | Um valor String (Parameter object only). |
adVariant | Um valor Variant (DBTYPE_VARIANT). |
Como no nosso exemplo todos os campos são do tipo Texto podemos usar então o tipo de dado adVarChar ou adBSTR . Vamos usar advarChar.
O parâmetro Atributos ( Attributes ) é opcional e define atributos para os novos campos : EX: Conter valores NULL - adFldMaybeNull. O valor padrão é adFldDefault .
Nosso recordset será criando conforme o código a seguir:
With .Fields
.Append "Nome", adVarChar, 50
.Append "Endereco", adVarChar, 50
.Append "Cidade", adVarChar, 40
.Append "Cep", adVarChar, 15
.Append "UF", adVarChar, 2
.Append "telefone", adVarChar, 15
.Append "email", adVarChar, 250
End With
]E como fazemos para salvar o Recordset ?
Simples, use o método Save do objeto Recordset.
A sintaxe para o método Save é:
recordset.Save Destination, PersistFormat
Ex: rsagenda.Save "c:\teste\agenda.dat" , adPersistADTG
Lembre-se que:
O método Save somente pode
ser invocado em um Recordset aberto . Antes de usá-lo você deve usar o
método Open para restaurar o recordset a partir do destino.
Se a propriedade Filter estiver ativa no Recordset , então , somente as linhas acessíveis no filtro serão salvas. Ao salvar as alterações no recordset ele permanece aberto e você pode salvar as mudanças mais recentes. Para alcançar um bom desempenho usando Save utilize a propriedade CursorLocation como adUseClient. |
Vamos agora ao código das funções utilizadas no aplicativo agenda:
Na seção General Declarations do formulários insira o código abaixo , onde definimos as variáveis visíveis em todo o formulário.
Public rsagenda as ADODB.Recordset Public strArquivo as String Public Flag as Boolean |
A seguir teremos o código que inicializa o nosso objeto recordset - rsagenda. O código estará no evento Load do Formulário. Vejamos:
Private Sub Form_Load() Dim icontador As Integer Dim newitem As ListItem Set rsagenda = New ADODB.Recordset Call Abre_Recordset_Desconectado Call Preenche_Lista If rsagenda.RecordCount > 1 Then rsagenda.Filter = "Nome='" & ListAgenda.SelectedItem.Text & "'" Call Preenche_Controles End If End Sub |
A procedura Abre_Recordset_Desconectado , verifica se o arquivo agenda.dat ( voce pode usar qualquer nome).Se o arquivo não existir ele será criado através da rotina Cria_Recordset_Desconectado:
Private Sub Abre_Recordset_Desconectado() strArquivo = "c:\teste\agenda.dat" If Dir(strArquivo) = "" Then Cria_Recordset_Desconectado End If rsagenda.Open strArquivo End Sub |
A rotina Cria_Recordset_Desconectado abaixo irá criar o recordset rsagenda com a estrutura já definida:
Private Sub Cria_Recordset_Desconectado() With rsagenda Set .ActiveConnection = Nothing .CursorLocation = adUseClient .LockType = adLockBatchOptimistic With .Fields .Append "Nome", adVarChar, 50 .Append "Endereco", adVarChar, 50 .Append "Cidade", adVarChar, 40 .Append "Cep", adVarChar, 15 .Append "UF", adVarChar, 2 .Append "telefone", adVarChar, 15 .Append "email", adVarChar, 250 End With .Open .Save strArquivo, adPersistADTG .Close End With End Sub |
A seguir a rotina Preenche_Lista irá preencher o controle ListView com os dados do recordset exibindo somente o nome constante no recordset. Abaixo o código:
Private Sub Preenche_Lista() With ListAgenda .View = lvwList Do Until rsagenda.EOF Set newitem = .ListItems.Add(, , rsagenda("Nome")) rsagenda.MoveNext Loop .SortKey = 0 End With Set ListAgenda.SelectedItem = newitem End Sub |
A seguir usamos a propriedade Filter do recordset para filtrar o recordset , Assim :
rsagenda.Filter = "Nome='" & ListAgenda.SelectedItem.Text & "'"
Perceba que o filtramos pelo campo Nome igual ao item atualmente selecionado na Lista.
Depois preenchemos os controles através da procedura Preenche_Controles abaixo:
Private Sub Preenche_Controles() If rsagenda.RecordCount > 0 Then For icontador = 0 To rsagenda.Fields.Count - 1 Set Text1(icontador).DataSource = rsagenda Text1(icontador).Text = rsagenda.Fields(icontador) Next End If End Sub |
Para incluir dados no recordset basta clicar no botão - Incluir (cmdIncluir). O código é o seguinte:
Private Sub cmdincluir_Click(Index As Integer) Dim icontador As Integer ListAgenda.Sorted = False Set ListAgenda.SelectedItem = Nothing cmdsalvar.Enabled = True For icontador = 0 To rsagenda.Fields.Count - 1 Text1(icontador).Text = "" Next Text1(0).SetFocus End Sub |
A exclusão de um registro é obtida ao clicarmos no botão - Excluir (cmdexcluir) - cujo código é:
Private Sub cmdexcluir_Click(Index As Integer) rsagenda.Delete adAffectCurrent With ListAgenda Call Preenche_Controles |
A rotina mais importante é que salva o recordset em um arquivo definido . Usamos o arquivo agenda.dat . O botão cmsalvar ao ser clicado dispara o seguinte código:
Private Sub cmdsalvar_Click() rsagenda.AddNew For icontador = 0 To rsagenda.Fields.Count - 1 Call Salvar_Recordset_Desconectado cmdsalvar.Enabled = False |
Abaixo a procedure ListAgenda_ItemClick que atualiza os controles quando clicamos em um item da lista.
Private Sub ListAgenda_ItemClick(ByVal Item As MSComctlLib.ListItem) rsagenda.Filter = "Nome='" & ListAgenda.SelectedItem.Text & "'" Preenche_Controles End Sub |
Finalmente o código do evento Query_Unload que salva o recordset quando o usuário sai do aplicativo :
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) rsagenda.Save strArquivo, adPersistADTG End Sub |
Abaixo a tela do aplicativo em funcionamento:
Viu como tratamos um recordset sem precisar de uma conexão com um banco de dados. A vantagem é que podemos usar quase todos os métodos e propriedades do objeto recordset ( addnew, delete , Filter , Sort , etc.. )
Eu não usei um tratamento de erros no exemplo , nem me preocupei com alguns possíveis erros , meu objetivo foi mostrar como trabalhar um recordset desconectado.
Acreditou agora !!!!
Copyright (c) 2001 - José Carlos Macoratti