![]() |
||||||||
|
|
||||||||
|
| ||||||||


| com exemplos em VB |
| Componente para deixar forms em Vb semelhantes às telas do winnamp |
| Componente para colocar sua aplicação VB no Systray |
| Componente para transformar sua aplicação VB em serviço |
| Ferramentas úteis para quem usa Olap Server |
| |

|
||||||||||||
Pesquisa personalizada
Projeto : Acessando Indices Financeiros do Banco Central Iniciando sua adesão ao fornecimento de dados via Web o banco central disponibilizou vários índices financeiros que podem ser consultados via XML. O fato de serem fornecidos em formato XML permite que você crie uma aplicação personalizada, Windows ou Web, que faça acesso a esses índices e disponibilize estes indices diretamente em sua aplicação ou até mesmo os utilize para implementação de regras de negocio. Aproveitando a inspiração dada pelo banco central vamos implementar um projeto que nos permita consultar os índices financeiros do banco central. Neste projeto vamos estar vendo várias características do desenvolvimento .NET Vamos começar tendo uma visão geral das funcionalidades da aplicação :
Vejamos as telas que a aplicação terá :
Vamos começar a analisar os detalhes de cada tela, vamos começar pela frmIndices :
O MainMenu na aplicação deverá ter a seguinte estrutura : Atualizar
Atualizar Indices
Atualização Seletiva
Sair
Configurações
Indices
Opcoes
Já o ContextMenu terá as seguintes opções : Abrir Sair O código básico do contextMenu, do Sair e do NotifyIcon é bem simples, vejamos como fica : Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyBase.Resize
If Me.WindowState = FormWindowState.Minimized Then
Me.Hide()
End If
End Sub
Quanto aos dois Tabs do TabControl, no primeiro Tab, "Meus Indices", iremos inserir uma DataGrid. Essa dataGrid será usada para exibir os índices selecionados pelo usuários, fazendo com que possam ser consultados mais facilmente. Já no Tab "Todos os Indices" iremos inserir uma combo e 6 Labels, de forma a permitir que o usuário selecione na combo o índice que deseja visualizar e as informações a respeito deste índice aparecem nos labels.
Feito o desenho básico da tela vamos então montar as configurações da aplicação. São 4 as configurações que a aplicaçào terá :
Essas configurações precisarão ser acessadas através de toda a aplicação, não apenas no form frmConfig mas também nos locais da aplicação que forem fazer uso destas configurações. Para implementarmos isso podemos fazer com que ao invés de iniciar através de um form a aplicação se inicie com uma Sub Main. Podemos então programar a sub Main para criar uma instância de uma classe clsConfig (que vamos desenvolver) e manter esta instância disponível para toda a aplicação. Devemos então inserir um módulo para realizarmos estas tarefas. Veja como fica : Module Inicio
Public conf As clsConfig
Sub Main ()
Dim f As New frmIndices
conf = New clsConfig
Application.Run(f)
End Sub
End Module
Observe a variável conf, definida como public dentro do módulo e fora da sub main. Definida desta forma a variável conf será visivel por toda a aplicação. É um recurso útil, mas não abuse, pois variáveis públicas prejudicam a estrutura do sistema. Para dar inicio a aplicação instancia-se o formulário frmIndices e utiliza-se o Application.Run para rodar o formulário. O Application.Run gera um loop que ficará checando as mensagens enviadas pelo windows. Esse loop sempre existe quando temos um formulário rodando e garante que a thread ficará ativa, pois quando não houver nada executando a thread é suspensa. Veja como fica a classe clsConfig : Public Class clsConfig
Public Arquivo As String = Application.StartupPath & "\" & "selecionados.xml"
Dim Viniciaroculto, vautoatualizar, vautoiniciar, vcompartilharconf As Integer
Dim reg As Microsoft.Win32.RegistryKey
Public Property IniciarOculto() As Boolean
Get
Return (Viniciaroculto = 1)
End Get
Set(ByVal Value As Boolean)
Viniciaroculto = Value
reg.SetValue("IniciarOculto", Viniciaroculto)
End Set
End Property
Public Property AutoAtualizar() As Boolean
Get
Return (vautoatualizar = 1)
End Get
Set(ByVal Value As Boolean)
vautoatualizar = Value
reg.SetValue("AutoAtualizar", vautoatualizar)
End Set
End Property
Public Property AutoIniciar() As Boolean
Get
Return (vautoiniciar = 1)
End Get
Set(ByVal Value As Boolean)
vautoiniciar = Value
reg.SetValue("AutoIniciar", vautoiniciar)
End Set
End Property
Public Property CompartilharConf() As Boolean
Get
Return (vcompartilharconf = 1)
End Get
Set(ByVal Value As Boolean)
vcompartilharconf = Value
Application.CommonAppDataRegistry.SetValue("UseSameConfigForAll", vcompartilharconf)
CarregarValores()
End Set
End Property
Public Sub New()
CarregarValores()
End Sub
Private Sub CarregarValores()
vcompartilharconf = Application.CommonAppDataRegistry.GetValue("UseSameConfigForAll", 1)
If vcompartilharconf = 1 Then
reg = Application.CommonAppDataRegistry
Else
reg = Application.UserAppDataRegistry
End If
Viniciaroculto = reg.GetValue("IniciarOculto", 1)
vautoatualizar = reg.GetValue("AutoAtualizar", 1)
vautoiniciar = reg.GetValue("AutoIniciar", 1)
End Sub
End Class
Observe como fica o constructor da classe (sub new). Ele chama uma sub, CarregarValores, que inicializa todas as configurações. As configurações são lidas do Registry, utilizando classes do framework para isso. O objeto Application possui as propriedades CommonAppDataRegistry e UserAppDataRegistry . Ambas devolvem objetos do tipo RegistryKey que permitem ler e escrever do registry. A diferença entre as duas é que o CommonAppDataRegistry grava as configurações de forma compartilhada, ou seja, qualquer que seja o usuário as configurações serão as mesmas. Já o UserAppDataRegistry grava as configurações isoladas por usuário, ou seja, cada usuário pode manter configurações individualmente. Na sub carregarvalores iniciamos lendo a configuração "UseSameConfigForAll" . Com base nesta configuração definimos se as leituras seguintes serão feitas da CommonApp ou da UserApp. Guardamos então o objeto RegistryKey na variável reg e fazemos a leitura das demais configurações. Para cada configuração a classe clsConfig mantém uma propriedade. O GET da propriedade faz a leitura de um atributo privado, enquanto o SET além de gravar este atributo também faz a gravação do registry usando a variável reg, que foi cuidadosamente atribuida pelo constructor. Vamos então montar agora o núcleo de nossa aplicação, a recuperação de dados em XML do site do BC. Vamos montar uma classe, clsBuscarDados,que realizará estas tarefas em nossa aplicação. Nossa classe terá apenas um método público, IniciarAtualizacao, que será chamado para iniciar o processo de atualização. Porém terá as seguintes propriedades :
Esta classe irá também definir 2 delegates, um para o controle do progresso da atualização e outro para sinalizar a finalização da atualização. Veja como fica : Public Delegate Sub progress(ByVal i As Integer)
Public Delegate Sub Finalizou()
Vejamos então a sequencia de execução para esta classe : O constructor recebe um dataSet, um progress (o delegate acima) e um finalizou (o outro delegate acima).
Imports System.Net
Imports System.IO
Imports System.Globalization
Imports System.Windows.Forms
Imports System.Xml
Public Class clsBuscarDados
Public Delegate Sub progress(ByVal i As Integer)
Public Delegate Sub Finalizou()
Dim prg As progress
Dim fim As Finalizou
Dim ds1 As DS
Dim vInicioAtualizacao As Integer = 1
Dim vFimAtualizacao As Integer = 200
Public Sub New(ByVal Indices As DS, ByVal Progresso As progress, _
ByVal Retorno As Finalizou)
ds1 = Indices
prg = Progresso
fim = Retorno
End Sub
Private Sub inicio()
Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("pt-br")
PedeTudo(prg)
End Sub
Sub PedeTudo(ByVal p As progress)
Dim i As Integer
For i = InicioAtualizacao To FimAtualizacao
Umpedido(i)
p.Invoke(i)
Next
InicioAtualizacao = 1
FimAtualizacao = 200
Microsoft.Win32.SystemEvents.InvokeOnEventsThread(fim)
End Sub
Private Sub Umpedido(ByVal i As Integer)
Dim doc As New XmlDocument
doc.LoadXml("<SERIE><CODIGO>" & i & "</CODIGO></SERIE>")
requisita(doc)
End Sub
Private Sub requisita(ByVal doc As XmlDocument)
Dim req As HttpWebRequest
Dim res As HttpWebResponse
Dim reqstr As Stream
Dim resstr As Stream
Dim sw As StreamWriter
Dim sr As StreamReader
Dim proxy As IWebProxy
Dim docResposta As New XmlDocument
req = WebRequest.Create("http://www4.bcb.gov.br/pec/series/webservice/recebeXML.asp")
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
req.ContentLength = Len(doc.InnerXml)
reqstr = req.GetRequestStream
sw = New StreamWriter(reqstr)
sw.Write(doc.InnerXml)
sw.Close()
res = req.GetResponse
resstr = res.GetResponseStream
sr = New StreamReader(resstr)
docResposta.LoadXml(sr.ReadToEnd)
gravaregistro(docResposta)
End Sub
Private Sub gravaregistro(ByVal doc As XmlDocument)
Dim dtr As DS.moedaRow
Try
dtr = ds1.moeda.NewmoedaRow
dtr.CODIGO = doc.GetElementsByTagName("CODIGO").Item(0).InnerText
dtr.PERIODICIDADE = doc.GetElementsByTagName("PERIODICIDADE").Item(0).InnerText
dtr.NOME = doc.GetElementsByTagName("NOME").Item(0).InnerText
dtr.VALOR = doc.GetElementsByTagName("VALOR").Item(0).InnerText
dtr.UNIDADE = doc.GetElementsByTagName("UNIDADE").Item(0).InnerText
ds1.moeda.Rows.Add(dtr)
Catch er As Exception
End Try
End Sub
Public Sub IniciarAtualizacao()
Dim th As New Threading.Thread(AddressOf inicio)
th.Start()
Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("pt-br")
End Sub
Public Property InicioAtualizacao() As Integer
Get
Return (vInicioAtualizacao)
End Get
Set(ByVal Value As Integer)
vInicioAtualizacao = Value
End Set
End Property
Public Property FimAtualizacao() As Integer
Get
Return (vFimAtualizacao)
End Get
Set(ByVal Value As Integer)
vFimAtualizacao = Value
End Set
End Property
End Class
Vejamos então como será o uso desta classe. No momento em que a aplicação se iniciar deverá, conforme a configuração da aplicação, iniciar sua atualização em background. Veja como fica o load do formulário frmIndices : Private Sub frmIndices_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
If conf.AutoAtualizar Then
carga = New clsBuscarDados(Ds1, AddressOf progresso, AddressOf CarregarDados)
carga.IniciarAtualizacao()
End If
End Sub
A variável conf foi definida como pública dentro de um módulo, então ao fazer o load do frmIndices verificamos a configuração de AutoAtualizar e disparamos o processo de atualização. Agora que codificamos a carga dos dados vamos configurar o 2o tab, "Todos os Indices" . Vamos inserir uma combo chamada cmbIndices e 6 labels, para exibir o valor do índice, a unidade utilizada e a periodicidade de atualização do índice. Vamos vincular a combo com a tabela Indices. A única coisa que precisaremos fazer então é programar o evento SelectedIndexChanged da combo para exibir os detalhes do índice, veja como fica :
Vamos agora configurar a chamada e programar as telas secundárias. Temos duas : A tela de configuração da aplicação e a tela de seleção dos índices que aparecerão na entrada do sistema. O usuário apenas deverá poder abrir uma instância de cada tela. Para garantirmos isso vamos utilizar o seguinte procedimento :
Veja como fica : No form principal :
Observe que transmitimos o dataset com a lista de índices para o formulário de índices, para que possa utilizar este dataSet para montar a checkedListBox para o usuário selecionar os índices. No form de seleção de índices : Private Sub SelecionarIndices_Closing(ByVal sender As Object, ByVal e As _
System.ComponentModel.CancelEventArgs) _
Handles MyBase.Closing
e.Cancel = True
Me.Hide()
End Sub
Vamos então completar o código do formulário de configurações. Já criamos um pouco antes a classe de configurações e deixamos uma instância dela acessível a todo o sistema. Pois então o código será simples : Deveremos no load do form preencher as checkbox de acordo com os valores desta classe, enquanto que no botão Ok preencheremos a classe de acordo com as mudanças nas checkbox. Veja como fica : Private Sub frmConfig_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
chk1.Checked = conf.IniciarOculto
chk2.Checked = conf.AutoAtualizar
chk3.Checked = conf.AutoIniciar
chk4.Checked = conf.CompartilharConf
End Sub
Private Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cmdOK.Click
conf.IniciarOculto = chk1.Checked
conf.AutoIniciar = chk3.Checked
conf.AutoAtualizar = chk2.Checked
conf.CompartilharConf = chk4.Checked
Me.Close()
End Sub
O próximo passo é a seleção de índices. Vamos guardar os índices selecionados em um arquivo XML, por isso a classe de configuração tem uma propriedade "arquivo", para guardar o nome do arquivo.
Então quando o usuário entrar no formulário para selecionar os índices que deseja visualizar na tela principal da aplicação iremos ler este XML. O conteúdo do XML irá determinar quais já estarão previamente selecionados. Já a lista de índices será obtida do dataSet com todos os índices, que foi passado para este formulário. Veja como fica : Private Sub SelecionarIndices_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
chklstIndices.DataSource = Ds1.moeda
chklstIndices.DisplayMember = "NOME"
chklstIndices.ValueMember = "CODIGO"
Ds1.moeda.DefaultView.Sort = "CODIGO"
If IO.File.Exists(conf.Arquivo) Then
Dim drv As DataRowView
DsSelecionados1.ReadXml(conf.Arquivo)
For Each drv In DsSelecionados1.Selecionados.DefaultView
chklstIndices.SetItemCheckState(chklstIndices.Items.IndexOf( _
Ds1.moeda.DefaultView.FindRows(drv("indice"))(0)), _
CheckState.Checked)
Next
End If
End Sub
Se o arquivo XML existir ele é carregado e é feito um laço para marcar os itens selecionados, que estão contidos no arquivo XML. Quando o usuário alterar a seleção e der ok precisaremos atualizar o XML, veja :
Private Sub cmdRegistrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cmdRegistrar.Click
Dim drv As DataRowView
DsSelecionados1.Clear()
For Each drv In chklstIndices.CheckedItems
DsSelecionados1.Selecionados.Rows.Add(New String() {drv("CODIGO")})
Next
DsSelecionados1.WriteXml(conf.Arquivo, Data.XmlWriteMode.WriteSchema)
Me.Close()
End Sub
Neste caso recriamos o XML, utilizando para isso um dataset tipado criado especialmente para esta finalidade. Para cada indice selecionado pelo usuário criamos uma nova linha neste dataset e ao final regravamos o XML, sobrescrevendo seu conteúdo. O próximo passo será então realizar a carga dos índices selecionados na grid no momento em que a aplicação se iniciar. Porém já organizamos o load do form principal para iniciar a carga dos dados em background. Os índices selecionados só poderão ser exibidos após essa carga de dados acontecer. Por isso, no código do form_load, um pouco acima, transmitimos para o método iniciarAtualização o endereço de uma sub chamada CarregarDados. Essa sub será chamada ao término da carga de dados em background e irá realizar a seleção dos índices e exibição. Veja como fica a CarregarDados : Sub CarregarDados()
prog.Visible = False
If IO.File.Exists(conf.Arquivo) Then
dsPrincipais.Clear()
DsSelecionados1.Clear()
Dim drv As DataRow
DsSelecionados1.ReadXml(conf.Arquivo)
Ds1.moeda.PrimaryKey = New DataColumn() {Ds1.moeda.CODIGOColumn}
For Each drv In DsSelecionados1.Selecionados
dsPrincipais.moeda.ImportRow(Ds1.moeda.Rows.Find(drv("indice")))
Next
DG.DataSource = dsPrincipais.moeda
End If
End Sub
A carregarDados, conforme o código acima, verifica se o XML de indices selecionados existe. Se existe, ele é carregado para o dataSet de itens selecionados. É realizado um laço através da tabela deste dataSet. Para cada índice selecionado este é localizado no dataSet de índices e importado para o dataset que será exibido na Grid inicial do Form
Como um recurso adicional para a nossa aplicação, falta permitirmos que seja realizada uma atualização seletiva, ou seja, que a aplicação consulte o banco central para atualizar apenas alguns índices, ao invés de todos.
Primeiramente vamos criar algumas validações no formulário de atualizacaoSeletiva, veja como fica : Private Sub ValidandoValores(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) _
Handles txtInicio.Validating, txtFim.Validating
Dim t As TextBox
t = sender
If Not IsNumeric(t.Text) Then
ER.SetError(t, "É necessário informar um valor numérico")
e.Cancel = True
ElseIf t.Text > 200 OrElse t.Text < 1 Then
ER.SetError(t, "O valor precisa estar entre 1 e 200")
e.Cancel = True
End If
End Sub
Neste exemplo podemos ver um interessante truque combinado com o Handles e o uso do ErrorProvider, tudo contribuindo para que os valores digitados nas caixas de texto deste form sejam realmente válidos. Uma forma interessante de fazer com que esses valores possam ser acessados fora deste formulário e ainda assim manter o encapsulamento é através do uso de propriedades. Então podemos utilizar 2 propriedades, uma para o valor inicial e outra para o valor final. Veja como fica : Public Property Inicio() As Integer
Get
Return (txtInicio.Text)
End Get
Set(ByVal Value As Integer)
txtInicio.Text = Value
End Set
End Property
Public Property Fim() As Integer
Get
Return (txtInicio.Text)
End Get
Set(ByVal Value As Integer)
txtFim.Text = Value
End Set
End Property
Vamos então causar o disparo deste formulário. Vamos chama-lo de forma modal e com o resultado do formulário vamos configurar a classe de carga de dados e disparar uma recarga em background, só que desta vez estará sendo uma recarga parcial. Veja como fica : Private Sub mnuAtualizacaoSel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles mnuAtualizacaoSel.Click
Dim f As New frmAtualizacaoSeletiva
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then
carga.InicioAtualizacao = f.Inicio
carga.FimAtualizacao = f.Fim
carga.IniciarAtualizacao()
End If
End Sub
Observe como este trecho faz uso do dialogResult para identificar se o usuário pressionou Ok ou pediu para cancelar a atualização seletiva. Pronto. Com isso completamos a montagem de nossa aplicação que permitirá consultar índices financeiros no banco central. Neste exemplo foi possível vermos várias características do desenvolvimento com .NET, tal como requisições Web, comunicação entre forms, uso do Registry, entre outros recursos.
|
||||||||||||
|
Veja abaixo os comentários já enviados :
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Quer
saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e Prepare-se para o Mercado! Veja o que a Búfalo tem para você. |
||||||||||||
� Búfalo Informática,
Treinamento e Consultoria -
Rua Álvaro Alvim, 37 Sala 920 - Cinelândia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail: contato@bufaloinfo.com.br