投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/3/22 16:04:53
> これを型指定されたDataTableに格納したいのです。

こういうことでしょうか。

'あらかじめ、As Object(,) から 行単位に 1 次元化しておく 
Dim Items As Object() = {1, True"A"}

Dim row = dt.New表名Row()

'型指定な DataTable のために、個別に型を明示する方法もありますが 
'row.列名1 = CInt(Items(0)) 
'row.列名2 = CBool(Items(1)) 
'row.列名3 = CStr(Items(2)) 

'下記の手抜き実装でも十分です。(型チェックは DataTable 側に任せることになります) 
row.ItemArray = Items

dt.Add表名Row(row)



あるいは型指定した DataTable ではなく、素の DataTable を用いていて、
型が動的に決まるので自動判定したいという話なら、
  Dim t As Type = arr2D(1, 1).GetType()
などとして Type を得られますので、それを Columns.Add に渡して定義するという手も。


> Dim arr2D = TryCast(xlRange.Value, Object(,)) '1オリジンになることに注意 
> Dim rowCount = arr2D.GetLength(0) '行数 

これだと、NullReferenceException の可能性がありますね。
(xlRange が単一セルの場合など)

「Object(,) に変換できない場合」を想定していないのであれば、
TryCast を使う必要は無く、直接 DirectCast すれば十分かと思います。
型が違っていれば InvalidCastException になるので、むしろ分かりやすいのではないでしょうか。
Dim arr2D = DirectCast(xlRange.Value, Object(,))
Dim rowCount = arr2D.GetLength(0)



もしも TryCast するのであれば、変換できなかった場合に Nothing が返されることを
考慮したコードになっているべきですので、TryCast に続く行では、
 If arr2D IsNot Nothing Then
で判定するようにするとか、あるいは、
 'Dim rowCount = If(arr2D, New Object(-1, -1) {}).GetLength(0)
 Dim rowCount = If(arr2D?.GetLength(0), -1) 
のように、Nothing への対処を盛り込んだ方が良いでしょう。



> '1次元配列に変換 
> Dim arr1D = arr2D.Cast(Of Object)

1 次元配列への変換なら、
 Dim arr1D = arr2D.Cast(Of Object)().ToArray()
ですね。

元のコードだと、Dim arr1D As Object() にはなりません。
As IEnumerable(Of Object) として扱うことはできますが。


> Dim heder = Enumerable.Range(1, columnCount).Select(Function(x) $"列{x.ToString}").ToArray

$"列{x.ToString}" だと冗長なので、
$"列{x}" または $"列{x:D}" をお奨めしておきます。


> dt.Columns.Add(heder(i).ToString, GetType(String))

これも heder(i).ToString ではなく、header(i) だけで良いかと。
変数 header は「As String()」な型なので、ToString メソッドは冗長です。

String 値をわざわざ ToString() する必要性は無いはず…。
dt.Columns.Add(heder(i).ToString().ToString().ToString().ToString().ToString(), GetType(String))