VB .NET- Criando um gráfico no Excel


Este artigo mostra mais uma vez como interagir com o Microsoft Excel usando a linguagem VB .NET , desta vez vamos criar um gráfico no Excel a partir de uma aplicação VB .NET.

Você vai precisar ter instalado os seguintes recursos:

Abra o Visual Basic 2010 Express e crie um projeto via menu File-> New Project do tipo Windows Forms Application com o nome GraficoExcel;

Agora vamos incluir uma referência em nosso projeto a biblioteca Microsoft.Office.Interop.Excel;

No menu Project clique em Add Reference;

Na janela Add Reference clique na guia COM e selecione : Microsoft Excel 12.0 Object Library e clique em OK;

Vamos definir o código do formulário form1.cs definindo os namespaces a serem usados :

Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Runtime.InteropServices

A seguir vamos definir as variáveis para o Excel, a pasta de trabalho e a planilha logo após a declaração do formulário :

Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet

Agora vamos incluir dois botões de comando no formulário :

e um imagem de enfeite no fundo do formulário conforme o leiaute abaixo:

No evento Click do botão de comando - Gerar Gráfico no Excel - vamos digitar o código que irá criar a planilha e o gráfico no Excel:

 Private Sub btnGerarGraficoExcel_Click(sender As System.Object, e As System.EventArgs) Handles btnGerarGraficoExcel.Click

        xlApp = New Excel.Application

        '~~> Inclui um novo WorkBook
        xlWorkBook = xlApp.Workbooks.Add

        '~~> Exibe o Excel janela normal
        xlApp.Visible = True
        xlApp.WindowState = Excel.XlWindowState.xlNormal

        '~~> Define a planilha com a qual vamos trabalhar
        xlWorkSheet = xlWorkBook.Sheets("Plan1")

        With xlWorkSheet
            '~~> Inclui diretamente os valores na planilha
            .Range("A1").Value = "Mês - Ano 2012"
            .Range("A2").Value = "Janeiro"
            .Range("A3").Value = "Fevereiro"
            .Range("A4").Value = "Março"
            .Range("A5").Value = "Abril"

            .Range("B1").Value = "Vendas (Quantidade)"
            .Range("B2").Value = "1000"
            .Range("B3").Value = "1500"
            .Range("B4").Value = "1200"
            .Range("B5").Value = "1100"

            '~~> Define os títulos
            .Range("A6").Value = "Total Vendas"
            .Range("A7").Value = "Média Vendas"

            '~~> Inclui as forrmulas
            .Range("B6").Formula = "=Sum(B2:B5)"
            .Range("B7").Formula = "=Average(B2:B5)"

            '~~> Altera o intervalo no formato tabular
            .ListObjects.Add(Excel.XlListObjectSourceType.xlSrcRange, .Range("$A$1:$B$7"), , Excel.XlYesNoGuess.xlYes).Name = "Table1"

            '~~> Formata a tabela
            .ListObjects("Table1").TableStyle = "TableStyleLight8"

            '~~> Formata o total e a media nas células
            With .Range("A6:A7")
                .Interior.ColorIndex = 1 '<~~ cor de fundo
                With .Font
                    .ColorIndex = 2 '<~~ cor da fonte
                    .Size = 10
                    .Name = "Verdana"
                    .Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle
                    .Bold = True
                End With
            End With

            '~~> Ajusta os textos das colunas
            .Columns("A:B").EntireColumn.AutoFit()

            '~~> Insere o gráfico a partir dos dados da planilha Plan1
            .Shapes.AddChart.Select()
            xlApp.ActiveChart.ApplyCustomType(Excel.XlChartType.xlLineMarkers)
            xlApp.ActiveChart.SetSourceData(Source:=.Range("Plan1!$A$1:$B$5"))

        End With
    End Sub

Executando o projeto e clicando neste botão iremos obter a planilha e respectivo gráfico a seguir:

Agora temos que encerrar o Excel e liberar os recursos usados representados pelos objetos xlApp, xlWorkBook e xlWorkSheet.

Para isso vamos criar uma rotina que libera esses objetos com o nome liberarObjetos() que recebe um objeto como parâmetro e usa o método ReleaseComObject que diminui a contagem de referência de Runtime Callable Wrapper especificado (RCW) associado ao objeto COM especificado.

Este método é usado para controlar explicitamente o tempo de vida de um objeto COM usado de código gerenciado. Você deve usar este método para liberar o objeto COM base que contém as referências aos recursos em tempo hábil ou quando os objetos devem ser liberados em uma ordem específica.

  Private Sub liberarObjetos(obj As Object)
        Try
            Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
            MessageBox.Show("Ocorreu um erro durante a liberação do objeto " + ex.ToString())
        Finally
            GC.Collect()
        End Try
    End Sub

O método utiliza o Garbage Collector - GC para liberar os objetos da memória.

O coletor de lixo (garbage collector) conhecido também como gc, é usado para retirar objetos instanciados na memória mas que não estão sendo mais usados(referenciados). Este recurso, disponível na Linguagens .NET permite que você otimize o seu código, deixando ele mais rápido, e com isso ganhando produtividade O que o gc efetua é na verdade um gerenciamento automático de memória que automaticamente libera blocos de memória que não serão mais usados em uma aplicação.

No evento Click do botão de comando - Encerrar Excel e liberar Recursos - temos o código que chama esta rotina para liberar os objetos, mas, antes de fazer isso temos que verificar se existe um processo do Excel em execução. Vamos criar uma função que verifica isso com o nome VerificaExcel e retorna True ou False conforme o código a seguir:

 Private Function VerificaExcel() As Boolean
        'verifica se existe um processo rodando normal
        If UBound(Diagnostics.Process.GetProcessesByName("EXCEL")) >= 0 Then
            Return True
        Else
            Return False
        End If
    End Function 

A classe Process do namespace System.Diagnostic pode ser usada para iniciar e parar processos , controlar e monitorar aplicações.

Usando a classe Process você pode obter informações sobre processos e aplicações , pode também usá-la para criar uma instância de uma aplicação ou parar um processo que esta sendo executado.

O código verifica se existem processos para o Excel em execução e em caso positivo retorna True.

Finalmente no evento Click podemos agora definir o código que vai encerrar o Excel e liberar os objetos:

Private Sub btnEncerrar_Click(sender As System.Object, e As System.EventArgs) Handles btnEncerrar.Click
        If VerificaExcel() = True Then

            'fechar sem salvar
            xlWorkBook.Close(False)
            xlApp.Quit()

            liberarObjetos(xlWorkSheet)
            liberarObjetos(xlWorkBook)
            liberarObjetos(xlApp)

            For Each proc In Diagnostics.Process.GetProcessesByName("EXCEL")
                proc.Kill()
            Next
        Else
            MessageBox.Show("Todas as instãncias do Excel já foram fechadas.")
        End If
    End Sub

Estou encerrando o Excel sem salvar os dados pois eles podem ser gerados novamente via código para encerrar e salvar altere a linha de código que fecha o WorkBook para: xlWorkBook.Close(true)

Note que após liberar os objetos estamos matando os processo do Excel em execução usando o método Kill que para o processo associado.

Obs: O método Process.CloseMainWindow também fecha um processo que tem um interface com o usuário enviando uma mensagem de fechamento para sua janela.

O método Kill força uma finalização do processo, enquanto CloseMainWindow apenas solicita um encerramento.

Melhorando a aparência do Gráfico

Vamos incluir um novo botão de comando (btnGraficoMelhorado) no formulário que irá gerar o mesmo gráfico só que vamos incrementar a sua aparência aplicando algumas formatações.

A seguir vamos incluir o código abaixo no evento Click deste botão de comando:

  Private Sub btnGraficoMelhorado_Click(sender As System.Object, e As System.EventArgs) Handles btnGraficoMelhorado.Click
        xlApp = New Excel.Application

        '~~> Inclui um novo WorkBook
        xlWorkBook = xlApp.Workbooks.Add

        '~~> Exibe o Excel janela normal
        xlApp.Visible = True
        xlApp.WindowState = Excel.XlWindowState.xlNormal

        '~~> Define a planilha com a qual vamos trabalhar
        xlWorkSheet = xlWorkBook.Sheets("Plan1")

        With xlWorkSheet
            '~~> Inclui diretamente os valores na planilha
            .Range("A1").Value = "Mês - Ano 2012"
            .Range("A2").Value = "Janeiro"
            .Range("A3").Value = "Fevereiro"
            .Range("A4").Value = "Março"
            .Range("A5").Value = "Abril"

            .Range("B1").Value = "Vendas (Valores)"
            .Range("B2").Value = "1000"
            .Range("B3").Value = "1500"
            .Range("B4").Value = "1200"
            .Range("B5").Value = "1100"

            '~~> Define os títulos
            .Range("A6").Value = "Total Vendas"
            .Range("A7").Value = "Média Vendas"

            '~~> Inclui as forrmulas
            .Range("B6").Formula = "=Sum(B2:B5)"
            .Range("B7").Formula = "=Average(B2:B5)"

            '~~> Altera o intervalo no formato tabular
            .ListObjects.Add(Excel.XlListObjectSourceType.xlSrcRange, .Range("$A$1:$B$7"), , Excel.XlYesNoGuess.xlYes).Name = "Table1"

            '~~> Formata a tabela
            .ListObjects("Table1").TableStyle = "TableStyleLight8"

            '~~> Formata o total e a media nas células
            With .Range("A6:A7")
                .Interior.ColorIndex = 1 '<~~ cor de fundo
                With .Font
                    .ColorIndex = 2 '<~~ cor da fonte
                    .Size = 10
                    .Name = "Arial"
                    .Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle
                    .Bold = True
                End With
            End With

            '~~> Ajusta os textos das colunas
            .Columns("A:B").EntireColumn.AutoFit()

            '~~> Inserindo o gráfico
            .Shapes.AddChart.Select()

            '~~> formatando o grafico
            With xlApp.ActiveChart
                '~~> define um grafico de linhas
                .ApplyCustomType(Excel.XlChartType.xlLineMarkersStacked)

                '~~> definindo o intervalo de dados
                .SetSourceData(Source:=xlWorkSheet.Range("$A$1:$B$5"))

                '~~> preenchendo o fundo do gráfico
                xlApp.ActiveChart.ChartArea.Format.Fill.ForeColor.ObjectThemeColor = _
                Microsoft.Office.Core.MsoThemeColorIndex.msoThemeColorBackground2
                xlApp.ActiveChart.ChartArea.Format.Fill.ForeColor.TintAndShade = 0
                xlApp.ActiveChart.ChartArea.Format.Fill.Transparency = 0
                xlApp.ActiveChart.ChartArea.Format.Fill.Solid()

                '~~> arrendodando os cantos do grafico
                .Parent.RoundedCorners = True

                '~~> Removendo as linha e a cor de fundo 
                With .PlotArea
                    .Format.Fill.Visible = Microsoft.Office.Core.MsoTriState.msoFalse
                    .Format.Line.Visible = Microsoft.Office.Core.MsoTriState.msoFalse
                End With

                '~~> Removendo as linhas de grade
                .Axes(Excel.XlAxisType.xlValue).MajorGridlines.Format.Line.Visible = Microsoft.Office.Core.MsoTriState.msoFalse

                '~~> Definindo as series
                .SeriesCollection(1).Smooth = True

                '~~> Formatando a legenda
                With .Legend
                    With .Format.TextFrame2.TextRange.Font.Fill
                        .Visible = Microsoft.Office.Core.MsoTriState.msoTrue
                        .ForeColor.RGB = RGB(255, 125, 0)
                        .Transparency = 0
                        .Solid()
                    End With
                    With .Format.Fill
                        .Visible = Microsoft.Office.Core.MsoTriState.msoTrue
                        .ForeColor.ObjectThemeColor = Microsoft.Office.Core.MsoThemeColorIndex.msoThemeColorBackground2
                        .ForeColor.TintAndShade = 0
                        .Transparency = 0
                        .Solid()
                    End With
                End With

                '~~> alterando oforamto do eixo Y para exibir valores
                .Axes(Excel.XlAxisType.xlValue).TickLabels.NumberFormat = "$#,##0.00"

                '~~> sublinhando o titulo do gráfico
                .ChartTitle.Format.TextFrame2.TextRange.Font.UnderlineStyle = _
                Microsoft.Office.Core.MsoLineStyle.msoLineSingle
            End With
        End With
    End Sub

Eu estou repetindo os dados e alterando apenas o valor do eixo Y para valores ao invés de quantidade (só para testar).

A formatação aplicada pode ser alterada a seu gosto.

O resultado obtido pelo código acima é visto na figura a seguir:

Pegue o projeto completo aqui: GraficoExcelVBNET.zip

Joã 3:16 Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna.
Joã 3:17
Porque Deus enviou o seu Filho ao mundo, não para que julgasse o mundo, mas para que o mundo fosse salvo por ele.
Joã 3:18
Quem crê nele não é julgado; mas quem não crê, já está julgado; porquanto não crê no nome do unigênito Filho de Deus.
Joã 3:19
E o julgamento é este: A luz veio ao mundo, e os homens amaram antes as trevas que a luz, porque as suas obras eram más.

A luz veio ao mundo mas os homens amaram e continuam amando antes a trevas que a luz; porque somos maus.

Referências:


José Carlos Macoratti