2013年12月31日火曜日

【VB.NET】ADO.NET SqlCommand.ExecuteReaderメッソドでデータを読み込む

SqlCommandのExecuteReaderメッソドを使ってデータを読み込みます。

  1. SqlCommandのCommandTextへSELECTを設定します。
  2. SqlCommandのExecuteReaderメッソドでSqlDataReaderを構築する。
  3. SqlDataReaderのReadメッソドでレコードを読み込み
使用例:商品マスタのデータを取得してコンソールへ表示します。

テーブル定義
インスタンス名SQLEXPRESSデータベース名SAMPLE_DB
論理テーブル名商品マスタ物理テーブル名M_ITEM
列定義
No論理名物理名データ型Nullを許容主キー
1商品CDITEM_CDnvarchar(4)NoYes
2商品名ITEM_NMnvarchar(32)No
3単価PRICEnumeric(8,0)No

商品マスタ テーブルデータ

Imports System.Data.SqlClient
 
Module Module1
 
    Sub Main()
        Dim con As New SqlConnection
 
        'コネクション接続
        con.ConnectionString = "Data Source=localhost\SQLEXPRESS;Initial Catalog=SAMPLE_DB;Integrated Security=True"
        con.Open()
 
        
        'SqlCommand
        Dim sqlCom As New SqlCommand()
 
        'コネクションを指定
        sqlCom.Connection = con
 
        '実行するSQLステートメント
        sqlCom.CommandText = "SELECT ITEM_CD, ITEM_NM, PRICE FROM M_ITEM"
 
        'データの取得
        Dim dtReader As SqlDataReader = sqlCom.ExecuteReader
 
        'レコードの読み込み
        While dtReader.Read
            Dim str As String = String.Empty
 
            str = str & dtReader("ITEM_CD").ToString & ","
            str = str & dtReader("ITEM_NM").ToString & ","
            str = str & dtReader("PRICE").ToString
 
            Console.WriteLine(str)
        End While
 
        'SqlCommandの解放
        sqlCom.Dispose()
 
        '接続を閉じる
        con.Close()
 
        'コネクションの解放
        con.Dispose()
 
    End Sub
 
End Module
実行結果

2013年12月29日日曜日

【VB.NET】ADO.NET SqlCommandでテーブルを作成する。

SqlCommandのExecuteNonQueryメッソドを使って以下のテーブルを作成します。

インスタンス名SQLEXPRESSデータベース名SAMPLE_DB
論理テーブル名商品マスタ物理テーブル名M_ITEM
列定義
No論理名物理名データ型Nullを許容主キー
1商品CDITEM_CDnvarchar(4)NoYes
2商品名ITEM_NMnvarchar(32)No
3単価PRICEnumeric(8,0)No
  1. DBへコネクションを接続
  2. テーブルを作成するSQL文を記述
  3. SqlCommandのCommandTextへSQL文を設定およびコネクションを設定
  4. SqlCommandを実行
Imports System.Data.SqlClient
 
Module Module1
 
    Sub Main()
        Dim con As New SqlConnection
 
        'DB接続
        con.ConnectionString = "Data Source=localhost\SQLEXPRESS;Initial Catalog=SAMPLE_DB;Integrated Security=True"
        con.Open()
 
        '商品マスタの作成
        Dim strSql As String = "CREATE TABLE M_ITEM(ITEM_CD nvarchar(4) NOT NULL," _
                               + "ITEM_NM nvarchar(32) NOT NULL," _
                               + "PRICE numeric(8, 0) NOT NULL," _
                               + "CONSTRAINT PK_M_ITEM PRIMARY KEY (ITEM_CD))"
 
        'SQLCommand設定
        Dim sqlcom As SqlCommand = New SqlCommand(strSql, con)
 
        'SQLCommand実行
        sqlcom.ExecuteNonQuery()
 
        '接続を閉じる
        con.Close()
 
        'オブジェクトの解放
        sqlcom.Dispose()
        con.Dispose()
 
        Console.WriteLine("SQLCommandを実行しました。")
    End Sub
 
End Module
サーバーエクスプローラーでテーブルを確認

【VB.NET】ADO.NET SQLServer接続

ADO.NET利用してSQLSereverへ接続します。

  • SQLSerevr‥SQLServer2008
  • インスタンス名‥SQLEXPRESS
  • データベース名‥SAMPLE_DB


Imports System.Data.SqlClient
 
Module Module1
 
    Sub Main()
        Dim con As New SqlConnection
 
        '接続先
        con.ConnectionString = "Data Source=localhost\SQLEXPRESS;Initial Catalog=SAMPLE_DB;Integrated Security=True"
 
        '接続する
        con.Open()
 
        Console.WriteLine("接続に成功しました。")
 
        '接続を閉じる
        con.Close()
 
        'SqlConnectionの解放
        con.Dispose()
    End Sub
 
End Module

2013年12月15日日曜日

フィルム式一眼レフカメラ

先日、嫁さんの会社の上司からフィルム式一眼レフカメラの本体を頂きました。

機種はCanonEOS-1n、私にとっては初めての一眼レフカメラ!意外と重くいかにもメカって感じがして、それがまたいい感じです。

何を撮ろうか考えると心ワクワクです。
おおっと、その前にレンズを買わなきゃ‥

【VB.NET】DataViewRowStateで行の状態での抽出

DataViewRowStateを条件指定して行の状態で行を抽出します。

DataViewRowStateのメンバー(詳細はMSDN DataViewRowState列挙体を参照してください)
メンバー名説明
Added新しい行。
Deleted削除された行。
ModifiedCurrent変更された元のデータの現在のバージョン(ModifiedOriginalを参照)。
ModifiedOriginal変更されたデータの元のバージョン(データは変更されても、ModifiedCurrentとして利用可能です)。
Unchanged変更されていない行。

DataTable.Selectメッソドでの使用例
Module Module1
    Sub main()
        'サンプルデータテーブル
        Dim sampleTable As New DataTable
 
        sampleTable.TableName = "SampleTable"
        sampleTable.Columns.Add("ItemCD", Type.GetType("System.String"))
        sampleTable.Columns.Add("ItemName", Type.GetType("System.String"))
        sampleTable.Columns.Add("Price", Type.GetType("System.Double"))
 
        sampleTable.Rows.Add("001", "商品001", 110)
        sampleTable.Rows.Add("002", "商品002", 120)
        sampleTable.Rows.Add("003", "商品003", 130)
        sampleTable.Rows.Add("004", "商品004", 140)
        sampleTable.Rows.Add("005", "商品005", 150)
        sampleTable.Rows.Add("006", "商品006", 160)
        sampleTable.Rows.Add("007", "商品007", 170)
        sampleTable.Rows.Add("008", "商品008", 180)
        sampleTable.Rows.Add("009", "商品009", 190)
 
        'テーブルの変更をコミット‥DataRowをAdded→Modifiedへ
        sampleTable.AcceptChanges()
 
        'データを変更
        sampleTable.Rows(0)("Price") = 510
        sampleTable.Rows(3)("Price") = 530
 
        'データを削除
        sampleTable.Rows(1).Delete()
        sampleTable.Rows(4).Delete()
 
        'データを追加
        sampleTable.Rows.Add("010", "商品020", 200)
        sampleTable.Rows.Add("011", "商品020", 210)
 
        '変更された行
        Console.WriteLine("--- 変更された行 ---")
        Dim rws() As DataRow = sampleTable.Select(Nothing, Nothing, DataViewRowState.ModifiedCurrent)
        For i = 0 To rws.Length - 1
            Console.WriteLine(rws(i)("ItemCD").ToString & " " & rws(i)("ItemName").ToString & " " & rws(i)("Price").ToString)
        Next
 
        '変更された行の元の値
        Console.WriteLine("--- 変更された行の元の値 ---")
        rws = sampleTable.Select(Nothing, Nothing, DataViewRowState.ModifiedOriginal)
        For i = 0 To rws.Length - 1
            Console.WriteLine(rws(i)("ItemCD").ToString & " " & rws(i)("ItemName").ToString & " " & rws(i)("Price").ToString)
        Next
 
        '削除された行の元の値
        Console.WriteLine("--- 削除された行の元の値 ---")
        rws = sampleTable.Select(Nothing, Nothing, DataViewRowState.Deleted)
        For i = 0 To rws.Length - 1
            Console.WriteLine(rws(i)("ItemCD", DataRowVersion.Original).ToString & " " & _
                              rws(i)("ItemName", DataRowVersion.Original).ToString & " " & rws(i)("Price", DataRowVersion.Original).ToString)
        Next
 
        '追加された行
        Console.WriteLine("--- 追加された行の表示 ---")
        rws = sampleTable.Select(Nothing, Nothing, DataViewRowState.Added)
        For i = 0 To rws.Length - 1
            Console.WriteLine(rws(i)("ItemCD").ToString & " " & rws(i)("ItemName").ToString & " " & rws(i)("Price").ToString)
        Next
 
        '変更されてない行
        Console.WriteLine("--- 変更されてない行 ---")
        rws = sampleTable.Select(Nothing, Nothing, DataViewRowState.Unchanged)
        For i = 0 To rws.Length - 1
            Console.WriteLine(rws(i)("ItemCD").ToString & " " & rws(i)("ItemName").ToString & " " & rws(i)("Price").ToString)
        Next
 
    End Sub
End Module
実行結果
 ※DataTable.SelectメソッドでのModifiedOriginalは変更後の値が表示されるようです。


DataViewでの使用例
Module Module1
 
    Sub Main()
        'サンプルデータテーブル
        Dim sampleTable As New DataTable
 
        sampleTable.TableName = "SampleTable"
        sampleTable.Columns.Add("ItemCD", Type.GetType("System.String"))
        sampleTable.Columns.Add("ItemName", Type.GetType("System.String"))
        sampleTable.Columns.Add("Price", Type.GetType("System.Double"))
 
        sampleTable.Rows.Add("001", "商品001", 110)
        sampleTable.Rows.Add("002", "商品002", 120)
        sampleTable.Rows.Add("003", "商品003", 130)
        sampleTable.Rows.Add("004", "商品004", 140)
        sampleTable.Rows.Add("005", "商品005", 150)
        sampleTable.Rows.Add("006", "商品006", 160)
        sampleTable.Rows.Add("007", "商品007", 170)
        sampleTable.Rows.Add("008", "商品008", 180)
        sampleTable.Rows.Add("009", "商品009", 190)
 
        'テーブルの変更をコミット‥DataRowをAdded→Modifiedへ
        sampleTable.AcceptChanges()
 
        'データを変更
        sampleTable.Rows(0)("Price") = 510
        sampleTable.Rows(3)("Price") = 530
 
        'データを削除
        sampleTable.Rows(1).Delete()
        sampleTable.Rows(4).Delete()
 
        'データを追加
        sampleTable.Rows.Add("010", "商品020", 200)
        sampleTable.Rows.Add("011", "商品020", 210)
 
        '変更された行
        Console.WriteLine("--- 変更された行 ---")
        Dim dv As New DataView(sampleTable)
        dv.RowStateFilter = DataViewRowState.ModifiedCurrent
        For i = 0 To dv.Count - 1
            Console.WriteLine(dv(i)("ItemCD").ToString & " " & dv(i)("ItemName").ToString & " " & dv(i)("Price").ToString)
        Next
 
        '変更された行の元の値
        Console.WriteLine("--- 変更された行の元の値 ---")
        dv.RowStateFilter = DataViewRowState.ModifiedOriginal
        For i = 0 To dv.Count - 1
            Console.WriteLine(dv(i)("ItemCD").ToString & " " & dv(i)("ItemName").ToString & " " & dv(i)("Price").ToString)
        Next
 
        '削除された行の元の値
        Console.WriteLine("--- 削除された行の元の値 ---")
        dv.RowStateFilter = DataViewRowState.Deleted
        For i = 0 To dv.Count - 1
            Console.WriteLine(dv(i)("ItemCD").ToString & " " & _
                              dv(i)("ItemName").ToString & " " & dv(i)("Price").ToString)
        Next
 
        '追加された行
        Console.WriteLine("--- 追加された行の表示 ---")
        dv.RowStateFilter = DataViewRowState.Added
        For i = 0 To dv.Count - 1
            Console.WriteLine(dv(i)("ItemCD").ToString & " " & dv(i)("ItemName").ToString & " " & dv(i)("Price").ToString)
        Next
 
        '変更されてない行
        Console.WriteLine("--- 変更されてない行 ---")
        dv.RowStateFilter = DataViewRowState.Unchanged
        For i = 0 To dv.Count - 1
            Console.WriteLine(dv(i)("ItemCD").ToString & " " & dv(i)("ItemName").ToString & " " & dv(i)("Price").ToString)
        Next
    End Sub
 
End Module
実行結果

使用例はコンソールアプリケーションです。
VisualStudioの「新しいプロジェクト」から「コンソールアプリケーション」を選択しMain関数内にコードを記述します。
Ctrl+F5キーで実行します。


2013年11月27日水曜日

【VB.NET】DataView.ToTable 抽出した行から新しいDataTableを作成

DataViewのToTableで抽出した行を基に新しいDataTableを作成します。

  • DataView.ToTable()
    DataViewで抽出した行を基に新しいDataTableを作成します。
  • DataView.ToTable(TableName)
    DataViewで抽出した行を基に新しいテーブル名でDataTableを作成します。
      TableName‥新しいテーブル名
  • DataView.ToTable(Distinct,ColumnName())
    DataViewで抽出した行を基に重複した行を排除し新しいDataTableを作成します。
      DistinctTrue:重複した行を排除する False
    重複した行を排除しない
      ColumnName()‥新しいテーブルに含まれる列名の配列
  • DataView.ToTable(TableName,Distinct,ColumnName())
    DataViewで抽出した行を基に重複した行を排除し新しい名前でDataTableを作成します。
      TableName‥新しいテーブル名
      DistinctTrue:重複した行を排除する False
    重複した行を排除しない
      ColumnName()‥新しいテーブルに含まれる列名の配列
以下使用例です。
フォームにコントロールを配置
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'サンプルデータテーブル
        Dim sampleTable As New DataTable
        sampleTable.TableName = "SampleTable"
        sampleTable.Columns.Add("ItemCD", Type.GetType("System.String"))
        sampleTable.Columns.Add("ItemName", Type.GetType("System.String"))
        sampleTable.Columns.Add("Price", Type.GetType("System.Double"))
        sampleTable.Columns.Add("UnitSales", Type.GetType("System.Double"))
        sampleTable.Columns.Add("SalesAmount", Type.GetType("System.Double"))
 
        sampleTable.Rows.Add("001", "商品001", 100, 8, 100 * 8)
        sampleTable.Rows.Add("003", "商品003", 130, 5, 130 * 5)
        sampleTable.Rows.Add("001", "商品001", 100, 3, 100 * 3)
        sampleTable.Rows.Add("002", "商品002", 120, 6, 120 * 6)
        sampleTable.Rows.Add("002", "商品002", 120, 5, 120 * 5)
        sampleTable.Rows.Add("003", "商品003", 130, 7, 130 * 7)
        sampleTable.Rows.Add("003", "商品003", 130, 1, 130 * 1)
        sampleTable.Rows.Add("002", "商品002", 120, 3, 120 * 3)
        sampleTable.Rows.Add("001", "商品001", 100, 9, 100 * 9)
 
        'SampleTableの表示
        Me.DataGridView1.DataSource = sampleTable
 
        'DataViewを設定
        Dim dv As New DataView(sampleTable)
 
        '行を抽出
        dv.RowFilter = "ItemCD = '001' Or ItemCD = '003'"
 
        'DataViewを表示
        Me.DataGridView1.DataSource = dv
 
        '抽出された行で新しいDataTableを作成
        Dim newTable1 As DataTable = dv.ToTable()
        Me.DataGridView2.DataSource = newTable1
 
        '列を指定し重複した行の排除なしで新しいDataTableを作成
        Dim newTable2 As DataTable = dv.ToTable(False, "ItemCD")
        Me.DataGridView3.DataSource = newTable2
 
        '列を指定し重複した行を排除して新しい名前のDataTableを作成
        Dim newTable3 As DataTable = dv.ToTable("NewTable", True, "ItemCD", "ItemName")
        Me.DataGridView4.DataSource = newTable3
 
    End Sub
End Class
実行結果

【VB.NET】DataTableのコピー

DataTableのコピーです。

  1. DataTable.Clone
    DataTableのスキーム(構成)のみをコピーします。コピー元の空のテーブルが作られます。
  2. DataTable.Copy元のテーブルをデータごとコピーします。
  3. DataTable.Select(filter).CopyToDataTable
    抽出したデータをテーブルにコピーします。
以下使用例です。
フォームにコントロールを配置

Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'サンプルデータテーブル
        Dim sampleTable As New DataTable
        sampleTable.Columns.Add("ItemCD", Type.GetType("System.String"))
        sampleTable.Columns.Add("ItemName", Type.GetType("System.String"))
        sampleTable.Columns.Add("Price", Type.GetType("System.Double"))
        sampleTable.Columns.Add("UnitSales", Type.GetType("System.Double"))
        sampleTable.Columns.Add("SalesAmount", Type.GetType("System.Double"))
 
        sampleTable.Rows.Add("001", "商品001", 100, 8, 100 * 8)
        sampleTable.Rows.Add("003", "商品003", 130, 5, 130 * 5)
        sampleTable.Rows.Add("001", "商品001", 100, 3, 100 * 3)
        sampleTable.Rows.Add("002", "商品002", 120, 6, 120 * 6)
        sampleTable.Rows.Add("002", "商品002", 120, 5, 120 * 5)
        sampleTable.Rows.Add("003", "商品003", 130, 7, 130 * 7)
        sampleTable.Rows.Add("003", "商品003", 130, 1, 130 * 1)
        sampleTable.Rows.Add("002", "商品002", 120, 3, 120 * 3)
        sampleTable.Rows.Add("001", "商品001", 100, 9, 100 * 9)
 
        'サンプルデータテーブルを表示
        Me.DataGridView1.DataSource = sampleTable
 
        'サンプルデータテーブルのClone
        Dim newTable1 As DataTable = sampleTable.Clone
        Me.DataGridView2.DataSource = newTable1
 
        'サンプルデータテーブルのCopy
        Dim newTable2 As DataTable = sampleTable.Copy
        Me.DataGridView3.DataSource = newTable2
 
        'サンプルデータテーブルから抽出したデータをテーブルへCopy
        Dim newTable3 As DataTable = sampleTable.Select("ItemCD = '001'").CopyToDataTable
        Me.DataGridView4.DataSource = newTable3
 
    End Sub
End Class
実行結果

2013年11月24日日曜日

【VB.NET】Computeメソッドで列の集計

DataTable.Computeメソッドで列の集計をします。
Dim obj As Object = dtSample.Compute(expression , filter )
expression‥計算式、filter ‥抽出条件


使用例
フォームにコントロールを配置
Public Class Form1
 
    ''' <summary>
    ''' サンプルデータテーブル
    ''' </summary>
    ''' <remarks></remarks>
    Private dtSample As New DataTable
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'サンプルデータテーブル
        dtSample.Columns.Add("ItemCD", Type.GetType("System.String"))
        dtSample.Columns.Add("ItemName", Type.GetType("System.String"))
        dtSample.Columns.Add("Price", Type.GetType("System.Double"))
        dtSample.Columns.Add("UnitSales", Type.GetType("System.Double"))
        dtSample.Columns.Add("SalesAmount", Type.GetType("System.Double"))
 
        dtSample.Rows.Add("001", "商品001", 100, 8, 100 * 8)
        dtSample.Rows.Add("003", "商品003", 130, 5, 130 * 5)
        dtSample.Rows.Add("001", "商品001", 100, 3, 100 * 3)
        dtSample.Rows.Add("002", "商品002", 120, 6, 120 * 6)
        dtSample.Rows.Add("002", "商品002", 120, 5, 120 * 5)
        dtSample.Rows.Add("003", "商品003", 130, 7, 130 * 7)
        dtSample.Rows.Add("003", "商品003", 130, 1, 130 * 1)
        dtSample.Rows.Add("002", "商品002", 120, 3, 120 * 3)
        dtSample.Rows.Add("001", "商品001", 100, 9, 100 * 9)
 
        'Me.BindingSource1のDataSource設定
        Me.BindingSource1.DataSource = dtSample
 
        'Me.BindingSource1をDataGridView1へ連結
        Me.DataGridView1.DataSource = Me.BindingSource1
 
        'コンボボックス
        With Me.ComboBox1
            .Items.Add("")
            .Items.Add("001")
            .Items.Add("002")
            .Items.Add("003")
            .SelectedItem = ""
        End With
 
    End Sub
 
    ''' <summary>
    ''' SelectedIndexが変更された時
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
 
        '抽出条件
        Dim strFilter As String = Nothing
 
        '抽出条件の設定
        If Not Me.ComboBox1.SelectedItem = "" Then
            strFilter = "ItemCD = '" & Me.ComboBox1.SelectedItem & "'"
        End If
 
        'データ抽出"
        Me.BindingSource1.Filter = strFilter
 
        'SalesAmountの合計
        Me.TextBox1.Text = dtSample.Compute("SUM(SalesAmount)", strFilter).ToString
 
        'SalesAmountの平均
        Me.TextBox2.Text = Math.Round(dtSample.Compute("AVG(SalesAmount)", strFilter)).ToString
 
        'SalesAmountの最大値
        Me.TextBox3.Text = dtSample.Compute("MAX(SalesAmount)", strFilter).ToString
 
        'SalesAmountの最小値
        Me.TextBox4.Text = dtSample.Compute("MIN(SalesAmount)", strFilter).ToString
 
        'SalesAmountの行数
        Me.TextBox5.Text = dtSample.Compute("COUNT(SalesAmount)", strFilter).ToString
    End Sub
End Class
実行結果

【VB.NET】BindingNavigatorでフォームのレコードを操作する

BindingNavigatorでフォームのコントロールに連結されたデータレコードの移動や追加・削除といった操作ができます。

フォームにコントロールとBindingSource、BindingNavigatorを配置します。

BindingSourceを各コントロールとBindingNavigatorに連結します。
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("商品CD", Type.GetType("System.String"))
        dt.Columns.Add("商品名", Type.GetType("System.String"))
        dt.Columns.Add("単価", Type.GetType("System.Double"))
 
        For i = 1 To 20
            Dim nr As DataRow = dt.NewRow
            nr("商品CD") = i.ToString("000")
            nr("商品名") = "商品" & i.ToString("000")
            nr("単価") = i * 100
            dt.Rows.Add(nr)
        Next
 
        'BindingSource1のDataSourceを設定
        Me.BindingSource1.DataSource = dt
 
        'BindingSource1をBindingNavigator1と連結
        Me.BindingNavigator1.BindingSource = Me.BindingSource1
 
        'BindingSource1を各TextBoxと連結
        Me.TextBox1.DataBindings.Add(New Binding("Text", Me.BindingSource1, "商品CD"))
        Me.TextBox2.DataBindings.Add(New Binding("Text", Me.BindingSource1, "商品名"))
        Me.TextBox3.DataBindings.Add(New Binding("Text", Me.BindingSource1, "単価"))
 
        'BindingSource1をDataGridView1と連結
        Me.DataGridView1.DataSource = Me.BindingSource1
    End Sub
End Class
実行結果

2013年11月21日木曜日

【VB.NET】DataTableの並び替え

DataTableの行の抽出の引数またはプロパティに["列名 ソート方向"]を設定する。
ソート方向 ASC(省略可)‥昇順
        DESC‥降順

DataTable.Selectメソッドを使っての並び替え
Module Module1
 
    Sub Main()
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'データを抽出
        Dim rws() As DataRow = dt.Select("CATEGORY1 = '分類02'", "VAL1 ASC")
 
        '抽出したデータを出力
        For i = 0 To rws.Count - 1
            Dim str As String = Nothing
            For j = 0 To dt.Columns.Count - 1
                str = str & rws(i)(j).ToString & " "
            Next
            Console.WriteLine(str)
        Next
    End Sub
 
End Module
実行結果
DataViewを使っての並び替え
Module Module1
 
    Sub Main()
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'データを抽出
        Dim dv As New DataView(dt)
        dv.RowFilter = "CATEGORY1 = '分類03'"
        '並び替え
        dv.Sort = "VAL1 ASC"
 
        '抽出したデータを出力
        For i = 0 To dv.Count - 1
            Dim str As String = Nothing
            For j = 0 To dv.Table.Columns.Count - 1
                str = str & dv(i)(j).ToString & " "
            Next
            Console.WriteLine(str)
        Next
    End Sub
 
End Module
実行結果
BindingSourceを使っての並び替え
 フォームにDataGridView、BindingSourceを配置する
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'BindingSource1のDataSource設定
        Me.BindingSource1.DataSource = dt
 
        'データの抽出
        Me.BindingSource1.Filter = "CATEGORY1 = '分類01'"
 
        'データの並び替え
        Me.BindingSource1.Sort = "VAL1 ASC"
 
        'DataGridView1のDataSource設定
        Me.DataGridView1.DataSource = Me.BindingSource1
 
    End Sub
 
End Class
実行結果

2013年11月17日日曜日

【VB.NET】DataTableの行の抽出

DataTable.Selectメソッドを使っての抽出
Module Module1
 
    Sub Main()
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'データを抽出
        Dim rws() As DataRow = dt.Select("CATEGORY1 = '分類02'")
 
        '抽出したデータを出力
        For i = 0 To rws.Count - 1
            Dim str As String = Nothing
            For j = 0 To dt.Columns.Count - 1
                str = str & rws(i)(j).ToString & " "
            Next
            Console.WriteLine(str)
        Next
    End Sub
 
End Module
実行結果
DataViewを使っての抽出
Module Module1
 
    Sub Main()
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'データを抽出
        Dim dv As New DataView(dt)
        dv.RowFilter = "CATEGORY1 = '分類03'"
 
        '抽出したデータを出力
        For i = 0 To dv.Count - 1
            Dim str As String = Nothing
            For j = 0 To dv.Table.Columns.Count - 1
                str = str & dv(i)(j).ToString & " "
            Next
            Console.WriteLine(str)
        Next
    End Sub
 
End Module
実行結果
BindingSourceを使っての抽出
 フォームにDataGridView、BindingSourceを配置する
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
 
        dt.Rows.Add("0", "分類00", "名前0000", 15)
        dt.Rows.Add("1", "分類00", "名前0001", 23)
        dt.Rows.Add("2", "分類00", "名前0002", 75)
        dt.Rows.Add("3", "分類00", "名前0003", 0)
        dt.Rows.Add("4", "分類00", "名前0004", 69)
        dt.Rows.Add("5", "分類00", "名前0005", 45)
        dt.Rows.Add("6", "分類01", "名前0100", 96)
        dt.Rows.Add("7", "分類01", "名前0101", 12)
        dt.Rows.Add("8", "分類01", "名前0102", 69)
        dt.Rows.Add("9", "分類01", "名前0103", 2)
        dt.Rows.Add("10", "分類01", "名前0104", 2)
        dt.Rows.Add("11", "分類01", "名前0105", 18)
        dt.Rows.Add("12", "分類02", "名前0200", 8)
        dt.Rows.Add("13", "分類02", "名前0201", 72)
        dt.Rows.Add("14", "分類02", "名前0202", 95)
        dt.Rows.Add("15", "分類02", "名前0203", 55)
        dt.Rows.Add("16", "分類02", "名前0204", 22)
        dt.Rows.Add("17", "分類02", "名前0205", 99)
        dt.Rows.Add("18", "分類03", "名前0300", 74)
        dt.Rows.Add("19", "分類03", "名前0301", 51)
        dt.Rows.Add("20", "分類03", "名前0302", 68)
        dt.Rows.Add("21", "分類03", "名前0303", 18)
        dt.Rows.Add("22", "分類03", "名前0304", 99)
        dt.Rows.Add("23", "分類03", "名前0305", 37)
 
        'BindingSource1のDataSource設定
        Me.BindingSource1.DataSource = dt
 
        'データの抽出
        Me.BindingSource1.Filter = "CATEGORY1 = '分類01'"
 
        'DataGridView1のDataSource設定
        Me.DataGridView1.DataSource = Me.BindingSource1
 
    End Sub
 
End Class
実行結果

2013年11月10日日曜日

【VB.NET】DataRowViewでDataGridViewの現在の行のDataRowの取得する。

DataRowViewを使いDataGridViewの現在の行(または任意の行)からソース元のDataTableのDataRowを取得します。
Dim dgr As System.Windows.Forms.DataGridViewRow = Me.DataGridView1.CurrentRow
Dim drv As System.Data.DataRowView = CType(dgr.DataBoundItem, System.Data.DataRowView)
Dim dr As DataRow = CType(drv.Row, System.Data.DataRow)
使用例:フォームにDataGridViewとButtonを配置します。
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'サンプルデータテーブル
        Dim dt As New DataTable
        dt.Columns.Add("NO", Type.GetType("System.Double"))
        dt.Columns.Add("CATEGORY1", Type.GetType("System.String"))
        dt.Columns.Add("CATEGORY2", Type.GetType("System.String"))
        dt.Columns.Add("CATEGORY3", Type.GetType("System.String"))
        dt.Columns.Add("NAME", Type.GetType("System.String"))
        dt.Columns.Add("VAL1", Type.GetType("System.Double"))
        dt.Columns.Add("VAL2", Type.GetType("System.Double"))
        dt.Columns.Add("VAL3", Type.GetType("System.Double"))
        dt.Columns.Add("VAL4", Type.GetType("System.Double"))
        dt.Columns.Add("VAL5", Type.GetType("System.Double"))
 
        Dim r As New System.Random(1000)
 
        Dim no As Integer = 0
        For j1 = 0 To 100
            For j2 = 0 To 5
                For j3 = 0 To 3
                    Dim nr As DataRow = dt.NewRow
                    nr("NO") = no
                    nr("CATEGORY1") = "分類" & j1.ToString("00")
                    nr("CATEGORY2") = "分類" & j2.ToString("00")
                    nr("CATEGORY3") = "分類" & j3.ToString("00")
                    nr("NAME") = "名前" & j1.ToString("00") & j2.ToString("00") & j3.ToString("00")
                    nr("VAL1") = r.Next(10000)
                    nr("VAL2") = r.Next(10000)
                    nr("VAL3") = r.Next(10000)
                    nr("VAL4") = r.Next(10000)
                    nr("VAL5") = r.Next(10000)
                    dt.Rows.Add(nr)
 
                    no += 1
                Next
            Next
        Next
 
        Me.DataGridView1.DataSource = dt
 
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 
        Dim dgr As System.Windows.Forms.DataGridViewRow = Me.DataGridView1.CurrentRow
        Dim drv As System.Data.DataRowView = CType(dgr.DataBoundItem, System.Data.DataRowView)
        Dim dr As DataRow = CType(drv.Row, System.Data.DataRow)
 
        Console.WriteLine("---------------------------------------------------------")
        For i = 0 To dr.Table.Columns.Count - 1
            Console.WriteLine(dr.Table.Columns(i).ColumnName.ToString & " = " & dr.Item(i).ToString)
        Next
    End Sub
End Class
実行結果

2013年11月3日日曜日

記事を整理

ひとつのコントロールのコードを2つの記事に記載だと分かりづらいので、今までの記事を整理しました。

また【VB.NET】DataGridViewの列ヘッダーの2行表示のコード131~140行に間違いがありましたので修正しました。

2013年10月20日日曜日

【VB.NET】クラスライブラリー

これまでの記事のCustomHeaderDataGridView、CustomHeaderDataGridViewおよび
DataGridViewCustomDropDownComboBoxですが私はクラスライブラリーに作成しました。


クラスライブラリーのプロジェクト構成は以下の通りです。


各クラスのコードは以下の記事に記載されています。
クラスコードを記載した記事
CustomDropDownComboBox.vb【VB.NET】ComboBoxのリストに複数の列を表示する
DropDownColumn.vb
CustomHeaderDataGridView.vb【VB.NET】DataGridViewの列ヘッダーの複数行表示するカスタムコントロール①
HeaderCell.vb
DataGridViewCustomDropDownComboBoxCell.vb【VB.NET】DataGridViewのComboBoxのリストに複数の列を表示する
上記のプロイジェクトをビルドするとビルドの出力先にdllファイルとxmlファイルができます。
(TestFormですがこれは各コントロールの確認の為に使用したもので実際には不要です)


dllファイルとxmlファイルを任意のフォルダに置いて別のプロジェクトで参照しカスタムコントロールを
使用します。

参照方法

     
  1. プロジェクトの「参照」→「追加」→「参照の追加の参照タブを選択」→「任意のフォルダに置いたdllファイルを選択」
  2. 次にツールボックスにdllにあるカスタムコントロールを表示します。
    「ツール」→「ツールボックスアイテムの選択」→「参照」→「任意のフォルダに置いたdllファイルを選択」で.NET FrameWorkコンポーネントにコントロールが表示されるのでチェックを
    入れて「OK」で完了
後はツールボックスからカスタムコントロールをフォームに配置して使用します。

2013年9月10日火曜日

【VB.NET】DataGridViewのComboBoxのリストに複数の列を表示する

DataGridViewComboBoxのDataGridViewComboBoxColumn、DataGridViewComboBoxCellおよび
DataGridViewComboBoxEditingControlの各クラスを継承しドロップダウンリストに複数列表示する
DataGridViewCustomDropDownComboBoxの作成。

【VB.NET】ComboBoxのリストに複数の列を表示と同様に複数列の表示はDataSourceがDataTableの場合のみに限定します。DataSourceがDataTable以外の時は複数列の表示設定は無視されます。

先ず表示する列を定義するコレクションのためのDropDownColumnクラスを作ります。
(これは【VB.NET】ComboBoxのリストに複数の列を表示するのDropDownColumnクラス同じです
したがって同じプロジェクト内に含める場合は追加の必要はありません)

Imports System.Drawing
Imports System.ComponentModel
 
''' <summary>
''' ドロップダウンリストに表示される列の定義
''' </summary>
''' <remarks></remarks>
Public Class DropDownColumn
 
    ''' <summary>
    ''' 列のプロパティ
    ''' </summary>
    ''' <remarks></remarks>
    Private _member As String
 
    ''' <summary>
    ''' 列のプロパティを設定または取得します。
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Description("列のプロパティ")>
    Public Property Member As String
        Get
            Return _member
        End Get
        Set(ByVal value As String)
            _member = value
        End Set
    End Property
 
    ''' <summary>
    ''' 列の幅
    ''' </summary>
    ''' <remarks></remarks>
    Private _width As Integer = Nothing
 
    ''' <summary>
    ''' 列の幅を設定または取得します。
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Description("列の幅")>
    Public Property Width As Integer
        Get
            Return _width
        End Get
        Set(ByVal value As Integer)
            _width = value
        End Set
    End Property
 
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        'インスタンスの初期化
    End Sub
 
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="paramMember">表示する列名</param>
    ''' <param name="paramWidth">幅</param>
    ''' <remarks>ドロップダウンリストに表示される列の定義</remarks>
    Public Sub New(ByVal paramMember As String, ByVal paramWidth As Integer)
        Member = paramMember
        Width = paramWidth
    End Sub
End Class

次に各継承クラスを追加します。
  1. DataGridViewCustomDropDownComboBoxColumn‥DataGridViewComboBoxColumnを継承しCellTemplateに
    DataGridViewCustomDropDownComboBoxCellクラスのインスタンスを設定します。
  2. DataGridViewCustomDropDownComboBoxCell‥DataGridViewComboBoxCellを継承し
    DataGridViewCustomDropListComboBoxEditingControlをホストします。
  3. DataGridViewCustomDropListComboBoxEditingControl‥DataGridViewComboBoxEditingControlを継承しここでドロップダウンリストのアイテムが
    描画される時に複数列を描画します。
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Drawing
 
''' <summary>
''' 複数列のドロップダウンを表示するComboBoxColumn
''' </summary>
''' <remarks></remarks>
Public Class DataGridViewCustomDropDownComboBoxColumn
    Inherits DataGridViewComboBoxColumn
 
    Private _item As New MyCollection(Me)
 
    ''' <summary>
    ''' ドロップダウンリストの列を設定します。
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Category("ドロップダウンリストの列のカスタマイズ")> _
    <Description("ドロップダウンリストの列を設定します")>
    Public Property DropDownColumns() As MyCollection
        Get
            Return _item
        End Get
        Set(ByVal value As MyCollection)
            _item = value
        End Set
    End Property
 
    ''' <summary>
    ''' ドロップダウンリストの列コレクションの設定。
    ''' </summary>
    ''' <remarks></remarks>
    Public Class MyCollection
        Inherits System.Collections.ObjectModel.Collection(Of DropDownColumn)
 
        Private _parent As DataGridViewCustomDropDownComboBoxColumn
 
        Friend Sub New(ByVal parent As DataGridViewCustomDropDownComboBoxColumn)
            _parent = parent
        End Sub
 
        Protected Overrides Sub ClearItems()
            MyBase.ClearItems()
        End Sub
 
        Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As DropDownColumn)
            MyBase.InsertItem(index, item)
 
        End Sub
 
        Protected Overrides Sub RemoveItem(ByVal index As Integer)
            MyBase.RemoveItem(index)
        End Sub
 
        Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As DropDownColumn)
            MyBase.SetItem(index, item)
        End Sub
    End Class
 
    '新しいプロパティを追加しているため、
    ' Cloneメソッドをオーバーライドする必要がある
    Public Overrides Function Clone() As Object
        Dim col As DataGridViewCustomDropDownComboBoxColumn = _
            DirectCast(MyBase.Clone(), DataGridViewCustomDropDownComboBoxColumn)
        col.DropDownColumns = Me.DropDownColumns
        Return col
    End Function
 
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        Dim cel As New DataGridViewCustomDropDownComboBoxCell
        Me.CellTemplate = cel
    End Sub
 
    ''' <summary>
    ''' 現在選択されている行のメンバーの値を取得します。
    ''' </summary>
    ''' <param name="member"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property selectMemberValue(ByVal member As String)
        Get
            Dim cel As DataGridViewCustomDropDownComboBoxCell = _
                TryCast(Me.CellTemplate, DataGridViewCustomDropDownComboBoxCell)
 
            Return cel.selectMemberValue(member)
        End Get
    End Property
End Class
 
''' <summary>
''' 複数列のドロップダウンを表示するComboBoxCell
''' </summary>
''' <remarks></remarks>
Public Class DataGridViewCustomDropDownComboBoxCell
    Inherits DataGridViewComboBoxCell
 
    ''' <summary>
    ''' EditType
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides ReadOnly Property EditType() As Type
        Get
            Return GetType(DataGridViewCustomDropListComboBoxEditingControl)
        End Get
    End Property
 
    ''' <summary>
    ''' InitializeEditingControl
    ''' </summary>
    ''' <param name="rowIndex"></param>
    ''' <param name="initialFormattedValue"></param>
    ''' <param name="dataGridViewCellStyle"></param>
    ''' <remarks></remarks>
    Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, _
                                                  ByVal dataGridViewCellStyle As DataGridViewCellStyle)
        MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
 
        'セルを格納している複数列表示のコンボボックス列を取得
        Dim clm As DataGridViewCustomDropDownComboBoxColumn = _
            TryCast(Me.OwningColumn, DataGridViewCustomDropDownComboBoxColumn)
 
        '現在のセルでホストされている複数列表示のコンボボックスコントロール
        Dim ctrl As DataGridViewCustomDropListComboBoxEditingControl = _
            TryCast(DataGridView.EditingControl, DataGridViewCustomDropListComboBoxEditingControl)
 
        ctrl.ownerCell = Me
 
        'ホストされている複数列表示のコンボボックスコントロールの列の設定をクリア
        ctrl.DropDownColumns.Clear()
 
        'ホストされている複数列表示のコンボボックスコントロールの列の設定
        For i = 0 To clm.DropDownColumns.Count - 1
            ctrl.DropDownColumns.Add(New DropDownColumn(clm.DropDownColumns(i).Member, clm.DropDownColumns(i).Width))
        Next
 
    End Sub
 
    ''' <summary>
    ''' 現在選択されている行のメンバーの値を取得します。
    ''' </summary>
    ''' <param name="member"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property selectMemberValue(ByVal member As String)
        Get
            '現在のセルでホストされている複数列表示のコンボボックスコントロール
            Dim ctrl As DataGridViewCustomDropListComboBoxEditingControl = _
                TryCast(DataGridView.EditingControl, DataGridViewCustomDropListComboBoxEditingControl)
 
            Return ctrl.selectMemberValue(member)
        End Get
    End Property
 
End Class
 
''' <summary>
''' DataGridViewCustomDropListComboBoxEditingControl
''' </summary>
''' <remarks></remarks>
Public Class DataGridViewCustomDropListComboBoxEditingControl
    Inherits DataGridViewComboBoxEditingControl
 
    Private _item As New MyCollection(Me)
 
    ''' <summary>
    ''' ドロップダウンリストの列を設定します。
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Category("ドロップダウンリストの列のカスタマイズ")> _
    <Description("ドロップダウンリストの列を設定します")>
    Public Property DropDownColumns() As MyCollection
        Get
            Return _item
        End Get
        Set(ByVal value As MyCollection)
            _item = value
        End Set
    End Property
 
    ''' <summary>
    ''' ドロップダウンリストの列コレクションの設定。
    ''' </summary>
    ''' <remarks></remarks>
    Public Class MyCollection
        Inherits System.Collections.ObjectModel.Collection(Of DropDownColumn)
 
        Private _parent As DataGridViewCustomDropListComboBoxEditingControl
 
        Friend Sub New(ByVal parent As DataGridViewCustomDropListComboBoxEditingControl)
            _parent = parent
        End Sub
 
        Protected Overrides Sub ClearItems()
            MyBase.ClearItems()
        End Sub
 
        Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As DropDownColumn)
            MyBase.InsertItem(index, item)
        End Sub
 
        Protected Overrides Sub RemoveItem(ByVal index As Integer)
            MyBase.RemoveItem(index)
        End Sub
 
        Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As DropDownColumn)
            MyBase.SetItem(index, item)
        End Sub
    End Class
 
    Property ownerCell As DataGridViewCustomDropDownComboBoxCell = Nothing
 
    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        Me.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
    End Sub
 
    ''' <summary>
    ''' 現在選択されている行のメンバーの値を取得します。
    ''' </summary>
    ''' <param name="member"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property selectMemberValue(ByVal member As String)
        Get
            'データソースがない場合はNothingを返す。
            If MyBase.DataSource Is Nothing Then
                Return Nothing
            End If
 
            'データソースがデータテーブルでない場合はNothingを返す。
            If MyBase.DataSource.GetType IsNot GetType(DataTable) Then
                Return Nothing
            End If
 
            'DataTableを取得
            Dim dt As DataTable = CType(Me.DataSource, DataTable)
 
            'メンバーがデータテーブルの列でない場合はNothingを返す。
            If dt.Columns.IndexOf(member) = -1 Then
                Return Nothing
            End If
 
            'メンバーがデータテーブルの列の場合値を返す。
            Return dt.Rows(Me.SelectedIndex).Item(member)
        End Get
    End Property
 
    ''' <summary>
    ''' ドロップダウンリストItemが描画される時
    ''' </summary>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
        MyBase.OnDrawItem(e)
        '選択されているアイテムのハイライト
        e.DrawBackground()
        e.DrawFocusRectangle()
 
        'データソースがない場合は除外。
        If MyBase.DataSource Is Nothing Then
            Exit Sub
        End If
 
        'データソースがデータテーブルでない場合は除外
        If MyBase.DataSource.GetType IsNot GetType(DataTable) Then
            Exit Sub
        End If
 
        'データテーブルの取得
        Dim dt As DataTable = CType(MyBase.DataSource, DataTable)
 
        'アイテムの描画座標の取得
        Dim x As Integer = e.Bounds.X
        Dim y As Integer = e.Bounds.Y
        Dim width As Integer = e.Bounds.X
        Dim height As Integer = e.Bounds.Height
        Dim top As Integer = e.Bounds.Top
        Dim bottom As Integer = e.Bounds.Bottom
 
        '色の取得
        Dim grayPen As New Pen(Brushes.Gray)
        Dim brsh As New SolidBrush(e.ForeColor)
 
        '文字列の表示形式
        Dim sf As New StringFormat
        sf.Trimming = StringTrimming.EllipsisWord
 
        Try
            For i = 0 To Me.DropDownColumns.Count - 1
 
                '列の幅の取得
                width = Me.DropDownColumns(i).Width
 
                '最後の列の時は幅は右端まで
                If i = Me.DropDownColumns.Count - 1 AndAlso Me.Width > Me.DropDownWidth Then
                    width += Me.DropDownWidth - width
                End If
 
                '列の境界線の描画
                If i < Me.DropDownColumns.Count - 1 Then
                    e.Graphics.DrawLine(grayPen, x + width, top, x + width, bottom)
                End If
 
                '列のメンバーの取得
                Dim columnIndex As String = Me.DropDownColumns(i).Member
 
                '列のメンバーがない場合またはデータテーブルの列でない場合は除外
                If columnIndex Is Nothing OrElse columnIndex = String.Empty _
                    OrElse dt.Columns.IndexOf(columnIndex) = -1 Then
                    x += width
                    Continue For
                End If
 
                '列に表示する値を取得
                Dim text As String = dt.Rows(e.Index)(columnIndex).ToString
                '描画領域
                Dim rectF As New RectangleF(CSng(x), CSng(y), CSng(width), CSng(height))
                '値の描画
                e.Graphics.DrawString(text, e.Font, brsh, rectF, sf)
 
                '次の列の座標
                x += width
 
            Next
        Finally
            'リソースの解放
            grayPen.Dispose()
            brsh.Dispose()
            sf.Dispose()
        End Try
    End Sub
 
End Class
以下は簡単な使用例です。
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        'テーブルの作成
        Dim DtPerson As New DataTable
 
        DtPerson.Columns.Add("ID", Type.GetType("System.String"))
        DtPerson.Columns.Add("NAME", Type.GetType("System.String"))
        DtPerson.Columns.Add("ADDRESS", Type.GetType("System.String"))
 
        For i = 0 To 10
            Dim nr As DataRow = DtPerson.NewRow
            nr("ID") = i.ToString("000")
            nr("NAME") = "氏名" & i.ToString("000")
            nr("ADDRESS") = "新潟県○○市" & i.ToString("000")
            DtPerson.Rows.Add(nr)
 
        Next
 
        'DataGridViewComboBoxColumnを作成()
        Dim comboBoxColumn As New DataGridViewCustomDropDownComboBoxColumn
 
        With comboBoxColumn
            .HeaderText = "ID"
            .DataPropertyName = "ID"
            .DisplayMember = "ID"
            .ValueMember = "ID"
            .DataSource = DtPerson
            .DropDownWidth = 450
            .DropDownColumns.Add(New MyLibrary.DropDownColumn("ID", 100))
            .DropDownColumns.Add(New MyLibrary.DropDownColumn("NAME", 150))
            .DropDownColumns.Add(New MyLibrary.DropDownColumn("ADDRESS", 200))
        End With
 
        Me.DataGridView1.Columns.Add(comboBoxColumn)
    End Sub
End Class
実行結果
以外にあっさりできたので色々不具合でもあるのではと考えてしまいます。