ナイトオウル深夜便

何ふり構ってられない インターネット初心者だから

DataGridViewのデータをExcelに出力する(VB.NET)

こういうコードを実装する機会があったのでメモ


kchon.blog111.fc2.com
↑こちらのサイトを参考にさせて頂いたのだけど、今回の目的はここの処理で使われてる「DataGridViewPlus」を使うほど複雑ではなかったのでそのままDataGridViewで実装した


想定として

  • 画面上に設置したExcel出力するためのボタンを押した際のイベント
  • 保存先のディレクトリは「EXCEL_SAVE_PATH」で指定
  • ファイル名には現在日時も入れる
  • 出力の際は罫線も表示する
    ' Excelを参照設定する必要があります
    ' [参照の追加],[COM],[Microsoft Excel *.* Object Library]
    ' Imports Microsoft.Office.Interop (必要)
    ' Imports System.Runtime.InteropServices (必要)

    ''' <summary>
    ''' Excel出力ボタン押下時の処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub EXCEL_BTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EXCEL_BTN.Click

        ' EXCEL関連オブジェクトの定義
        Dim objExcel As Excel.Application = New Excel.Application
        Dim objWorkBook As Excel.Workbook = objExcel.Workbooks.Add
        Dim objSheet As Excel.Worksheet = Nothing

        '現在日時を取得
        Dim timestanpText As String = Format(Now, "yyyyMMddHHmmss")

        '保存ディレクトリとファイル名を設定
        Dim saveFileName As String
        saveFileName = objExcel.GetSaveAsFilename( _
            InitialFilename:=EXCEL_SAVE_PATH & "ファイル名_" & timestanpText, _
            FileFilter:="Excel File (*.xlsx),*.xlsx")

        '保存先ディレクトリの設定が有効の場合はブックを保存
        If saveFileName <> "False" Then
            objWorkBook.SaveAs(Filename:=saveFileName)
        End If

        'シートの最大表示列項目数
        Dim columnMaxNum As Integer = dgv.Columns.Count - 1
        'シートの最大表示行項目数
        Dim rowMaxNum As Integer = dgv.Rows.Count - 1

        '項目名格納用リストを宣言
        Dim columnList As New List(Of String)
        '項目名を取得
        For i As Integer = 0 To (columnMaxNum)
            columnList.Add(dgv.Columns(i).HeaderCell.Value)
        Next

        'セルのデータ取得用二次元配列を宣言
        Dim v As String(,) = New String(rowMaxNum, columnMaxNum) {}

        For row As Integer = 0 To rowMaxNum
            For col As Integer = 0 To columnMaxNum
                If dgv.Rows(row).Cells(col).Value Is Nothing = False Then
                    ' セルに値が入っている場合、二次元配列に格納
                    v(row, col) = dgv.Rows(row).Cells(col).Value.ToString()
                End If
            Next
        Next

        ' EXCELに項目名を転送
        For i As Integer = 1 To dgv.Columns.Count
            ' シートの一行目に項目を挿入
            objWorkBook.Sheets(1).Cells(1, i) = columnList(i - 1)

            ' 罫線を設定
            objWorkBook.Sheets(1).Cells(1, i).Borders.LineStyle = True
            ' 項目の表示行に背景色を設定
            objWorkBook.Sheets(1).Cells(1, i).Interior.Color = RGB(140, 140, 140)
            ' 文字のフォントを設定
            objWorkBook.Sheets(1).Cells(1, i).Font.Color = RGB(255, 255, 255)
            objWorkBook.Sheets(1).Cells(1, i).Font.Bold = True
        Next

        ' EXCELにデータを範囲指定で転送
        Dim data As String = "A2:" & Chr(Asc("A") + columnMaxNum) & dgv.Rows.Count + 1
        objWorkBook.Sheets(1).Range(data) = v

        ' データの表示範囲に罫線を設定
        objWorkBook.Sheets(1).Range(data).Borders.LineStyle = True

        ' エクセル表示
        objExcel.Visible = True

        ' EXCEL解放
        Marshal.ReleaseComObject(objWorkBook)
        Marshal.ReleaseComObject(objExcel)
        objWorkBook = Nothing
        objExcel = Nothing
    End Sub


どこか間違ってたら未来の自分が修正してくれるはず
VBって処理を{}でくくらないから未だに見慣れない…