【C#入門】DataTableの使い方(Select、Sort、Compute、LINQも解説)

DataTableって使ってますか?

DataTableは表形式のデータを扱う時に使います。表形式のデータを処理するために、SelectメソッドやComputeメソッドなどがあらかじめ用意されていて便利です。

この記事では、DataTableについて

  • DataTableとは?
  • DataSetで扱う方法
  • データを追加する方法
  • DataGridViewで表示する方法

といった基本的な内容から、Selectメソッドで絞り込み、LINQでデータ抽出、DataTableのソート、Computeメソッドで集計演算など実用的な使い方についても解説していきます。今回はDataTableについて、使い方をわかりやすく解説します。

目次

DataTableとは?

DataTableとはC#で表形式のデータを扱う時に使います。DataTableはクラスで表形式のデータを処理するために、SelectメソッドやComputeメソッドなどがあらかじめ用意されていて便利です。

DataSetで扱う方法

DataTableクラスで表形式のデータを扱う場合、DataSetクラスもあわせて使います。

DataSetクラスは表形式のデータをメモリ領域へ格納するクラスです。DataSetクラスはデータを保持するだけでなく、テーブル間の関係や制約なども保持することができます。

DataTableクラスとDataSetクラスで表形式のデータを扱う方法についてサンプルコードでみていきましょう。尚このサンプルコードでは、表形式のデータのカラム名を左から順に、「教科」「点数」「名前」「クラス名」とします。

using System;
using System.Data;

class Program
{
    static void Main(string[] args)
    {
        DataSet dataSet = new DataSet();
        DataTable table = new DataTable("Table");

        // カラム名の追加
        table.Columns.Add("教科");
        table.Columns.Add("点数", Type.GetType("System.Int32"));
        table.Columns.Add("氏名");
        table.Columns.Add("クラス名");

        // DataSetにDataTableを追加
        dataSet.Tables.Add(table);
    }
}

このサンプルコードでは、DataTableクラスのインスタンスtableからプロパティColumnsのAddメソッドを呼び出しカラム名を追加しています。そして、DataSetクラスのインスタンスdataSetからプロパティTablesのAddメソッドを呼び出しテーブルを追加しています。

[補足]エラーが出る場合

「using System.Data」した際に以下のようなエラーが出る場合があります。

Error CS0234: The type or namespace name ‘Data’ does not exist in the namespace ‘System’

その場合は、まずソリューションウィンドウの参照へ「System.Data」を追加する必要があります。

エラーが出る場合は、追加を行なってから再度ためしてみましょう。

データを追加する方法

それでは、表のデータを追加する方法についてみていきましょう。追加する方法はいくつかありますが、ここでは2種類ご紹介します。

DataRowを使う方法

まずはDataRowクラスを使う方法をご紹介します。

DataRow dr = table.NewRow();
dr["教科"] = "国語";
dr["点数"] = 90;
dr["氏名"] = "田中 一郎";
dr["クラス名"] = "A";
dataSet.Tables["Table"].Rows.Add(dr);

DataRowクラスを使ってデータを追加する方法をご紹介しましたが、カラムの数だけ記述量が多く冗長な感じですね。

Rows.Addを使う方法

Rows.Addメソッドを使うと手短に記述することができます。

table.Rows.Add("数学", 80, "田中 一郎", "A");
table.Rows.Add("英語", 70, "田中 一郎", "A");
table.Rows.Add("国語", 60, "鈴木 二郎", "A");
table.Rows.Add("数学", 50, "鈴木 二郎", "A");
table.Rows.Add("英語", 80, "鈴木 二郎", "A");
table.Rows.Add("国語", 70, "佐藤 三郎", "B");
table.Rows.Add("数学", 80, "佐藤 三郎", "B");
table.Rows.Add("英語", 90, "佐藤 三郎", "B");

DataGridViewで表示する方法

これをWPFのDataGridコントロールを使ってGUIで表示してみましょう。

ちなみにWPFとはHTMLに似た感覚で外観デザインを開発することができるGUI開発ライブラリのことです。C#でGUI開発を行う場合、WindowsフォームとWPFの2種類があります。

WindowsフォームはC言語などで使われるWin32 APIを継承しているのに対して、WPFはWin32 APIとは無関係で新たに実装されたGUI開発ライブラリです。

WPFはUI(ユーザー・インターフェイス)要素に拡大・縮小/回転などを掛けることができて、柔軟にカスタマイズできるなどの点で便利なGUI開発ライブラリです。

今回はWPFのDataGridコントロールについてご紹介していきます。

またBindingを使ってDataGridコントロールで表データを表示します。

WPFにはデータ・バインディングという機能があります。これは表示するデータに不整合がないか検証する機能と外観デザインとを分離する仕組みです。

データ・バインディングでは、外観デザインには「ここにはこのデータを表示する」という目印を入れるだけで、実際のデータは別のファイルから提供します。

WPFのDataGridコントロールの使い方やBindingについては、こちらで詳しく解説しています。ぜひ参考にしてください。

それではサンプルコードで確認しましょう。

MainWindow.xaml.cs:

using System.Data;

public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();

            DataSet dataSet = new DataSet();
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // DataSetにDataTableを追加
            dataSet.Tables.Add(table);

            // DataRowクラスを使ってデータを追加
            DataRow dr = table.NewRow();
            dr["教科"] = "国語";
            dr["点数"] = 90;
            dr["氏名"] = "田中 一郎";
            dr["クラス名"] = "A";
            dataSet.Tables["Table"].Rows.Add(dr);

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            this.DataContext = table;
        }
}

MainWindow.xaml(一部のみ):

<DataGrid ItemsSource="{Binding}" x:Name="dataGrid" >

実行結果:
c#_datatable01

Selectメソッドで絞り込み

DataTableクラスには、条件を満足するデータのみ抽出するSelectメソッドが用意されています。サンプルコードで確認しましょう。

using System;
using System.Data;

class Program {
        static void Main(string[] args) {
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("国語", 90, "田中 一郎", "A");
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            // Selectメソッドを使ってデータを抽出
            DataRow[] dRows = table.Select("教科 = '国語'");
            foreach (var row in dRows) {
                Console.WriteLine("点数:{0}点、氏名:{1}、クラス:{2}", row[1], row[2], row[3]);
            }
        }
}

実行結果:

点数:90点、氏名:田中 一郎、クラス:A
点数:60点、氏名:鈴木 二郎、クラス:A
点数:70点、氏名:佐藤 三郎、クラス:B

このサンプルコードではDataTableクラスのSelectメソッドを使って、カラム名「教科」が国語の場合にデータを抽出し出力表示しています。

LINQでデータ抽出

データを抽出するにはLINQを使う方法もあります。LINQを使ってデータを抽出する方法についてサンプルコードで確認しましょう。

using System;
using System.Data;

class Program {
        static void Main(string[] args) {
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("国語", 90, "田中 一郎", "A");
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            // LINQを使ってデータを抽出
            DataRow[] dRows = table.AsEnumerable()
                .Where(row => row.Field<string>("教科") == "国語").ToArray();
            foreach (var row in dRows) {
                Console.WriteLine("点数:{0}点、氏名:{1}、クラス:{2}", row[1], row[2], row[3]);
            }
        }
}

実行結果:

点数:90点、氏名:田中 一郎、クラス:A
点数:60点、氏名:鈴木 二郎、クラス:A
点数:70点、氏名:佐藤 三郎、クラス:B

LINQで抽出を行うために、まずはtableでAsEnumerableメソッドを実行します。そしてWhereオペレータで条件を指定します。LINQでデータを抽出する方がSelectメソッドで抽出する方法に比べて処理速度が速いと言われています。

LINQの使い方については、こちらで詳しく解説していますので、ぜひ参考にしてください。

DataTableのソート

DataTableデータをソートすることもできます。これもSelectメソッドを使う方法とLINQを使う方法があります。

Selectメソッドを使う方法

Selectメソッドで並べ替える場合は、第2引数でソート文字列を指定します。

昇順の場合、ソート文字列にはカラム名とASCを記述します。降順の場合、カラム名とDESCを記述します。

using System;
using System.Data;

class Program {
        static void Main(string[] args) {
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("国語", 90, "田中 一郎", "A");
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            // Selectメソッドを使ってデータを抽出
            DataRow[] dRows = table.Select("教科 = '国語'", "点数 DESC");
            foreach (var row in dRows) {
                Console.WriteLine("点数:{0}点、氏名:{1}、クラス:{2}", row[1], row[2], row[3]);
            }
        }
}

実行結果:

点数:90点、氏名:田中 一郎、クラス:A
点数:70点、氏名:佐藤 三郎、クラス:B
点数:60点、氏名:鈴木 二郎、クラス:A

このサンプルコードでは、点数で降順に並び替えています。

LINQを使う方法

LINQのOrderByメソッドを使い並び替えます。

昇順に並び替える場合はOrderByメソッドを使用し、降順に並び替える場合はOrderByDescendingメソッドを使用します。

using System;
using System.Data;

class Program {
        static void Main(string[] args) {
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("国語", 90, "田中 一郎", "A");
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            // LINQを使ってデータを抽出
            DataRow[] dRows = table.AsEnumerable()
                .Where(row => row.Field<string>("教科") == "国語")
                .OrderByDescending(row => row.Field<int>("点数")).ToArray();
            foreach (var row in dRows) {
                Console.WriteLine("点数:{0}点、氏名:{1}、クラス:{2}", row[1], row[2], row[3]);
            }
        }
}

実行結果:

点数:90点、氏名:田中 一郎、クラス:A
点数:70点、氏名:佐藤 三郎、クラス:B
点数:60点、氏名:鈴木 二郎、クラス:A

Computeメソッドで集計演算

DataTableクラスのComputeメソッドでMAX、MIN、SUM、AVEの集計演算ができます。ここでは代表してMAXで集計演算する場合についてご紹介します。

using System;
using System.Data;

class Program {
        static void Main(string[] args) {
            DataTable table = new DataTable("Table");

            // カラム名の追加
            table.Columns.Add("教科");
            table.Columns.Add("点数", Type.GetType("System.Int32"));
            table.Columns.Add("氏名");
            table.Columns.Add("クラス名");

            // Rows.Addメソッドを使ってデータを追加
            table.Rows.Add("国語", 90, "田中 一郎", "A");
            table.Rows.Add("数学", 80, "田中 一郎", "A");
            table.Rows.Add("英語", 70, "田中 一郎", "A");
            table.Rows.Add("国語", 60, "鈴木 二郎", "A");
            table.Rows.Add("数学", 50, "鈴木 二郎", "A");
            table.Rows.Add("英語", 80, "鈴木 二郎", "A");
            table.Rows.Add("国語", 70, "佐藤 三郎", "B");
            table.Rows.Add("数学", 80, "佐藤 三郎", "B");
            table.Rows.Add("英語", 90, "佐藤 三郎", "B");

            // Computeメソッドを使って集計演算
            object obj = table.Compute("Max(点数)", "教科 = '国語'");
            Console.WriteLine("国語の最高点:{0}点", (int)obj);
        }
}

実行結果:

国語の最高点:90点

まとめ

ここでは、DataTableクラスで表データを扱う方法について説明しました。GUIで表示したり、SelectメソッドやComputeメソッド、LINQで操作することができます。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次