Monthly Archives: 11月 2012 - Page 4

属性テーブルの表示example [Chapter 7-4]

属性テーブルの表示example

今回は、shape fileの属性値をDataGridView controlに表示するexampleツールのメニューを付け加えていきます。ツールメニューは、dbfのCSV出力とExcel出力ができるようにします。
元になるprogramは、属性テーブルの表示example [Chapter 7-3]のex073に付け加えていきます。

Program Coding

さらに、[Chapter 7-3]でToolBarに追加してあります。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image01.jpg

Form design

Main Form

Main Formの変更・追加はありません。
属性テーブルの表示example [Chapter 7-1]そのまんまです。

ツールのCSV出力とExcel出力buttonで呼び出すprogramを作成します。
今回は、Sub Formの作成はありません。

Coding

CSV出力やExcelの出力は他のプログラムでもよく使うので、再利用を考えてClassを作成してみましょう。

CSV出力のCLass作成

vb.netのソリューションエクスプローラからClassを新規作成します。
とりあえずは、名前をCSVOutPut.vbとしておきます。

ClassのCodingは、

Imports System
Imports System.IO
Imports System.Data
Imports System.Text
 
''' <summary>
''' DataGridViewからCSV書き込みClass
''' </summary>
 
Public Class CSVOutput
 
    Public Shared Function DGV2CSV(ByVal stmFileName As String,
                                   ByVal dgv As System.Windows.Forms.DataGridView,
                                   ByVal chrCode As String) As Boolean
        ' CSVファイルオープン
        Dim stmFile As IO.StreamWriter   '出力ファイル名
        stmFile = New IO.StreamWriter(stmFileName,
                                      False,
                                      System.Text.Encoding.GetEncoding(chrCode))
 
        Try
            'ヘッダーの書き込み
            For col As Integer = 0 To dgv.Columns.Count - 1
                ' DataGridViewのセルのデータ取得
                Dim strHeader As String = ""
                strHeader = Chr(34) & _
                            dgv.Columns(col).HeaderCell.Value.ToString().Trim & _
                            Chr(34)
                If col < dgv.Columns.Count - 1 Then
                    strHeader = strHeader & ","
                End If
                ' CSVファイル書込
                stmFile.Write(strHeader)
            Next
            stmFile.Write(vbCrLf)
 
            'セルデータの書き込み
            For row As Integer = 0 To dgv.Rows.Count - 1
                For col As Integer = 0 To dgv.Columns.Count - 1
                    'DataGridViewのセルのデータ取得
                    Dim strCell As String = ""
                    If dgv.Rows(row).Cells(col).Value _
                    Is Nothing = False Then
                        strCell = Chr(34) & _
                                  dgv.Rows(row).Cells(col).Value.ToString() & _
                                  Chr(34)
                    End If
                    If col < dgv.Columns.Count - 1 Then
                        strCell = strCell & ","
                    End If
                    'CSVファイル書込
                    stmFile.Write(strCell)
                Next
                stmFile.Write(vbCrLf)
            Next
            'CSVファイルクローズ
            stmFile.Close()
        Catch ex As Exception
            'エラー処理
            DGV2CSV = False
            'CSVファイルクローズ
            stmFile.Close()
        Finally
            DGV2CSV = True
            'CSVファイルクローズ
            stmFile.Close()
        End Try
 
    End Function
 
End Class

System.IO.StreamWriterを利用して書き出します。chsCodeでshift-jis,utf-8,euc-jpに拡張できるようにし起きます。
DataGridviewのcellデータを順に書き出します。
それほど、難しいcodeではないと思いますので、しっかり読んでください。

Excel出力のCLass作成

vb.netのソリューションエクスプローラからClassを新規作成します。
とりあえずは、名前をExcelOutPut.vbとしておきます。

ExcelOutPut ClassのExcel出力のmainのCodingは、

        Public Function ExcelDGVOut(strFileName As String, dgv As DataGridView, ByRef strErrMessage As String) As Int32
            Dim command As New OleDbCommand()
            Dim conn As New OleDbConnection()
            Dim strCommand As String = "create table "
            Dim strTable As String = ""
            Dim iRet As Int32 = ExcelDefine.EXCEL_NO_ERROR
 
            Try
                Me.ExcelProvider(strFileName, strTable, conn)
 
                Try
                    conn.Open()
                Catch ex As Exception
                    strErrMessage = "ファイルが開けません" & Environment.NewLine & ex.Message
                    Return ExcelDefine.EXCEL_OPEN_ERROR
                End Try
 
                'ファイルを作成
                command = conn.CreateCommand()
 
                ' テーブルを作成
                If strTable = "" Then
                    strTable = "1"
                End If
                strCommand += "[" & strTable & "]" & "("
                For i As Int32 = 0 To dgv.Columns.Count - 1
                    If dgv.Columns(i).ValueType.Name = "Integer" Or dgv.Columns(i).ValueType.Name = "Int32" Or dgv.Columns(i).ValueType.Name = "Decimal" Or dgv.Columns(i).ValueType.Name = "Long" Or dgv.Columns(i).ValueType.Name = "Double" Or dgv.Columns(i).ValueType.Name = "Short" Then
                        'セルの書式を数値型に設定 
                        strCommand += "[" + dgv.Columns(i).HeaderText & "] int "
                    ElseIf dgv.Columns(i).ValueType.Name = "DateTime" Then
                        'セルの書式を日付型に設定 
                        strCommand += "[" + dgv.Columns(i).HeaderText & "] time "
                    Else
                        strCommand += "[" + dgv.Columns(i).HeaderText & "] " & ExcelDefine.EXCELVARCHAR
                    End If
                    '最後じゃなければ「,」をつける
                    If i <> dgv.Columns.Count - 1 Then
                        strCommand += ","
                    End If
                Next
                strCommand += ")"
                command.CommandText = strCommand
 
                Try
                    command.ExecuteNonQuery()
                Catch ex As Exception
                    strErrMessage = "Tableの作成に失敗しました" & Environment.NewLine & "コマンド:" & strCommand & " " & Environment.NewLine & ex.Message
                    conn.Close()
                    Return ExcelDefine.EXCEL_TABLE_ERROR
                End Try
 
                'データ入力(パラメータマッチング)
                strCommand = " INSERT INTO " & "[" & strTable & "]" & " VALUES ("
                For i As Int32 = 0 To dgv.Columns.Count - 1
                    If dgv.Columns(i).ValueType Is Nothing Then
                        Continue For
                    End If
                    strCommand += "?"
                    '最後じゃなければ「,」をつける
                    If i <> dgv.Columns.Count - 1 Then
                        strCommand += ","
                    End If
                Next
                strCommand += ")"
 
                command.CommandText = strCommand
                '出力
                For Each dtRow As DataGridViewRow In dgv.Rows
                    If (InlineAssignHelper(iRet, Me.DGVSetFunc(dgv, dtRow, conn, command, strErrMessage))) <> ExcelDefine.EXCEL_NO_ERROR Then
                        Return iRet
                    End If
                Next
 
                Try
                    conn.Close()
                Catch ex As Exception
                    strErrMessage = "Excelファイルの終了処理に失敗しました" & Environment.NewLine & ex.Message
                    Return ExcelDefine.EXCEL_CLOSE_ERROR
                End Try
 
                Return iRet
            Catch ex As Exception
                strErrMessage = "Excelファイルの出力処理に失敗しました" & Environment.NewLine & ex.Message
                conn.Close()
                Return ExcelDefine.EXCEL_OTHER_ERROR
            End Try
        End Function

oledbで接続して、DataGridViewのcellデータを書き込んできます。

Excel Fileの接続providerはxls形式と2007以降のxlsx形式とに分けて作成します。

        Private Sub ExcelProvider(strFileName As String, ByRef strTable As String, ByRef conn As OleDbConnection)
            Dim strExt As String
 
            'ファイルの拡張子チェック
            strExt = Path.GetExtension(strFileName)
 
            If strExt = ExcelDefine.EXCEL_EXT_2007 Then
                conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFileName & ";Extended Properties=""Excel 12.0 Xml;HDR=YES;""")
                strTable = "1"
            ElseIf strExt = ExcelDefine.EXCEL_EXT_200X Then
                conn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFileName & ";Extended Properties=""Excel 8.0;HDR=Yes;""")
                strTable = "1"
             End If
        End Sub

DataGridViewのcellデータの書き込みは、oledbcommandを使って、時刻、数値、文字列その他に分けて書き込みます。
functionのDGVSetFunc(dgv, dtRow, conn, command, strErrMessage))が書き込む部分になります。
そのDGVSetFuncのcodeは、

        Private Function DGVSetFunc(dgv As DataGridView, dtRow As DataGridViewRow, ByRef conn As OleDbConnection, ByRef command As OleDbCommand, ByRef strErrMessage As String) As Int32
            command.Parameters.Clear()
            For i As Int32 = 0 To dgv.Columns.Count - 1
                '日時の場合
                If dgv.Columns(i).ValueType.Name = "DateTime" Then
                    Dim dTime As DateTime = CType(dtRow.Cells(i).Value, DateTime)
                    command.Parameters.AddWithValue("@" & i.ToString(), "time").Value = dTime.ToString(Me.strEXCELTIME)
                    '数値の場合
                ElseIf dgv.Columns(i).ValueType.Name = "Integer" Or dgv.Columns(i).ValueType.Name = "Int32" Or dgv.Columns(i).ValueType.Name = "Decimal" Or dgv.Columns(i).ValueType.Name = "Long" Or dgv.Columns(i).ValueType.Name = "Double" Or dgv.Columns(i).ValueType.Name = "Short" Then
                    command.Parameters.AddWithValue("@" & i.ToString(), "int").Value = dtRow.Cells(i).Value
                Else
                    'それ以外の場合
                    command.Parameters.AddWithValue("@" & i.ToString(), "text").Value = dtRow.Cells(i).Value
                End If
            Next
 
            Try
                'コマンド実行
                command.ExecuteNonQuery()
            Catch ex As Exception
                strErrMessage = "データ出力に失敗しました" & Environment.NewLine & "コマンド:" & Convert.ToString(command.CommandText) & " " & Environment.NewLine & ex.Message
                Return ExcelDefine.EXCEL_INSERT_ERROR
            End Try
            Return ExcelDefine.EXCEL_NO_ERROR
        End Function

ExcelOutput.vbのClassは、

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Data.OleDb
Imports System.IO
 
Namespace ExcelOutPut
    Class ExcelDefine
        ''' <summary>
        ''' テキスト型
        ''' </summary>
 
        Public Const EXCEL_EXT_2007 As String = ".xlsx"
        Public Const EXCEL_EXT_200X As String = ".xls"
 
    End Class
 
    Public Class ExcelOutClass
 
        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        Public Sub New()
           .....
        End Sub
 
        ''' <summary>
        ''' エクセル出力関数(DataGridViewから)
        ''' </summary>
        Public function ExcelDGVOut(.....)
        ''''
        End FUnction
 
        ''' <summary>
        ''' プロバイダ選定
        ''' </summary>
        Public function ExcelProvider(.....)
        ''''
        End FUnction
 
        ''' <summary>
        ''' DataGridViewからExcelファイルに出力
        ''' </summary>
        Public function DGVSetFunc(.....)
        ''''
        End FUnction
 
    End Class
End Namespace

な感じで作成します。

Attribute View Formのcoding

それでは、CSV出力とExcel出力Button eventを実装します。

CSV出力Button eventの実装

CSV出力Button event Click発生時のcodingは、sharedでfunctionを定義しているので、CSVOutput.DGV2CSVで直接呼び出します。

    Private Sub CSV出力ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CSV出力ToolStripMenuItem.Click
        Dim saveDialog As New SaveFileDialog()
        Dim chrCode As String = "shift-jis"
        'chrCode = shift-jis or utf-8 or euc-jp
 
        'initialize dialog
        saveDialog.Filter = "CSV File|*.csv|csv format (*.csv)|*.csv"
        saveDialog.FilterIndex = 2
        saveDialog.RestoreDirectory = True
 
        'csv save
        If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            'get the extension of the file
            Dim ext As String = System.IO.Path.GetExtension(saveDialog.FileName)
 
            If ext = ".csv" Then
                If CSVOutput.DGV2CSV(saveDialog.FileName, DataGridView1, chrCode) = False Then
                    MsgBox("CSVファイルに保存できませんでした。", MsgBoxStyle.Critical, "CSV File Save error")
                    Exit Sub
                End If
            Else
                MsgBox("ファイルの拡張子(csv)を入力してください。", MsgBoxStyle.Critical, "Excel出力ファイル名")
                Exit Sub
            End If
 
        End If
    End Sub

CSVOutput.DGV2CSVに出力するファイル名、DataGridView objectと文字コードstringを渡します。
また、拡張子がcsv以外だと保存できないようにしておきます。

Excel出力Button eventの実装

Excel出力Button event Click発生時のcodingは、ExcelOutPut.ExcelOutClassのインスタンスを作成して呼び出します。

    Private Sub EXCEL出力ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles EXCEL出力ToolStripMenuItem.Click
        Dim m_excel As New ExcelOutPut.ExcelOutClass
 
        Dim saveDialog As New SaveFileDialog
        'saveFileDialog1.Filter = "Excel files (*.xlsx)|*.xlsx"
        saveDialog.Filter = "Excel File|*.xls;*.xls|Excel 2000-2003 (*.xls)|*.xls|Excel 2007-2010 (*.xlsx)|*.xlsx"
        saveDialog.FilterIndex = 2
        saveDialog.RestoreDirectory = True
        If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            'get the extension of the file
            Dim ext As String = System.IO.Path.GetExtension(saveDialog.FileName)
 
            If ext = ".xls" Or ext = ".xlsx" Then
                Dim strMessage As String = ""
                m_excel.ExcelDGVOut(saveDialog.FileName, DataGridView1, strMessage)
            Else
                MsgBox("ファイルの拡張子(xls)または(xlsx)を入力してください。", MsgBoxStyle.Critical, "Excel出力ファイル名")
                Exit Sub
            End If
        End If
    End Sub

ExcelDGVOutに出力するファイル名、DataGridViewを渡し、 strMessageでエラー発生時のstringを受け取ります。
また、拡張子がxls,xlsx以外だと保存できないようにしておきます。

Programの実行

では、ex074を保存して実行してみましょう。

今回は、神奈川県のサンプルc14_regionDD.shpを読み込んだ後、属性値テーブル表示buttonをクリックして、属性値テーブル表示formを表示させて、ツールButtonをClickすると、CSV出力とExcel出力表示されます。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image02.jpg
ツールButtonをClick画面

CSV出力を選択するとsavedialogが表示されます。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image03.jpg
CSV出力を選択するとsavedialog追加表示

Excel出力を選択するとsavedialogが表示されます。xlsとxlsx形式のみに対応しています。
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image04.jpg
Excel出力を選択するとsavedialog追加表示

出力結果を確認してみます。

CSV出力結果をメモ帳で開いた状態
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image05.jpg
CSV出力結果

Excel出力結果(xlsx)をExcel 2010で開いた状態
blog.godo-tys.jp_wp-content_gallery_mapwingis_ex074_image06.jpg
Excel出力結果(xlsx)結果

ちゃんと出力されていますね。
大丈夫ですね。

今回のまとめ

では、今回のまとめを

  1. dbfのCSV出力の実装を行いました。
  2. dbfのExcel出力の実装を行いました。
  3. Classを作成して、再利用できるようにしました。

今回で[Chapter 7]を終了します。
次回は、labelやcategoryを設定してもアプリケーションを終了すると初期状態にresetされますよね。
その操作状態を保存して保存と再度呼び出し表示するprogramの実装を行う予定です。

vb.net2010だけでなく、C#でも、visual studio2008でも動作することができます。
簡単に自前のソフトウェアにちょっとしたGIS機能を付け加えるには良いと思います。
ex073のsource codeを公開しますので、活用してください。
ただし、あくまでの自分用のサンプルですので、バグなどがある可能性が高いので、原文のままの使用は避けてください。

サンプルコードおよびサンプルデータを使って、お使いのPCの不具合が生じても一切責任は持てませんので、あくまでも自己責任にて使用してください。

Exercise

今回のProgramを少し発展させて以下の項目を付け加えてみてください。

  1. 別名のdbfファイルに出力してみる。
  2. Access形式のmdbファイルに出力してみる。

Social Widgets powered by AB-WebLog.com.