投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/4/16 21:32:14
2 つ目のコードについても解説。


> Dim jsonList = JsonConvert.DeserializeObject(Of JObject)(TextBox1.Text)("list")
ここでは、(Of JObject) の型パラメーター付きのオーバーロードを用いています。
型パラメーターを使わず、Object で受け取ってから、CType や DirectCast を使っても良いです。
Dim jsonList = DirectCast(JsonConvert.DeserializeObject(TextBox1.Text), JObject)("list")


> Dim cols = jsonList("grouplist").Select(Function(g) g.ToString())
LINQ を用いて、grouplist 内の値を列挙しています。
上記の実行結果は、下記のようになります。
Dim cols() As String = {"fruit""animal""flower"}


> jsonDataTable.Columns.AddRange(cols.Select(Function(c) New DataColumn(c)).ToArray())
ここでは LINQ を用いて、3 つの列を一度に追加していますが、
下記のように、ループ処理で 3 回に分けて追加しても構いません。
For Each c As String In cols
   jsonDataTable.Columns.Add(New DataColumn(c))
Next



> For rowIndex = 0 To Integer.MaxValue - 1
To に渡した Integer.MaxValue は 2147483647 と同義ですので、
それを -1 して、rowIndex が 0~2147483646 の間で遷移していきます。

わざわざ上限値を 1 つ減らしているのは、OverflowException の発生を避けるための処置です。
Next に到達する度に、rowIndex が +1 されるためですね。

もしも上限いっぱいの 0~2147483647 の間で遷移させたい場合には、
「For rowIndex As Long = 0L To Integer.MaxValue」
のように、ループカウンターを Long 型にすることができます。

しかし、この後で呼び出す ElementAtOrDefault メソッドは Integer 型を必要とするため、
今回は As Long とはせず、Integer 型のままにしてあります。


> Dim newRow = jsonDataTable.NewRow()
> For Each col In cols
>     newRow(col) = jsonList(col).ElementAtOrDefault(rowIndex)
> Next

ElementAtDefault は、該当する位置の値が無い場合に Nothing を返します。

jsonList(col)(rowIndex) だと、インデックスが範囲外エラーになる可能性があるので、ここでは
jsonList(col).ElementAtOrDefault(rowIndex) をかわりに利用しています。


このループにより、下記のような動作が行われます。

newRow = jsonDataTable.NewRow()   '新しい行を作る 
newRow("fruit" ) = jsonList("fruit" ).ElementAtOrDefault(0)  'リンゴ 
newRow("animal") = jsonList("animal").ElementAtOrDefault(0)  'イヌ 
newRow("flower") = jsonList("flower").ElementAtOrDefault(0)  'バラ 
ここまで作ってから、DataTable に一行追加。

newRow = jsonDataTable.NewRow()   '新しい行を作る 
newRow("fruit" ) = jsonList("fruit" ).ElementAtOrDefault(1)  'バナナ 
newRow("animal") = jsonList("animal").ElementAtOrDefault(1)  'ネコ 
newRow("flower") = jsonList("flower").ElementAtOrDefault(1)  'ユリ 
ここまで作ってから、DataTable にまた一行追加。


>  If newRow.ItemArray.All(AddressOf IsDBNull) Then
>      Exit For
>  End If
fruit、animal、flower の 3 つすべてが Nothing だった場合は、
もうデータが無いことになるので、行追加のループを脱出させます。

JSON データを直接確認するなら、Nothing 判定のため IsNothing を使うところですが、
DataTable に格納したデータは DBNull に変化するため、IsNull で判定しています。