投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/12/14 19:40:27
ADODB.Recordset を使っているのなら、
 → GetRows メソッドで二次元配列化
 → GetString メソッドで CSV/TSV 化
をループなしで一括変換できますね。

ループ中で変換・判定処理とかを行っている場合には使えませんが、
単純出力の場合には便利かと思います。


> ADO.netについてはまだ勉強不足で試してせていないのですが
ということは、VB.NET をお使いですか? (VBA では ADO.NET を使えませんので)


もしも VB.NET から ADODB を扱う場合、先に紹介した URL にもありますように、
使用後に COM オブジェクトを Marshal.ReleaseComObject メソッドで
解放する必要があります。

Recordset の解放は、手順的にはこんなイメージですね。
(掲示板に直接記述したので、試してはいませんが)
Recordset などと同様に、Connection オブジェクトも解放対象です。

Dim fs = rs.Fields    'Fiedls コレクション オブジェクト 
Dim fCol1 = fs("Col1")  'Field オブジェクト 
Dim fCol2 = fs("Col2")  'Field オブジェクト…フィールドの数だけ用意する 
row = -1
Do Until rs.EOF
    row += 1
    ary(0, row) = fCol1.Value
    ary(1, row) = fCol2.Value
    rs.MoveNext()
Loop
If Marshal.IsComObject(fCol2) Then Marshal.ReleaseComObject(fCol2)  '解放処理 
If Marshal.IsComObject(fCol1) Then Marshal.ReleaseComObject(fCol1)  '解放処理 
If Marshal.IsComObject(fs) Then Marshal.ReleaseComObject(fs)  '解放処理 
rs.Close()
If Marshal.IsComObject(rs) Then Marshal.ReleaseComObject(rs)  '解放処理 
ReDim Preserve ary(1, row)




なお、上記で IsComObject メソッドで事前チェックしているのは、
「Fields が COM オブジェクトかどうか」が異なる可能性があるためです。
これは、参照設定している ADODB のライブラリが
自動生成された Interop アセンブリ (IA) を使っているのか、それとも
システムに登録された Primary Interop アセンブリ(PIA) を使っているのかで変わります。

そして 基本的には、PIA の利用が強く推奨されています。
(しかしそれ以上に、ADODB から ADO.NET に移行することがさらに望ましい)
https://bit.ly/3hsV9JC


もし、Fields や Field のオブジェクト管理が面倒なのであれば、
フィールドへのアクセスに Collect プロパティを使う手もあります。

「rs.Fields("Col1").Value = NewValue」ではなく
「rs.Collect("Col1") = NewValue」とする感じで。

Collect プロパティが読み書きする値は、COM オブジェクトではないはずなので、
この場合、解放処理は Recordset (と Connection) だけで済むでしょう。

※ただし稀に、COM オブジェクトが返されるケースもあります。
 たとえば "Provider=MSDataShape" の場合、階層型 Recordset として、
 列の値として「子階層の Recrodset」が入れ子上に返されてきたりします。