C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

DataTableで列の値を一括更新する方法

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■87402 / inTopicNo.1)  DataTableで列の値を一括更新する方法
  
□投稿者/ いずみ (1回)-(2018/05/17(Thu) 21:47:40)

分類:[VB.NET/VB2005 以降] 

Visual Studio 2017 Community:Visual Basicを使用した、DataTableの値を更新する方法についての質問です。

col1 | col2
A01 | B101
A01 | B102
A02 | B201
A02 | B202

上記のようなDataTableがあったとして、[col1]列="A02"である行の[col2]列の値を一括更新したい場合、
C#では、次のような書き方をすることにより、機能の実現が可能になると思います。
[1]
dt.AsEnumerable().Where(r => r.Field<string>("col1") == "A02").Select(r => r["col2"] = "changed").ToList();


Visual Basicにおいて、これと同様の処理を行いたく、以下のように記述すればよいのかと考えたのですが、うまくいきません。
[1']?
dt.AsEnumerable.Where(Function(r) r.Field(Of String)("col1") = "A02").Select(Function(r) r("col2") = "changed").ToList

Visual Basicで、列の値を一括更新するためには、どのようにすればよいのでしょうか?
ご教示いただけると幸いです。
引用返信 編集キー/
■87403 / inTopicNo.2)  Re[1]: DataTableで列の値を一括更新する方法
□投稿者/ 魔界の仮面弁士 (1673回)-(2018/05/17(Thu) 22:51:58)
2018/05/18(Fri) 09:44:41 編集(投稿者)

No87402 (いずみ さん) に返信
> Visual Basicにおいて、これと同様の処理を行いたく、以下のように記述すればよいのかと考えたのですが、うまくいきません。

VB では、代入操作が『式』ではなく、『文(ステートメント)』だからですね。

C# にとっての
 .Select(r => r["col2"] = "changed")
というコードは、Visual Basic においては
 .Select(Function(r)
   r("col2") = "changed"
   Return "changed"
 End Function)
に相当するというわけで。




> 列の値を一括更新するためには
無理せず、For Each ループで書いた方が良い気もしますが、
どうしてもワンライナーにしたいのであれば、代入操作のために

・ステートメント実行のため、Func を受け取るメソッドではなく、Action を受け取るメソッドを使う
  → 例:ForEach メソッド

・代入処理と同時に、何かしらの値を返すメソッドを併用する
  → 例:CallByName、Interlocked.Exchange メソッドなど

といった手法をとることができます。



【案1】
// C#
Array.ForEach(dt.Select("col1='A02'"), r => r["col2"] = "changed");
' Visual Basic
Array.ForEach(dt.Select("col1='A02'"), Sub(r) r!col2 = "changed")


【案2】
// C#
dt.AsEnumerable().Where(r => r.Field<string>("col1") == "A02").Select(r => r["col2"] = "changed").ToArray();
' Visual Basic
dt.AsEnumerable().Where(Function(r) r.Field(Of String)("col1") = "A02").Select(Function(r) CallByName(r, Nothing, CallType.Let, "col2", "changed")).ToArray()
' Visual Basic
dt.AsEnumerable().Where(Function(r) "A02".Equals(r!col1)).Select(Function(r) Interlocked.Exchange(r!col2, "changed")).ToArray()



【案3】
// C#
(from r in dt.AsEnumerable() where r.Field<string>("col1") == "A02" select r).ToList().ForEach(r => r["col2"] = "changed");
// C#
dt.AsEnumerable().Where(r => r.Field<string>("col1") == "A02").ToList().ForEach(r => r["col2"] = "changed");
' Visual Basic
Call (From r In dt Where r.Field(Of String)("col1") = "A02").ToList().ForEach(Sub(r) r!col2 = "changed")
' Visual Basic
dt.AsEnumerable().Where(Function(r) r.Field(Of String)("col1") = "A02").ToList().ForEach(Sub(r) r!col2 = "changed")
引用返信 編集キー/
■87418 / inTopicNo.3)  Re[2]: DataTableで列の値を一括更新する方法
□投稿者/ いずみ (2回)-(2018/05/18(Fri) 21:54:56)
No87403 (魔界の仮面弁士 さん) に返信

迅速かつ的確なご回答、ありがとうございます。

> VB では、代入操作が『式』ではなく、『文(ステートメント)』だからですね。
この違いを理解できていなかったため、ご解説いただき非常に勉強になりました。

仰る通り、ForEachループを使用する方法が、最も素直でよいのでしょうけれど、
今回「代入操作」の手法について教えていただけたこと、とても嬉しく思います。
また、C#での場合と対応させてご記載くださったため、理解しやすかったです。

この度は誠にありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ