VB .NET - Importando e tratando arquivos CSV


Um arquivo CSV é um arquivo texto delimitado que utiliza a vírgula para separar os valores existentes no arquivo, sendo que existem implementações onde outros separadores também podem ser usados.

Os arquivos CSV mais simples não permitem valores que contém vírgula (Ex: Rua Teste, 100) ou outros caracteres especiais como o indicador de nova linha CR ou LF. (Carriage Return/ Line Feed) . Implementações mais sofisticadas permitem vírgulas, ponto e vírgula(;), asterístico(*) como delimitadores e outros caracteres especiais.

Este é mais um artigo onde vou mostrar como importar e tratar arquivos CSV.

Neste artigo eu vou importar e tratar arquivos CSV que usa a virgula para separar os valores do arquivo.

Vou usar o provedor OleDb para acessar os arquivos texto no padrão CSV usando a string de conexão adequada.

A string de conexão usada para acessar arquivos textos é dada abaixo:

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\caminho\;Extended Properties=""text;HDR=Yes;FMT=Delimited"""

onde "HDR=Yes;"  - indica que a primeira linha contém os nomes das colunas e não dados.

Vou importar e exibir o conteúdo dos arquivos em um controle DataGridView e permitir que o usuário realize o tratamento do arquivo realizando algumas consultas que serão destacadas no DataGridView e também permitindo que o arquivo seja exportado para o Excel.

Em nosso exemplo vou usar dois arquivos textos como exemplo:

1- O arquivo Contatos.csv que representa uma relação de contatos com nome, idade e sexo e cujo conteúdo é visto abaixo:

Primeiro,Ultimo,Idade,Sexo
Jose Carlos,Macoratti,21,Masculino
Janice,Rachel,32,Masculino
Jefferson,Ribeiro,24,Feminino
Miriam,Bueno,18,Masculino
Lucia,Ramos,44,Feminino
Tomas,Dos Santos,33,Masculino
Justina,Granola,25,Masculino
Pedrita,Dola,18,Feminino

2- O arquivo SextaFeira_Treze.csv que relaciona os meses e anos cuja sexta-feira cai no dia 13,  mostrado a seguir:

Mes,ano1,ano2,ano3,ano4,ano5,ano6,ano7,ano8,ano9
Janeiro,1978,1984,1989,1995,2006,2012,2017,2023,2034
Fevereiro,1976,1981,1987,1998,2004,2009,2015,2026,2032
Março,1981,1987,1992,1998,2009,2015,2020,2026,2037
Abril,1973,1979,1984,1990,2001,2007,2012,2018,2029
Maio,1977,1983,1988,1994,2005,2011,2016,2022,2033
Junho,1975,1980,1986,1997,2003,2008,2014,2025,2031
Julho,1973,1979,1984,1990,2001,2007,2012,2018,2029
Agsoto,1971,1976,1982,1993,1999,2004,2010,2021,2027
Setembro,1974,1985,1991,1996,2002,2013,2019,2024,2030
Outubro,1972,1978,1989,1995,2000,2006,2017,2023,2028
Novembro,1981,1987,1992,1998,2009,2015,2020,2026,2037
Dezembre,1974,1985,1991,1996,2002,2013,2019,2024,2030

Note que em ambos os arquivos a primeira linha representa o cabeçalho com os  nomes das colunas dos dados.

Para importar os arquivos vou criar uma aplicação usando o Visual Studio 2012 Express for Destkop com o nome Importar_Tratar_CSV;

Após criar a solução no Visual Studio usando o template Windows Forms Application inclua a partir da ToolBox os seguintes controles no formulário form1.vb:

Disponha os controles conforme o leiaute da figura abaixo:

Os namespaces usados neste formulário são:

Imports System.IO

Imports System.Data.OleDb

Imports Microsoft.Office.Interop

 

Quando a aplicação for carregada o evento Load do formulário verifica se o arquivo log.txt existe e grava informações sobre nome do usuário e data de início do programa.

 

 Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Me.Text = "Importar e Tratar CSV  | v" & My.Application.Info.Version.ToString
        Dim arquivoExiste As Boolean
        arquivoExiste = My.Computer.FileSystem.FileExists(My.Application.Info.DirectoryPath & "/log.txt")
        If arquivoExiste = False Then
            If MessageBox.Show("O arquivo de log não existe, você gostaria de criar um agora ?", "Arquivo de Log", MessageBoxButtons.YesNo,
 MessageBoxIcon.Question) = DialogResult.Yes Then
                My.Computer.FileSystem.WriteAllText(My.Application.Info.DirectoryPath & "/log.txt", String.Empty, False)
                MsgBox("Arquivo de log criado!")
            End If
        End If
        Dim xLog As String = My.Application.Info.DirectoryPath & "/log.txt"
        Dim vt As String = vbCrLf & My.Application.Info.Version.ToString & " - " & My.User.Name & " - Programa Iniciado." & Date.Now
        Try
            My.Computer.FileSystem.WriteAllText(xLog, vt, True)
        Catch ex As Exception
            MessageBox.Show(ex.ToString, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

 

Para ver o  conteúdo do arquivo Log.txt clique na figura sob o texto Log no formulário. O código usado para exibir o arquivo Log.txt é mostrado abaixo:

 Private Sub picLog_Click(sender As System.Object, e As System.EventArgs) Handles picLog.Click
        Dim xLog As String = My.Application.Info.DirectoryPath & "/log.txt"
        Diagnostics.Process.Start(xLog)
 End Sub

Após iniciar a aplicação o usuário deverá clicar no botão Importar CSV onde será aberto uma caixa de diálogo para selecionar o arquivo desejado.

Após selecionar o arquivo o código abaixo no evento Click do botão irá importar o arquivo exibindo no controle DataGridView:

Private Sub btnImportarCSV_Click(sender As System.Object, e As System.EventArgs) Handles btnImportarCSV.Click
        Try
            ofd1.InitialDirectory = My.Application.Info.DirectoryPath
            If ofd1.ShowDialog(Me) = DialogResult.OK Then
                Dim nomeArquivo As New FileInfo(ofd1.FileName)
                Dim stringConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Text;Data Source=" & nomeArquivo.DirectoryName
                Dim objConn As New OleDbConnection(stringConexao)
                objConn.Open()
                Dim oCmdSelect As New OleDbCommand("SELECT * FROM " & nomeArquivo.Name, objConn)
                Dim oAdapter As New OleDbDataAdapter
                oAdapter.SelectCommand = oCmdSelect
                Dim objdataset1 As New DataSet
                oAdapter.Fill(objdataset1, "teste")
                dgView.DataSource = objdataset1.Tables(0).DefaultView
                objConn.Close()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.ToString, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

O código usa o provedor OleDb com a string de conexão apropriada para acessar o arquivo escolhido.

A seguir usando os objetos OledbCommand, OledbDataAdapter e DataSet, selecionamos todos os dados do arquivos e preenchemos um dataset exibindo-o a seguir no controle DataGridView usando a propriedade DataSource.

Conforme o arquivo selecionado podemos realizar algumas consultas destacando-as no controle DataGridView Vou mostrar apenas uma delas pois o processo usado para as demais é parecido.

Marcando o primeiro checkbox onde vamos destacar as idades maior ou igual a informada na caixa de texto. No exemplo informei o valor 30.

Clicando no botão Destacar no Arquivo CSV temos o seguinte resultado:

O código responsável por esta e pelas demais consultas no primeiro GroupBox para o arquivo Contatos.csv é dado a seguir:

Private Sub btnDestacar1_Click(sender As System.Object, e As System.EventArgs) Handles btnDestacar1.Click
        Try
            dgView.CurrentCell.Selected = False
            limpaGrid()
            Me.dgView.ClearSelection()
            If chkIdadeMaiorQue.CheckState = CheckState.Checked Then
                Dim cell As DataGridViewCell
                Dim cellVar As Integer
                For Each row As DataGridViewRow In Me.dgView.Rows
                    cell = row.Cells(2)
                    cellVar = CInt(row.Cells(2).Value)
                    If cellVar > txtIdade.Text Then
                        row.Selected = True
                    End If
                Next
            End If
            If chkFeminino.CheckState = CheckState.Checked Then
                Dim cell As DataGridViewCell
                Dim cellVar As String
                For Each row As DataGridViewRow In Me.dgView.Rows
                    cell = row.Cells(3)
                    cellVar = CStr(row.Cells(3).Value)
                    If cellVar = "Feminino" Then
                        row.Selected = True
                    End If
                Next
            End If
            If chkSobrenome.CheckState = CheckState.Checked Then
                If Not String.IsNullOrEmpty(txtSobrenome.Text) Then
                    Dim cell As DataGridViewCell
                    Dim cellVar As String
                    For Each row As DataGridViewRow In Me.dgView.Rows
                        cell = row.Cells(1)
                        cellVar = CStr(row.Cells(1).Value)
                        If cellVar = txtSobrenome.Text Then
                            row.Selected = True
                            cell.Style.BackColor = Color.Red
                        End If
                    Next
                Else
                    MessageBox.Show("Informe o sobrenome...")
                    ' desmarcaCheckBox()
                    Exit Sub
                End If
            End If
            If chkTodosFemininos.CheckState = CheckState.Checked Then
                Dim cell As DataGridViewCell
                Dim cellVar As String
                For Each row As DataGridViewRow In Me.dgView.Rows
                    cell = row.Cells(3)
                    cellVar = CStr(row.Cells(3).Value)
                    If cellVar = "Feminino" Then
                        cell.Selected = True
                    End If
                Next
            End If
            If chkTodosMasculinos.CheckState = CheckState.Checked Then
                Dim cell As DataGridViewCell
                Dim cellVar As String
                For Each row As DataGridViewRow In Me.dgView.Rows
                    cell = row.Cells(3)
                    cellVar = CStr(row.Cells(3).Value)
                    If cellVar = "Masculino" Then
                        cell.Selected = True
                    End If
                Next
            End If
        Catch ex As Exception
            MessageBox.Show("Importe o arquivo CSV para continuar....", "Aviso", MessageBoxButtons.OK, 
MessageBoxIcon.Information)
        End Try
        desmarcaCheckBox()
    End Sub

Além disso estou usando as seguintes rotinas:

    Private Sub limpaGrid()
        For Each row As DataGridViewRow In Me.dgView.Rows
            row.Selected = False
        Next
    End Sub

    Private Sub desmarcaCheckBox()
        For Each c As CheckBox In GroupBox1.Controls
            If c.CheckState = CheckState.Checked Then
                c.CheckState = CheckState.Unchecked
            End If
        Next
        For Each c As CheckBox In GroupBox2.Controls
            If c.CheckState = CheckState.Checked Then
                c.CheckState = CheckState.Unchecked
            End If
        Next
    End Sub  

O código do evento Click do botão Exportar CSV que exporta o arquivo para o Excel é visto abaixo:

Private Sub btnExportarCSV_Click(sender As System.Object, e As System.EventArgs) Handles btnExportarCSV.Click
        If dgView.RowCount - 1 > 0 Then
            Dim rowsTotal, colsTotal As Short
            Dim I, j, iC As Short
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor
            Dim xlApp As New Excel.Application
            Try
                Dim excelBook As Excel.Workbook = xlApp.Workbooks.Add
                Dim excelWorksheet As Excel.Worksheet = CType(excelBook.Worksheets(1), Excel.Worksheet)
                xlApp.Visible = True
                rowsTotal = dgView.RowCount - 1
                colsTotal = dgView.Columns.Count - 1
                With excelWorksheet
                    .Cells.Select()
                    .Cells.Delete()
                    For iC = 0 To colsTotal
                        .Cells(1, iC + 1).Value = dgView.Columns(iC).HeaderText
                    Next
                    For I = 0 To rowsTotal
                        For j = 0 To colsTotal
                            .Cells(I + 2, j + 1).value = dgView.Rows(I).Cells(j).Value
                        Next j
                    Next I
                    .Rows("1:1").Font.FontStyle = "Bold"
                    .Rows("1:1").Font.Size = 10
                    .Cells.Columns.AutoFit()
                    .Cells.Select()
                    .Cells.EntireColumn.AutoFit()
                    .Cells(1, 1).Select()
                End With
            Catch ex As Exception
                Dim meuArquivo As String = My.Settings.LogFile
                Dim itxt As New TextBox
                If IO.File.Exists(meuArquivo) Then
                    itxt.Text = IO.File.ReadAllText(meuArquivo)
                End If
                Dim vt As String = vbCrLf & Date.Now & " - " & My.Application.Info.Version.ToString & "--" & "Exportação para Excel ERRO - " 
& My.User.Name & itxt.Text
                My.Computer.FileSystem.WriteAllText(meuArquivo, vt, False)
                itxt.Clear()
            Finally
                'libera os recursos alocados
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
                xlApp = Nothing
            End Try
        Else
            MessageBox.Show("Importe o arquivo CSV para continuar....", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

 

Creio que estes são os destaques desde singelo programa feito na linguagem VB .NET.

Pegue o sistema completo aqui: Importar_Tratar_CSV.zip

Mateus 15:19 Porque do coração procedem os maus pensamentos, homicídios, adultérios, prostituição, furtos, falsos testemunhos e blasfêmias.

Mateus 15:20 São estas as coisas que contaminam o homem; mas o comer sem lavar as mãos, isso não o contamina.

Referências:


José Carlos Macoratti