2011-01-15 9 views
2

私は72の列からなるデータテーブルを持っています。どのように2つのデータテーブルを比較するのですか

VSTOを使用してExcelシートをダウンロードしますが、これは正常に動作します。

これで、ユーザーはこれらの行の1つまたはこれらの行のすべてを変更し、新しい行を挿入します。

最初にダウンロードされたデータシートがdtAであり、Excelシートで修正されたデータテーブルがdtBであると考えます。

私はdtAとdtBを比較したいと思います。

dtAに存在しないdtBのすべての行を調べる必要があります。

私は、各行ごとにforeachループを入れず、非常に控えめなコーディング方法として評価しています。

これを行うにはどうすればよいですか?私はこの方法をやった

DataTable dtA = new DataTable(); 
    dtA.Columns.Add("ENo"); 
    dtA.Columns.Add("ENo1"); 
    dtA.Columns.Add("ENo2"); 
    dtA.Columns.Add("ENo3"); 
    dtA.Columns.Add("ENo4"); 

    for (int i = 0; i < 5; i++) 
    { 
     DataRow dr = dtA.NewRow(); 
     dr[0] = "Part 0 " + i.ToString(); 
     dr[1] = "Part 1 " + i.ToString(); 
     dr[2] = "Part 2 " + i.ToString(); 
     dr[3] = "Part 3 " + i.ToString(); 
     dr[4] = "Part 4 " + i.ToString(); 
     dtA.Rows.Add(dr); 
    } 

    DataTable dtB = new DataTable(); 
    dtB.Columns.Add("ENo"); 
    dtB.Columns.Add("ENo1"); 
    dtB.Columns.Add("ENo2"); 
    dtB.Columns.Add("ENo3"); 
    dtB.Columns.Add("ENo4"); 

    for (int i = 5; i < 10; i++) 
    { 
     DataRow dr = dtB.NewRow(); 
     dr[0] = "Part 0 " + i.ToString(); 
     dr[1] = "Part 1 " + i.ToString(); 
     dr[2] = "Part 2 " + i.ToString(); 
     dr[3] = "Part 3 " + i.ToString(); 
     dr[4] = "Part 4 " + i.ToString(); 
     dtB.Rows.Add(dr); 
    } 

    Response.Write("\n"); 
    Response.Write("dt A"); 
    Response.Write("\n"); 

    for (int i = 0; i < dtA.Rows.Count; i++) 
    { 
     Response.Write(dtA.Rows[i][i].ToString()); 
     Response.Write("\n"); 
    } 

    Response.Write("\n"); 
    Response.Write("dt B"); 
    Response.Write("\n"); 
    for (int i = 0; i < dtB.Rows.Count; i++) 
    { 
     Response.Write(dtB.Rows[i][i].ToString()); 
     Response.Write("\n"); 
    } 

    var VarA = dtA.AsEnumerable(); 
    var varB = dtA.AsEnumerable(); 

    var diff = VarA.Except(varB); 
    Response.Write("except"); 
    foreach (var n in diff) 
    { 
     Response.Write(n.Table.Rows[0].ToString()); 

    } 

しかし、私は、私はplsは何を使うべき のforeach varに使用するのか分からないのですか?

答えて

1
SELECT id FROM dtB WHERE id NOT IN (SELECT id FROM dtA) 
+0

ありがとうございます。答えはありますが、これは新しい行のみを取得します。変更するdtAの行はどうですか? – cmrhema

+0

元の質問で変更が見つかりませんでした。 Excelは「ON UPDATE CURRENT TIMESTAMP」列を持つことができないため、スプレッドシートにマクロを作成してWorksheet_Changeイベントにフックしてみてください。 http://www.ozgrid.com/forum/showthread.php?t=63176&page=1 – James

0

おそらくLINQ for DataSetsはオプションであってもよい(これは単なるデータセットはLINQをサポートし、.NET 3.5+フレームワークの一部であることを表します)。特に、IEnumerable.Exceptを使用しているExceptRows Set Patternをチェックしてください。行に何らかの「一意のID」が含まれていると最も簡単ですが、行自体が一意に失われているか、行が変更されているかどうかを検出するのに十分なはずです。

また、「データ[セット|テーブル]」の項目をサポートする唯一の製品(LINQが「SQL構文」を提供していると主張することもできます)があります。開発ライセンスは200ドルのポップですが、それに応じて価値があるかもしれません。 (私は提携しておらず、製品を試してみたこともなく、同様の問題の解決方法を見つけようとしたが、最終的には私のアプローチを変えた。)

ハッピーコーディング。

+0

こんにちはpstを参照してください。私は、Webサイトhttp://www.eggheadcafe.com/tutorials/aspnet/2eb80099-3611-43e0-82da-1d5889195d55/comparing-datasets-using-linq.aspxからコーディングを試みましたが、うまくいきましたが、私はそれを観察しますIenumerableの1つが値を持つ場合、キャスト例外エラーがスローされます。私はnewRec.count()> 0を与えた後、いくつかの作業を行います。カウントがない場合はエラーをスローし、dbnullは10進数に変換できません。解決策は何か – cmrhema

0
SELECT dtB.* FROM dtB LEFT JOIN dtA ON dtB.id=dtA.id /* AND ... */ 
WHERE dtA.id IS NULL 

dtAには一致しない行のみが表示されます。

JOIN条件の同じ行と同じにする必要がある列を追加できます。

データベースによっては、より簡単な方法があります。たとえば、まったく同じ行を削除するには、OracleにはMINUSというキーワードがあります。変更された行は引き続き結果に表示されます。

また、同じ行順であれば、両方のExcelファイルをテキスト(CSV、タブ区切りなど)としてエクスポートし、コマンドラインユーティリティdiffを使用して変更内容を確認できます。

diffアルゴリズムを実装するプログラミング言語用のライブラリが用意されているため、メモリ内ですべて実行できます。

関連する問題