DatatableをListに変換することはできますか
投稿者 さとう  (学生)
投稿日時
2021/8/28 08:43:46
学校の課題でプログラムを作成しているのですが、DatatableからListに値を変換させる処理がどうしてもわかりません。どうか教えていただけないでしょうか。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/8/28 10:55:30
> DatatableからListに値を変換させる処理
DataTable は「行」と「列」をもつ 2 次元情報ですが、List(Of ) は 1 次元情報ですよね。
Dim x As List(Of Object()) や
Dim y As List(Of List(Of String)) や
Dim z() As List(Of String)
などの構造で良いのであれば、たとえばこう書けます。
sample(3)(0) が、「yourTable.Rows(3)(0)」相当になります。(4行目1列目の値取得)
行列を逆にして sample("COL1")(2) などにしたいなら、たとえばこんな感じ。(COL1 列の 3 行目の値取得)
DataTable は「行」と「列」をもつ 2 次元情報ですが、List(Of ) は 1 次元情報ですよね。
Dim x As List(Of Object()) や
Dim y As List(Of List(Of String)) や
Dim z() As List(Of String)
などの構造で良いのであれば、たとえばこう書けます。
sample(3)(0) が、「yourTable.Rows(3)(0)」相当になります。(4行目1列目の値取得)
Dim sample1 As List(Of Object()) = yourTable.AsEnumerable().Select(Function(r) r.ItemArray).ToList()
Dim sample2 As List(Of List(Of String)) = yourTable.AsEnumerable().Select(Function(r) r.ItemArray.Select(AddressOf Convert.ToString).ToList()).ToList()
Dim sample3() As List(Of Object) = yourTable.AsEnumerable().Select(Function(r) r.ItemArray.ToList()).ToArray()
行列を逆にして sample("COL1")(2) などにしたいなら、たとえばこんな感じ。(COL1 列の 3 行目の値取得)
Dim sample4 As Dictionary(Of String, List(Of Object)) = yourTable.Columns.Cast(Of DataColumn)().ToDictionary(Function(r) r.ColumnName, Function(r) New List(Of Object)())
For Each r As DataRow In yourTable.Rows
For Each col In sample4.Keys
sample4(col).Add(r(col))
Next
Next
投稿者 るきお  (社会人)
投稿日時
2021/8/28 11:07:37
私も例を作ってみたので紹介します。
私の場合は、行列構造の維持にこだわらず特定の値のリストを作るような例が中心です。
この例はVB2015以上で動作します。
私の場合は、行列構造の維持にこだわらず特定の値のリストを作るような例が中心です。
この例はVB2015以上で動作します。
'▼サンプルのDataTable を作成。xid と xname の2列からなるテーブルです。
Dim table As New Data.DataTable
table.Columns.Add("xid", GetType(Integer))
table.Columns.Add("xname", GetType(String))
table.Rows.Add(1, "徳川家康")
table.Rows.Add(2, "豊臣秀吉")
table.Rows.Add(3, "織田信長")
'■【例1A】Tableを構成する各行(DataRow)のListを作成します。
Debug.WriteLine("例1A")
Dim theList As New List(Of Data.DataRow)
For Each row As Data.DataRow In table.Rows
theList.Add(row)
Next
'変換結果を確認するために出力ウィンドウに出力
For Each row As Data.DataRow In theList
Debug.WriteLine($"{row("xid")} = {row("xname")}")
Next
'■【例1B】xname を持つ List(Of String)に 変換B
Debug.WriteLine("例1B")
Dim xnameList As New List(Of String)
For Each row As Data.DataRow In table.Rows
xnameList.Add(CStr(row("xname")))
Next
'変換結果を確認するために出力ウィンドウに出力
For Each xname As String In xnameList
Debug.WriteLine(xname)
Next
'■【例1C】xid を持つ List(Of Integer)に 変換
Debug.WriteLine("例1C")
Dim xidList As New List(Of Integer)
For Each row As Data.DataRow In table.Rows
xidList.Add(CInt(row("xid")))
Next
'変換結果を確認するために出力ウィンドウに出力
For Each xid As Integer In xidList
Debug.WriteLine(xid)
Next
投稿者 るきお  (社会人)
投稿日時
2021/8/28 11:11:03
LINQを使う例も紹介します。この例を実行するには、先頭の方に Imports System.Data が記述されており、NuGet で System.Data.Common をインストールしておく必要がある場合があります。
'▼サンプルのDataTable を作成。xid と xname の2列からなるテーブルです。
Dim table As New Data.DataTable
table.Columns.Add("xid", GetType(Integer))
table.Columns.Add("xname", GetType(String))
table.Rows.Add(1, "徳川家康")
table.Rows.Add(2, "豊臣秀吉")
table.Rows.Add(3, "織田信長")
'■【例2A】Tableを構成する各行(DataRow)のListを作成します。
Debug.WriteLine("例2A")
Dim theList As List(Of DataRow) = table.AsEnumerable.ToList
'変換結果を確認するために出力ウィンドウに出力
For Each row As DataRow In theList
Debug.WriteLine($"{row("xid")} = {row("xname")}")
Next
'■【例2B】xname を持つ List(Of String)に 変換
Debug.WriteLine("例2B")
Dim xnameList As New List(Of String)(From row In table.AsEnumerable Select CStr(row("xname")))
'変換結果を確認するために出力ウィンドウに出力
For Each xname As String In xnameList
Debug.WriteLine(xname)
Next
'■【例2C】xid を持つ List(Of Integer)に 変換
Debug.WriteLine("例2C")
Dim xidList As New List(Of Integer)(From row In table.AsEnumerable Select CInt(row("xid")))
'変換結果を確認するために出力ウィンドウに出力
For Each xid As Integer In xidList
Debug.WriteLine(xid)
Next
'■【例2D】xname と xid を持つ匿名型の List に変換
Debug.WriteLine("例2D")
Dim modelList = (From row In table.AsEnumerable
Select xname = CStr(row("xname")), xid = CInt(row("xid"))).ToList
'変換結果を確認するために出力ウィンドウに出力
For Each model In modelList
Debug.WriteLine($"{model.xid} = {model.xname}")
Next
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/8/28 11:36:07
> Dim xnameList As New List(Of String)(From row In table.AsEnumerable Select CStr(row("xname")))
VB のクエリ構文においては、
From row In table.AsEnumerable()
や
From row In table.Rows.Cast(Of DataRow)()
という処理を、もっと単純に
From row In table
と書くだけでも同じ結果が得られます。蛇足までに。
VB のクエリ構文においては、
From row In table.AsEnumerable()
や
From row In table.Rows.Cast(Of DataRow)()
という処理を、もっと単純に
From row In table
と書くだけでも同じ結果が得られます。蛇足までに。
投稿者 るきお  (社会人)
投稿日時
2021/8/28 15:16:39
> From row In table
> と書くだけでも同じ結果が得られます。蛇足までに。
情報ありがとうございます。
.NET 5/6 のコンソールアプリケーションでやってみたのですが、System.Data が 既定で Imports されておらず、ちょっと準備(=System.Data.CommonのインストールとImports)しないと From row In table という記述はできないようでした。
2つ目のコメントの例の方はその準備がしてあるので、より簡略に書けますね。
> と書くだけでも同じ結果が得られます。蛇足までに。
情報ありがとうございます。
.NET 5/6 のコンソールアプリケーションでやってみたのですが、System.Data が 既定で Imports されておらず、ちょっと準備(=System.Data.CommonのインストールとImports)しないと From row In table という記述はできないようでした。
2つ目のコメントの例の方はその準備がしてあるので、より簡略に書けますね。
投稿者 さとう  (学生)
投稿日時
2021/8/28 17:22:26
お二人とも、ありがとうございます。無事解決することが出来ました!
投稿者 るきお  (社会人)
投稿日時
2021/8/28 17:41:10
解決して何よりです。
>魔界の仮面弁士さん、
最後のコメントは手元で作成していたサンプルを見ながら書いてしまいました…。
>2つ目のコメントの例の方はその準備がしてあるので、より簡略に書けますね。
この部分は意味が通らないので無視してください…。
>魔界の仮面弁士さん、
最後のコメントは手元で作成していたサンプルを見ながら書いてしまいました…。
>2つ目のコメントの例の方はその準備がしてあるので、より簡略に書けますね。
この部分は意味が通らないので無視してください…。