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