将不同类型的列从数据表合并为一个更大的数据表

时间:2014-02-20 19:29:08

标签: vb.net datagridview datatable merge

我有两个单独的数据表,一个是整数,另一个是字符串。两者都是3x3大小,我想简单地合并两个表并在datagridview中显示它们,以便我显示3x6 datagridview。

Two separate datatables

我想把两者放在一起以获得下面的图像

Datatables joined

    Dim stringtable As New DataTable
    stringtable.Columns.Add("PK", GetType(Integer))
    stringtable.Columns.Add("Col1", GetType(Integer))
    stringtable.Columns.Add("Col2", GetType(Integer))
    stringtable.Columns.Add("Col3", GetType(Integer))

    stringtable.Rows.Add(1, 1, 1, 1)
    stringtable.Rows.Add(2, 2, 2, 2)
    stringtable.Rows.Add(3, 3, 3, 3)

    Dim primaryKey(1) As DataColumn
    primaryKey(0) = stringtable.Columns("Name")
    stringtable.PrimaryKey = primaryKey

    Dim Inttable As New DataTable
    Inttable.Columns.Add("PK", GetType(Integer))
    Inttable.Columns.Add("ColA", GetType(String))
    Inttable.Columns.Add("ColB", GetType(String))
    Inttable.Columns.Add("ColC", GetType(String))

    Inttable.Rows.Add(1, "A", "A", "A")
    Inttable.Rows.Add(2, "B", "B", "B")
    Inttable.Rows.Add(3, "C", "C", "C")

    primaryKey(0) = Inttable.Columns("Name")
    Inttable.PrimaryKey = primaryKey

    DataGridView2.DataSource = stringtable
    DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    DataGridView2.AllowUserToAddRows = False

    DataGridView1.DataSource = Inttable
    DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    DataGridView1.AllowUserToAddRows = False


    ''This is where I can't figure out what do
    Dim mergedTable As New DataTable
    mergedTable = DataGridView2.DataSource
    mergedTable.Merge(Inttable, False, MissingSchemaAction.Add)

    DataGridView3.DataSource = mergedTable

我尝试过一些东西,但似乎无法做到这一点。有时它会填充6x6 datagridview,其中包含12个空白单元格,有时会保留一个数据表的值,但会为第二个值的所有值填充空白。

修改 我编辑了我的代码,以反映在数据表中添加主键,但现在有些表填充了空白单元格。有人可以告诉我为什么数据表不会只是在主要数据上合并而不留空格

enter image description here

2 个答案:

答案 0 :(得分:3)

为了合并2个DataTable,你需要一个公共列 - 我想说,你最好/最简单的选择是向两者添加一个主键列,然后你可以像在代码中那样简单地合并它们。


<强>更新

根据您更新的代码,您的问题在于如何定义主键...

这里有几个问题:

  1. 您已使用名称PK定义了主键列,然后您拥有primaryKey(0) = Inttable.Columns("Name")
  2. 这应该是primaryKey(0) = Inttable.Columns("PK")

    1. 您可以按如下方式定义primaryKey数组:

      Dim primaryKey(1)As DataColumn

    2. 应该是:

      Dim primaryKey(0) As DataColumn
      

      使它只有一个值(你的方式实际上创建了一个2元素数组,因为它是数组的从零开始的语言)。

      您更改的代码应如下所示:

      Dim primaryKey(0) As DataColumn
      primaryKey(0) = stringtable.Columns("PK")
      stringtable.PrimaryKey = primaryKey
      

      我写这篇文章的首选方式是(尽管它会完成同样的事情)如下:

      stringtable.PrimaryKey = {stringtable.Columns("PK")}
      

      只是为了帮助你,这里是我创建的一些代码来做你想要做的事情(没有DataGridView部分)

      Dim stringtable As New DataTable
      stringtable.Columns.Add("PK", GetType(Integer))
      stringtable.Columns.Add("Col1", GetType(Integer))
      stringtable.Columns.Add("Col2", GetType(Integer))
      stringtable.Columns.Add("Col3", GetType(Integer))
      
      stringtable.Rows.Add(1, 1, 1, 1)
      stringtable.Rows.Add(2, 2, 2, 2)
      stringtable.Rows.Add(3, 3, 3, 3)
      
      stringtable.PrimaryKey = {stringtable.Columns("PK")}
      
      Dim Inttable As New DataTable
      Inttable.Columns.Add("PK", GetType(Integer))
      Inttable.Columns.Add("ColA", GetType(String))
      Inttable.Columns.Add("ColB", GetType(String))
      Inttable.Columns.Add("ColC", GetType(String))
      
      Inttable.Rows.Add(1, "A", "A", "A")
      Inttable.Rows.Add(2, "B", "B", "B")
      Inttable.Rows.Add(3, "C", "C", "C")
      
      Inttable.PrimaryKey = {Inttable.Columns("PK")}
      
      stringtable.Merge(Inttable, False, MissingSchemaAction.AddWithKey)
      

      希望这有帮助并且有意义!!

答案 1 :(得分:0)

使用LINQ

        Dim intTable As New DataTable
        Dim stringTable As New DataTable

        intTable.Columns.Add("Col1", GetType(Integer))
        intTable.Columns.Add("Col2", GetType(Integer))
        intTable.Columns.Add("Col3", GetType(Integer))

        intTable.Rows.Add(1, 1, 1)
        intTable.Rows.Add(2, 2, 2)
        intTable.Rows.Add(3, 3, 3)

        stringTable.Columns.Add("ColA", GetType(String))
        stringTable.Columns.Add("ColB", GetType(String))
        stringTable.Columns.Add("ColC", GetType(String))

        stringTable.Rows.Add("A", "A", "A")
        stringTable.Rows.Add("B", "B", "B")
        stringTable.Rows.Add("C", "C", "C")

        DataGridView2.DataSource = intTable
        DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView2.AllowUserToAddRows = False

        DataGridView1.DataSource = stringTable
        DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView1.AllowUserToAddRows = False

        Dim indexColumn1 As New Data.DataColumn("Index", GetType(Integer))
        Dim indexColumn2 As New Data.DataColumn("Index", GetType(Integer))
        intTable.Columns.Add(indexColumn1)
        stringTable.Columns.Add(indexColumn2)
        For i As Integer = 0 To intTable.Rows.Count - 1
            intTable.Rows(i)("Index") = i
            stringTable.Rows(i)("Index") = i
        Next

        Dim resultTable = From i In intTable.AsEnumerable()
                          Join s In stringTable.AsEnumerable()
                          On s("Index") Equals i("Index")
                          Select {i("Col1"), i("Col2"), i("Col3"), s("ColA"), s("ColB"), s("ColC")}

        Dim dt As New DataTable()
        dt.Columns.AddRange({New DataColumn("Col1"), New DataColumn("Col2"), New DataColumn("Col3"),
                             New DataColumn("ColA"), New DataColumn("ColB"), New DataColumn("ColC")})
        For Each result In resultTable
            dt.LoadDataRow(result, True)
        Next

        DataGridView3.DataSource = dt
        DataGridView3.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView3.AllowUserToAddRows = False