Desenvolvimento - Visual Basic .NET

.NET: Utilizando DataSet em um Ambiente Desconectado

Neste artigo vou mostrar como utilizar o DataSet em um ambiente desconectado, vou criar uma tabela que armazena algumas informações. Nesta tabela vamos incluir, alterar ou excluir as informações e depois persistir os dados em um arquivo XML.

por Rosana de Oliveira



Tecnologia Utilizada: Visual Studio .NET 2003

Existem muitas aplicações que utilizam armazenamento de dados em arquivos simples, por exemplo, o arquivo tipo .CSV (separado por vírgula). Um arquivo deste tipo podeser representado com as informações ordenadas em linhas e colunas, ou seja, podemos colocar estas informações em tabelas. Uma forma simples de manipular um arquivo deste tipo seria utilizando um DataSet.

Neste artigo vou mostrar como utilizar o DataSet em um ambiente desconectado, vou criar uma tabela que armazena algumas informações. Nesta tabela vamos incluir, alterar ou excluir as informaçõese depois persistir os dados em um arquivo XML.

Projetando uma Agenda de Telefone

Para mostrar como utilizar o DataSet em um ambiente desconectado criei um programasimples de uma agenda de telefone. Este programa quando inicializado lê um arquivo XML com os dados gravados anteriormente, se houver,e carrega um controle ComboBox com os nomes dos contatos. Utilizando este Combox o usuário poderá selecionar um contato e através do botão Procurar exibir as informações do contato nos TextBoxNome, Telefone, Celular e Email. Com as informações carregadas em memóriao usuário pode alterar, excluir e depois salvar oscontatosem umarquivo XML. Este programa também permite a inclusão de novos contatos. Na figura a seguir é exibido o layout do programa.

Vou utilizaruma tabela com quatro colunas Nome, Telefone, Celular e Email. Para utilizar o DataSet e o controle de manipulação de arquivos e evitar que tenhamos queusar a qualificação completa de cada namespace,utilizei os seguintes Imports:

Imports System.Data

Imports System.IO

Onamespace System.Dataestá sendo utilizado para o controle da tabela e do dataset e o namespaceSystem.IOestá sendoutilizado para verificar se um determinado arquivo existe ou não em um diretório.

Na Classe do formulário da Agenda de Telefonedeclarei as seguintes variáveis:

Private tabelaTel As DataTable "Tabela que armazena as informações

Private drEncontrou As DataRow "Armazena as informações da linha localizada no arquivo XML

Private dsTelefone As New DataSet("AgendaTelefone") "Cria o DataSet AgendaTelefone

Private dvTelefone As DataView "Cria o DataView para ordenar os dados

Private alterouRegistro As Boolean = False "informa se algum registro sofreu alteração

Vou utilizar a tabela tabelaTel para manipular os dados durante a utilização do programa. Nesta tabela podemos, incluir, alterar ou excluir os dados.O DataSet dsTelefone é utilizado para ler e escrever o arquivo XML, com os dados atualizados. O DataView é utilizado para exibir os dados ordenados alfabeticamente por nome no ComboBox.O DataView é mais flexível que o DataTable para exibir os dados, pois ele permite apresentar umavisão dos dados ordenados diferentemente do formato armazenado na tabela, além de permitir outras funcionalidades como por exemplo filtrar dados.

No evento Load do formulárioinstanciei a tabela tabelaTel, criei as colunas e a chave primária da tabela, associeia tabela ao DataSet dsTelefone e carreguei o DataSet com um arquivo XML previamente gravado. Observe que verifico se o arquivo existe utilizando o método Exists() da classe File.Caso o arquivo ainda não exista vou trabalhar com umatabela nova. Em seguida criei o DataView dvTelefone para ordenar alfabeticamente a coluna "Nome" que será exibida no ComboBox Nome.

Private Sub frmAgendaTelefone_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

"Instância a tabela

tabelaTel = New DataTable("Telefone")

"Cria as colunas

tabelaTel.Columns.Add("Nome", Type.GetType("System.String"))

tabelaTel.Columns.Add("Telefone", Type.GetType("System.String"))

tabelaTel.Columns.Add("Celular", Type.GetType("System.String"))

tabelaTel.Columns.Add("Email", Type.GetType("System.String"))

"Define a coluna Nome como chave primária para não repetir o nome

"e não permitir que o campo esteja vazio

tabelaTel.PrimaryKey = New DataColumn() {tabelaTel.Columns("Nome")}

"Associa a tabela de agenda de telefone ao DataSet

dsTelefone.Tables.Add(tabelaTel)

"Carrega a tabela com os dados do arquivo XML

If File.Exists("Agenda.xml") Then

dsTelefone.ReadXml("Agenda.xml")

End If

"Cria um dataview para ordenar o combobox por Nome

dvTelefone = New DataView(tabelaTel)

dvTelefone.Sort = "Nome"

"Carrega o combobox com a lista de nomes cadastrados no arquivo Xml

cboProcuraNome.DataSource = dvTelefone

cboProcuraNome.DisplayMember = "Nome"

End Sub

Incluir Dados

No botão Incluir verifiquei se todos os campos estão preenchidos e inseri os dados na tabela tabelaTel. As rotinas auxiliares CampoVazio() e LimparCampos() estão detalhadas no final do artigo. Estou utilizando um flag alterouRegistro paraverificar se algumcontatofoialterado antes de fechar o programa e avisar o usuário que existem informações ainda não salvas na tabela. Nesta rotina utilizei o tratamento de exceção try - catch com umtratamento específico caso se tente inserir nomes repetidos, observena rotina anterior frmAgenda_Load()que a coluna "Nome" é uma chave primária não permitindo deste modo a entrada de nomes repetidos, caso o usuário insira um nome repetido o programa gera uma exceção do tipo System.Data.ConstraintException.Ooutro tratamento de exceção épara todas as outras exceções.

Private Sub btnIncluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIncluir.Click

Dim dr As DataRow = tabelaTel.NewRow()

Try

"Verifica se todos os textbox estão preenchidos antes de inserir uma nova linha

If Not CampoVazio() Then

"insere a linha

dr("Nome") = txtNome.Text

dr("Telefone") = txtTelefone.Text

dr("Celular") = txtCelular.Text

dr("Email") = txtEmail.Text

tabelaTel.Rows.Add(dr)

MessageBox.Show("O nome " & txtNome.Text & " foi incluido com sucesso!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Information)

alterouRegistro = True

LimparCampos()

End If

Catch exC As System.Data.ConstraintException

MessageBox.Show("Este nome já está cadastrado. Selecione um novo Nome!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Warning)

LimparCampos()

Catch ex As Exception

MessageBox.Show(ex.ToString, "Erro Interno", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

End Sub

ProcurarDados

Antes de fazer uma alteração ou exclusão de registro na tabela devemos primeiro localizar a linha que queremos alterar ou excluir. Esta rotina está implementada no botão Procurar. Utilizando o nome selecionado no ComboBox Nome como argumento no métodoFind() da tabela tabelaTel conseguimos localizar a linha com as informações do nome selecionado. Com estas informações preenchemos os respectivos TextBox e habilitamos os botões Alterar e Excluir, além de armazenarmos a linha localizada no DataRow drEncontrou, para que possamos utilizar no momento de alterar ou excluir um registro.

Private Sub btnProcurar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcurar.Click

Dim strProcura As String

"Verifica se foi digitado um nome na caixa de texto de procura

If cboProcuraNome.SelectedIndex = -1 Then Exit Sub

drEncontrou = tabelaTel.Rows.Find(cboProcuraNome.Text)

"Verifica se encontrou alguma linha

If Not drEncontrou Is Nothing Then

"Como só existe um nome único para cada registro

Me.txtNome.Text = drEncontrou("Nome")

Me.txtTelefone.Text = drEncontrou("Telefone")

Me.txtCelular.Text = drEncontrou("Celular")

Me.txtEmail.Text = drEncontrou("Email")

"Habilita o botão alterar e excluir

Me.btnAlterar.Enabled = True

Me.btnExcluir.Enabled = True

Else

MessageBox.Show("Não foi localizado o nome " & Me.cboProcuraNome.SelectedText & "!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Warning)

"Não habilita o botão alterar e excluir

Me.btnAlterar.Enabled = False

Me.btnExcluir.Enabled = False

End If

End Sub

Alterar Dados

Para alterar os dados de um nome selecionadoutilizar os métodosBeginEdit() e EndEdit() doDataRow drEncontrou. O método BeginEdit() coloca o DataRow em modo de edição, permitindo quese faça alterações noDataRow sem chamar as regras de validação.Ométodo EndEdit()retira o DataRow do modo de edição.Enquanto o método EndEdit() não for chamado, ainda existe a possibilidade de cancelar as alterações chamando o método CancelEdit() do DataRow. O método CancelEdit() não foi utilizado neste exemplo, mas fica aí a dica.

Private Sub btnAlterar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAlterar.Click

Try

"Verifica se todos os textbox estão preenchidos antes de alterar uma linha

If Not CampoVazio() Then

drEncontrou.BeginEdit()

drEncontrou("Nome") = Me.txtNome.Text

drEncontrou("Telefone") = Me.txtTelefone.Text

drEncontrou("Celular") = Me.txtCelular.Text

drEncontrou("Email") = Me.txtEmail.Text

drEncontrou.EndEdit()

MessageBox.Show("O nome " & txtNome.Text & " foi alterado com sucesso!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Information)

alterouRegistro = True

LimparCampos()

End If

Catch ex As Exception

MessageBox.Show(ex.ToString, "Erro Interno", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

End Sub

Excluir Dados

Para excluir todas as informações de um nome selecionadoutilizei o método Remove() da tabela tabelaTel. O método Remove() faz com que todas as informações da linha sejam excluídas da tabela. O método Delete() também pode ser utilizado, mas neste caso a linha é somente marcada para exclusão, a mesma só ocorrerá quando for chamado o método AcceptChanges() do DataRow onde será feita a exclusão da linha, ou o método AcceptChanges() da tabela, onde serão salvas todas as alterações de todas as linhas da tabela.

Private Sub btnExcluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExcluir.Click

Try

"Remove o registro da tabela

tabelaTel.Rows.Remove(drEncontrou)

LimparCampos()

MessageBox.Show("O nome " & txtNome.Text & " foi excluido com sucesso!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Information)

alterouRegistro = True

Catch ex As Exception

MessageBox.Show(ex.ToString, "Erro Interno", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

End Sub

Salvar Dados

Para salvar todos os dadosde uma tabelautilizei o método AcceptChanges() da tabela tabelaTel. Para persistir as informações até a próxima inicialização da Agenda de Telefonearmazeneias informações do DataSet dsTelefone no arquivo XML.

Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click

Dim resposta As DialogResult

Try

resposta = MessageBox.Show("Deseja salvar as alterações?", "Aviso", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)

If resposta = DialogResult.OK Then

"Salva todas as alterações na tabela

tabelaTel.AcceptChanges()

"Grava a agenda de telefone no arquivo xml

dsTelefone.WriteXml("Agenda.xml")

MessageBox.Show("O arquivo foi salvo com sucesso!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Information)

Else

tabelaTel.RejectChanges()

End If

alterouRegistro = False

Catch ex As Exception

MessageBox.Show(ex.ToString, "Erro Interno", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

End Sub

Rotinas Auxiliares

Afunção CampoVazio() verifica se todos os campos estão preenchidos antes de fazer uma inclusão na tabela.Observe quea verificação é feita somentenosTextBox que estão dentro do GroupBox1, para isso verifico se o controle é umTextBox e se elenão está preenchido, se houver um campo vazioo programa exibe uma mensagem solicitando que todos os campos sejam preenchidos.

Private Function CampoVazio() As Boolean

"Verifica se todos os campos estão preenchidos

For Each ctl As Control In Me.GroupBox1.Controls

If TypeOf ctl Is TextBox Then

If ctl.Text = String.Empty Then

MessageBox.Show("Todos os campos devem estar preenchidos!", "Aviso", _

MessageBoxButtons.OK, MessageBoxIcon.Warning)

Return True

End If

End If

Next

Return False

End Function

A rotina LimparCampos() apaga o conteúdo dos TextBox, após uma inclusão, alteração ou exclusão. Facilitando desse modo a utilização de novos dados na Agenda de Telefone.

Private Sub LimparCampos()

For Each txt As Control In Me.GroupBox1.Controls

If TypeOf txt Is TextBox Then

txt.Text = String.Empty

End If

Next

"Desabilita os botões Alterar e Excluir

Me.btnAlterar.Enabled = False

Me.btnExcluir.Enabled = False

End Sub

Conclusão

O DataSet, DataTable e Dataview facilitam muito o trabalho de manipulação e atualizaçãode informações que podem ser armazenadas em formato detabelas.

Rosana de Oliveira

Rosana de Oliveira - MCP em VB.NET, consultora na www.romarconsultoria.com.br, desenvolvendo aplicações na plataforma .NET.