VB.NET - Controle de visitas
médicas - II
Este artigo é continuação do VB.NET - Controle de visitas médicas - I , se você não leu o artigo anterior clique no link e acompanhe a definição das tabelas da base de dados e do dataset tipado.
Nota: Para saber mais sobre datasets tipados veja os artigos:
Nossa aplicação tem por objetivo registrar as visitas a pacientes e gerar uma receita para cada paciente com os dados cadastrados para pacientes , medicamentos e diagnósticos. A aplicação deverá efetuar portanto o cadastro de pacientes , medicamentos e diagnósticos para em seguida registrar as visitas feitas usando os dados cadastrados.
Vamos criar o formulário de menu da aplicação incluindo um novo formulário no projeto com o nome de Menu.vb e definindo a sua propriedade isMdiContainer como True. A seguir inclua um componente no MenuStrip no formulário e crie um menu com as seguintes opções:
![]() |
![]() |
Vamos agora incluir um novo formulário com o nome de pacientes.vb. Neste formulário será efetuado o cadastro dos pacientes. Vamos usar o assistente do VB 2005. Abra a janela Data Sources e selecione a tabela pacientes clicando a seguir na seta para baixo. Selecione a opção Details e a seguir arraste e solte a tabela no formulário criado. O assistente irá criar os campos da tabela e todo o menu para navegação e realização das operações CRUD (create, read, update e delete) no formulário. Veja na figura abaixo:
![]() |
Devemos incluir mais dois formulários: medicamentos.vb e diagnosticos.vb e repetir a operação feita acima usando as tabelas medicamentos e diagnosticos de forma a criar os formulários conforme abaixo:
![]() |
![]() |
O formulário de visitas é o mais complexo pois nele devemos ter as informações cadastradas para além de atualizar as tabelas de visitas, pacienteMedicamentos e pacienteDiagnosticos também gerar o receituário para o paciente com gravação do arquivo com nome do paciente e impressão do mesmo.
Abaixo temos o leiaute do formulário contendo os controles relativos aos dados que deverão ser exibidos ou informados.
![]() |
Inclua um novo formulário visitas.vb no seu projeto. Menu Project opção Add Windows Form...
![]() |
Para poder exibir os pacientes
cadastrados vamos usar um controle combobox para fazer isto na janela
Data Sources selecione a tabela pacientes e selecione a opção Combobox
arrastando em seguida a tabela para o formulário visitas.vb. Serão criados os componentes no formulário:
Selecione o componente visual PacientesBindingNavigator e o exclua do projeto. Se você espiar o evento Load do formulário irá ver que o assistente criou a seguinte linha de código: Me.PacientesTableAdapter.Fill(Me.DiagnosticoDataSet.pacientes) Esta linha de código irá preencher a combobox
com os dados dos pacientes cadastrados que é exatamente o que queremos
obter. A combobox é identificada por pacientesComboBox. |
Vamos repetir o processo acima para criar a combobox que irá exibir os diagnósticos cadastrados: diagnosticosComboBox (usando a tabela diagnosticos) e para a combobox que irá exibir os medicamentos cadastrados: MedicamentosCombobox (usando a tabela medicamentos). Clique na tabela na janela Data Sources selecione a opção ComboBox, arraste a tabela para o formulário e exclua o componente BindingNavigator.
Com isto já podemos selecionar o paciente e o diagnóstico para o paciente, mas aqui temos um problema, pois podemos ter mais de um medicamento indicado para o paciente/diagnóstico em questão. Para resolver isto vamos incluir um controle ListBox(lstbMedicamentos) e um botão de comando para que possamos selecionar um medicamento e clicando no botão de comando incluir o medicamento no ListBox com isto podermos indicar mais de um medicamento para o paciente/diagnóstico.
A solução adotada acima nos remete a um outro problema: devemos atualizar a tabela pacienteMedicamentos com o ID do medicamento mas temos somente o nome do mesmo na ListBox(lstbMedicamentos). Para poder obter o ID de cada medicamento incluído no controle ListBox temos que criar uma classe para obter esta informação. Inclua um módulo de classe no projeto; no menu Project selecione a opção Add Class e informe o nome lbMedicamentos.vb e no módulo inclua o seguinte código:
Nota: A ausência da propriedade ItemData presente no VB5/VB6 deverá ser criada usando a classe. Para saber mais sobre o assunto leia o artigo: VB.NET - Ressuscitando a propriedade ItemData
Public Class lbMedicamentos Private sNome As String Private iID As Integer ' construtor padrão vazio Public Sub New() sNome = "" iID = 0 End Sub Public Sub New(ByVal Nome As String, ByVal ID As Integer) sNome = Nome iID = ID End Sub Public Property Nome() As String Get Return sNome End Get Set(ByVal sValue As String) sNome = sValue End Set End Property 'esta propriedade irá obter o ID do item do listbox Public Property ItemData() As Int32 Get Return iID End Get Set(ByVal iValue As Int32) iID = iValue End Set End Property Public Overrides Function ToString() As String Return sNome End Function End Class |
Vamos voltar a falar sobre esta classe quando comentarmos o código da aplicação.
Inclua um controle TextBox (txtNotas) para informar as recomendações do médico ao paciente. Inclua também 3 botões de comando : btnSalvar , btnDescartar e btnSalvaImprime.
Nota: Devemos incluir arrastar e soltar as tabelas pacientesMedicamentos e pacienteDiagnosticos para o formulário para obtermos os componentes Adapter correspondentes.
Ao final desta etapa o formulário deverá exibir além dos controles incluídos os componentes no formulário conforme figura abaixo:
![]() |
Analisando o código da aplicação
Se você espiar o evento Load do formulário visitas.vb irá notar que o assistente já criou o código para preencher os TableAdapters criados.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'TODO: This line of code loads data into the 'DiagnosticoDataSet.visitas' table. You can move, or remove it, as needed. Me.VisitasTableAdapter.Fill(Me.DiagnosticoDataSet.visitas) 'TODO: This line of code loads data into the 'DiagnosticoDataSet.pacienteDiagnosticos' table. You can move, or remove it, as needed. Me.PacienteDiagnosticosTableAdapter.Fill(Me.DiagnosticoDataSet.pacienteDiagnosticos) 'TODO: This line of code loads data into the 'DiagnosticoDataSet.pacienteMedicamentos' table. You can move, or remove it, as needed. Me.PacienteMedicamentosTableAdapter.Fill(Me.DiagnosticoDataSet.pacienteMedicamentos) 'TODO: This line of code loads data into the 'DiagnosticoDataSet.medicamentos' table. You can move, or remove it, as needed. Me.MedicamentosTableAdapter.Fill(Me.DiagnosticoDataSet.medicamentos) 'TODO: This line of code loads data into the 'DiagnosticoDataSet.diagnosticos' table. You can move, or remove it, as needed. Me.DiagnosticosTableAdapter.Fill(Me.DiagnosticoDataSet.diagnosticos) 'TODO: This line of code loads data into the 'DiagnosticoDataSet.pacientes' table. You can move, or remove it, as needed. Me.PacientesTableAdapter.Fill(Me.DiagnosticoDataSet.pacientes) End Sub |
O código do formulário principal que contém o menu de opções do sistema é o formulário menu.vb que irá abrir os demais formulários como formulários filhos do formulário MDI é dado a seguir:
Public Class MenuPrivate Sub PacientesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PacientesToolStripMenuItem.Click My.Forms.pacientes.MdiParent = Me My.Forms.pacientes.Show() End Sub Private Sub MedicamentosToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MedicamentosToolStripMenuItem.Click My.Forms.medicamentos.MdiParent = Me My.Forms.medicamentos.Show() End Sub Private Sub DiagnósticosToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DiagnósticosToolStripMenuItem.Click My.Forms.diagnosticos.MdiParent = Me My.Forms.diagnosticos.Show() End Sub Private Sub RegistrarVisitaToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RegistrarVisitaToolStripMenuItem.Click My.Forms.visitas.MdiParent = Me My.Forms.visitas.Show() End Sub Private Sub SobreToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SobreToolStripMenuItem.Click My.Forms.sobre.MdiParent = Me My.Forms.sobre.Show() End Sub Private Sub SairToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SairToolStripMenuItem.Click If (MsgBox("Confirma encerramento da aplicação ? ", MsgBoxStyle.YesNo) = MsgBoxResult.Yes) Then Me.Close() End If End Sub End Class |
Vamos criar o código do evento Click do botão - Receitar Medicamento - ele deverá obter o medicamento selecionado no combobox e incluir no ListBox. Inclua o código abaixo no evento Click do botão:
Private
Sub
btnIncluiMedicamento_Click(ByVal
sender As System.Object,
ByVal e
As System.EventArgs)
Handles
btnIncluiMedicamento.Click'obtem o
ID e o nome do medicamento e usando a classe lbMedicamanto inclui no
controle ListBox Dim medicamentoID As Integer = Convert.ToInt32(MedicamentosComboBox.SelectedValue) Dim medicamentoNome As String = CType((MedicamentosComboBox.SelectedItem), System.Data.DataRowView).Row.ItemArray(1).ToString lstbMedicamentos.Items.Add( New lbMedicamentos(medicamentoNome, medicamentoID)) End Sub |
As duas primeiras linhas de código obtêm o ID e o nome do medicamento a partir do combobox. Agora perceba a última linha de código; nela estamos incluindo o item selecionado na ListBox(lstbMedicamentos) usando a classe lbMedicamentos que foi criada para permitir a recuperação do ID do medicamento da ListBox, simulando a propriedade ItemData.
Vejamos a seguir o código do evento Click do botão - Gravar Registro e gera receituário:
Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click'obtem o ID e o nome do paciente Dim pacienteID As Integer = Convert.ToInt32(PacientesComboBox.SelectedValue) pacienteNome = CType((PacientesComboBox.SelectedItem), System.Data.DataRowView).Row.ItemArray(1).ToString'obtem o ID e a descrição do diagnóstico Dim diagnosticoID As Integer = Convert.ToInt32(DiagnosticosComboBox.SelectedValue) Dim diagnosticoDescricao As String = CType((DiagnosticosComboBox.SelectedItem), System.Data.DataRowView).Row.ItemArray(1).ToString 'define a data/hora como sendo a atual Dim datainicio As DateTime = DateTime.Now 'atualiza as tabelas de visitas e de PacientesDiagnosticos Me.VisitasTableAdapter.Insert(pacienteID, datainicio, txtNotas.Text) Me.PacienteDiagnosticosTableAdapter.Insert(pacienteID, diagnosticoID) Dim listaMedicamentos As lbMedicamentos Dim medicamentos As String = "" 'percorre o ListBox com os medicamentos receitados e inclui na receita For i As Integer = 0 To Me.lstbMedicamentos.Items.Count - 1 'selecione o item Me.lstbMedicamentos.SetSelected(i, True) ' Obtem o item selecionado listaMedicamentos = lstbMedicamentos.Items(lstbMedicamentos.SelectedIndex) 'inclui o item na tabela PacienteMedicamentos Dim nIncluido As Integer = PacienteMedicamentosTableAdapter.Insert(pacienteID, listaMedicamentos.ItemData, datainicio) medicamentos = medicamentos & (lstbMedicamentos.SelectedItem).ToString & vbCrLf
MessageBox.Show( "Não foi possivel receitar o medicamento", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)End If Next End Sub |
Este código obtém os dados informados e usando o método Insert do objeto TableAdapter atualiza as tabelas pertinentes. Note que como recuperamos o ID do medicamento usando a propriedade ItemData da classe lbMedicamentos.
Criando o arquivo .doc para mesclar os dados da aplicação
Mas o código não esta completo devemos poder mesclar as informações com o documento Word para gerar a receita para o paciente com seu diagnóstico , medicamento e recomendações.
Vamos criar no Word , eu estou usando o Word 2003, um documento chamado receita.doc contendo as seguintes informações:
![]() |
Salve o arquivo em um diretório separado, eu usei a pasta d:\teste\. Neste documento as variáveis estão sendo identificadas pelo símbolo @ no início das mesmas pois iremos substituir cada uma delas com informações vindas da aplicação VB.
Agora podemos concluir o código do botão - Gravar Registro e gera receituário:
Private Sub btnSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click'obtem o ID e o nome do paciente Dim pacienteID As Integer = Convert.ToInt32(PacientesComboBox.SelectedValue) pacienteNome = CType((PacientesComboBox.SelectedItem), System.Data.DataRowView).Row.ItemArray(1).ToString'obtem o ID e a descrição do diagnóstico Dim diagnosticoID As Integer = Convert.ToInt32(DiagnosticosComboBox.SelectedValue) Dim diagnosticoDescricao As String = CType((DiagnosticosComboBox.SelectedItem), System.Data.DataRowView).Row.ItemArray(1).ToString 'define a data/hora como sendo a atual Dim datainicio As DateTime = DateTime.Now 'atualiza as tabelas de visitas e de PacientesDiagnosticos Me.VisitasTableAdapter.Insert(pacienteID, datainicio, txtNotas.Text) Me.PacienteDiagnosticosTableAdapter.Insert(pacienteID, diagnosticoID) Dim listaMedicamentos As lbMedicamentos Dim medicamentos As String = "" 'percorre o ListBox com os medicamentos receitados e inclui na receita For i As Integer = 0 To Me.lstbMedicamentos.Items.Count - 1 'selecione o item Me.lstbMedicamentos.SetSelected(i, True) ' Obtem o item selecionado listaMedicamentos = lstbMedicamentos.Items(lstbMedicamentos.SelectedIndex) 'inclui o item na tabela PacienteMedicamentos Dim nIncluido As Integer = PacienteMedicamentosTableAdapter.Insert(pacienteID, listaMedicamentos.ItemData, datainicio) medicamentos = medicamentos & (lstbMedicamentos.SelectedItem).ToString & vbCrLf
MessageBox.Show( "Não foi possivel receitar o medicamento", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)End If Next 'inicia geração da receita com substituição dos valores Try 'Instancia a Aplicação Word. objWord = CreateObject("Word.Application") 'Abre o documento aviso.doc do Microsoft Word. objWord.Documents.Open("d:\teste\receita.doc") 'Procura pela palavra "@escola" e substitui pelo conteúdo indicado SubstituiVariavel("@clinica", "JcmSoft - Clinica Geral") SubstituiVariavel( "@medico", "Dr. José Carlos Macoratti")SubstituiVariavel( "@data", Today)SubstituiVariavel( "@endereco", "SHS 912 Conjunto C Bloco A Sala 21")SubstituiVariavel( "@cidade", "Brasilia-DF")SubstituiVariavel( "@paciente", pacienteNome)SubstituiVariavel( "@diagnostico", diagnosticoDescricao)SubstituiVariavel( "@medicamentos", medicamentos) If txtNotas.Text.Length > 0 ThenSubstituiVariavel( "@recomendacao", txtNotas.Text) End IfSubstituiVariavel( "@clinico", "Dr. Jose C. Macoratti")
'torna o Word visivel objWord.visible = True'habilita o botão para fechar o word sem salvar Else fechaWord() End If Catch ex As ExceptionMsgBox( "Ocorreu um erro durante a geração do receituário", MsgBoxStyle.Critical, "Erro")objWord.ActiveDocument.Close( False)objWord.Quit() objWord = NothingMsgBox(ex.Message) End Try
|
Para podermos usar este código temos que efetuar uma referência COM no nosso projeto. Existem outras formam de efetuar uma chamada a uma aplicativo Office a partir do VB.NET. Para referenciar o Word no seu projeto clique com o botão direito do mouse sobre o nome do projeto selecione a opção Add Reference. A seguir clique na guia COM da janela Add Reference e selecione a opção : Microsoft Word 11.0 Object Library (pode haver variações dependendo da sua versão do Word).
![]() |
A seguir temos o código da rotina SubstituiVariavel que irá mesclar as informações da aplicação VB com o arquivo .doc.
Private Sub SubstituiVariavel(ByVal Achar As String, ByVal Substituir As String) 'procura a variável e substitui o valor With objWord.Selection.Find .Text = Achar.ToString .Replacement.Text = Substituir.ToString .Forward = True .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False While .Execute = True objWord.Selection.Select() System.Windows.Forms.Clipboard.SetDataObject(Substituir) objWord.Selection.Paste() End While End With End Sub
|
A seguir o código dos demais botões de comando:
Private Sub btnSalvaImprime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvaImprime.Click fechaWord(pacienteNome) End Sub Private Sub btnDescartar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDescartar.Click Me.Close() End Sub |
A rotina fechaWord irá salvar e imprimir o documento Word usando o nome do paciente com a extensão doc no caminho definido. Perceba que o parâmetro pacienteNome é opcional e por isto tem que ter um valor padrão definido. Se o nome for passado o arquivo é salvo e impresso e somente depois será fechado.
Private Sub fechaWord(Optional ByVal pacienteNome As String = "") 'se o nome do paciente foi usado como parâmetro salva o arquivo e imprime If pacienteNome.Length > 0 Then objWord.ActiveDocument.SaveAs(FileName:=caminho & pacienteNome & ".doc", LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:=False) objWord.Application.PrintOut(FileName:="", Copies:=1, Pages:="", ManualDuplexPrint:=False, Collate:=True, Background:=True, PrintToFile:= _ False, PrintZoomColumn:=0, PrintZoomRow:=0, PrintZoomPaperWidth:=0, _ PrintZoomPaperHeight:=0) End If 'Fecha o documento Word objWord.ActiveDocument.Close(False) 'Fecha o Word objWord.Quit() objWord = Nothing End Sub
|
Inclua no início do código do formulário as seguintes declarações para o objeto Word , para o caminho do arquivo .doc a ser salvo e para o nome do paciente.
Dim
objWord As ObjectJá podemos rodar a aplicação e ver o resultado conforme exibido nas figuras a seguir:
1- O formulário visitas.vb preenchido com os dados já cadastrados:
![]() |
2- Ao clicar no botão - Gravar Registro e gerar receituário, as informações são mescladas com o arquivo receita.doc , o arquivo é salvo e impresso na impressora padrão. Abaixo o arquivo .doc exibindo as informações após efetuar a substituição das variáveis.
![]() |
Como eu já mencionei existem maneiras mais elegantes para usar os aplicativos Office do que apelar para o COM , em futuros artigos estarei abordando estas possibilidades. De qualquer forma, como você acompanhou é bem simples criar o seu aplicativo no VB 2005 e fazer a integração com o Word.
O texto do arquivo receita.doc é meramente ilustrativo e você pode fazer os ajustes necessários as suas necessidades bem como usar o seu talento para aperfeiçoar o projeto expandido-o com novas funcionalidades.
Nota: Se você analisar com cuidado a normalização utilizada irá verificar que alguns ajustes serão necessários dependendo do ajuste que você pretende fazer na aplicação.
O projeto completo esta no Super DVD .NET (com opção de relatórios via printDocument)
Até o próximo artigo ...
José Carlos Macoratti