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

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

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

Re[3]: Datatableの 比較テーブルを作成したい


(過去ログ 172 を表示中)

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

■99035 / inTopicNo.1)  Datatableの 比較テーブルを作成したい
  
□投稿者/ Tarou (1回)-(2022/02/01(Tue) 18:30:44)

分類:[.NET 全般] 

環境:Win10 環境:Visual Studio2015 言語:VB.NET

やりたいこと ファイルコピーを行うための Datatableの比較テーブルを作成したい


コピー元とコピー先のディレクトリでSystem.IO.Directory.GetFilesを行い
ファイル一覧を取得(この際に作成日及び更新日も取得)
してTableA(コピー元)とTableB(コピー先)に作成


TableA(コピー元)
 列A(絶対ファイルパス)
 列B(相対ファイルパス)
 列C(作成日)
 列D(更新日)
 
TableB(コピー先)
 列A(絶対ファイルパス)
 列B(相対ファイルパス)
 列C(作成日)
 列D(更新日)



TableAとTableBの列B(相対ファイルパス)と列D(更新日)を比較して

TableBに無いものを TableC に摘出

TableBにあるけど 更新日が TableAの列D(更新日)の更新日より古いものをTableDに摘出したいと考えております

LINQを使えばできるのかなと思ったのですがイマイチLINQのが理解できなかったので 教えていただけると幸いです

一応力技で考えたのが
TableAを1行読んで コピー先にSystem.IO.File.Existsでファイルの存在確認
ファイルが有った場合のみSystem.IO.File.GetLastWriteTimeで更新日取得
列Dと比較してTableAに列E(コピーフラグ)みたいなのを作って コピーするフラグを立てる
というのをTableAの行数だけ回すということも考えました


参考サイト
http://bbs.wankuma.com/index.cgi?mode=al2&namber=27396&KLOG=50

https://blog.jhashimoto.net/entry/2015/07/30/120000

引用返信 編集キー/
■99036 / inTopicNo.2)  Re[1]: Datatableの 比較テーブルを作成したい
□投稿者/ radian (6回)-(2022/02/01(Tue) 19:46:32)
2022/02/02(Wed) 08:06:47 編集(投稿者)
using System;
using System.Data;
using System.Linq;

class Program
{
    static void Main()
    {
        var tableA = new DataTable();
        tableA.Columns.Add("FilePath");
        tableA.Rows.Add("aaa");
        tableA.Rows.Add("bbb");
        tableA.Rows.Add("ccc");
        tableA.Rows.Add("ddd");
        var tableB = tableA.Clone();
        tableB.Rows.Add("aaa");
        tableB.Rows.Add("ccc");

        // tableBのFilePath検索用のHashSet
        var hashFilePathB = tableB.AsEnumerable()
            .Select(x => x["FilePath"])
            .ToHashSet();

        // tableBにFilePathが含まれないDataRowを元にtableCを作成
        var tableC = tableA.AsEnumerable()
            .Where(x => !hashFilePathB.Contains(x["FilePath"]))
            .CopyToDataTable();

        foreach(var row in tableC.AsEnumerable())
        {
            Console.WriteLine(row["FilePath"]); // "bbb"と"ddd"が出力される
        }

        Console.ReadKey();
    }

}

tableDは、試しに考えてみてください。

引用返信 編集キー/
■99037 / inTopicNo.3)  Re[1]: Datatableの 比較テーブルを作成したい
□投稿者/ くま (148回)-(2022/02/01(Tue) 19:48:41)
> Datatableの比較テーブル
コピー元とコピー先と比較のDatatableはDataGridViewで表示とかで使うのですか?

引用返信 編集キー/
■99038 / inTopicNo.4)  Re[2]: Datatableの 比較テーブルを作成したい
□投稿者/ Tarou (2回)-(2022/02/01(Tue) 20:07:12)
>radian さん
ありがとうございます とりあえずc#に馴染みがないのでVB.NETにコード変換してコードを詳しく見てみますね

>くま さん
使います画面の実装は コピー元のファイルリスト・コピー先のファイルリスト・ 更新されたファイルリスト・新規作成されたファイルリストを4つのDataGridViewに表示させます
(現状でもコピー元のファイルリスト・コピー先のファイルリストはすでに表示する段階まで実装済みです)

引用返信 編集キー/
■99039 / inTopicNo.5)  Re[3]: Datatableの 比較テーブルを作成したい
□投稿者/ くま (149回)-(2022/02/01(Tue) 20:16:15)
> TableAを1行読んで コピー先にSystem.IO.File.Existsでファイルの存在確認
> ファイルが有った場合のみSystem.IO.File.GetLastWriteTimeで更新日取得
> 列Dと比較してTableAに列E(コピーフラグ)みたいなのを作って コピーするフラグを立てる
> というのをTableAの行数だけ回すということも考えました

これ多分考え方が色々混じってるよ
まず「TableB(コピー先)」のテーブルは
前提としてコピー先の構成が絶対に変更にならないのであれば事前に用意する事ができるけど
違う場合はファイル情報を1つごとに参照しないといけないよね
だから事前準備ができない。
そうするとLINQの利点はあまりないと思います。

vb.netだったらこの場合「FileInfoクラス」のほうが良いと思います。
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.fileinfo?view=net-6.0
https://dobon.net/vb/dotnet/file/filecopy.html#fileinfo

TableA(コピー元)
 列A(絶対ファイルパス)
 列B(相対ファイルパス)
 列C(作成日)
 列D(更新日)
 列E(コピー先絶対ファイルパス)


1. 列Aの値でFileInfoクラスを取得
(エラーの場合、ファイルが存在しないので次の処理へ)
2. 列Eの値でFileInfoクラスを取得
(エラーの場合、コピー先にファイルが存在しないのでTableCへ)
3. 列AのFileInfoクラスと列EのFileInfoクラスの作成日及び更新日で比較
値が「異なる」場合、コピー対象としてTableDへ出力

となると比較前の表示が必要なければ列C、列Dの値は空で良い
(1.で取得できたときに設定する)
となります。

なんか最近この手の質問が多いのはどっかで課題とかででているの?
引用返信 編集キー/
■99040 / inTopicNo.6)  Re[4]: Datatableの 比較テーブルを作成したい
□投稿者/ くま (150回)-(2022/02/01(Tue) 20:23:28)
2022/02/01(Tue) 20:29:19 編集(投稿者)

> 使います画面の実装は コピー元のファイルリスト・コピー先のファイルリスト・ 更新されたファイルリスト・新規作成されたファイルリストを4つのDataGridViewに表示させます
> (現状でもコピー元のファイルリスト・コピー先のファイルリストはすでに表示する段階まで実装済みです)
さっきの例は表示用のデータを作成する際の話ね。

あとさっきの例だと「コピー元になくってコピー先にある場合」を1.で無視したけど削除が必要なら2.まで進めて判定できるので。
引用返信 編集キー/
■99041 / inTopicNo.7)  Re[3]: Datatableの 比較テーブルを作成したい
□投稿者/ radian (7回)-(2022/02/01(Tue) 20:38:18)
2022/02/02(Wed) 09:45:24 編集(投稿者)
2022/02/02(Wed) 08:06:14 編集(投稿者)

■No99038 (Tarou さん) に返信
> >radian さん
> ありがとうございます とりあえずc#に馴染みがないのでVB.NETにコード変換してコードを詳しく見てみますね

ああ、VB.NETでしたか。

Module Module1

    Sub Main()
        Dim tableA = New DataTable()
        tableA.Columns.Add("FilePath")
        tableA.Columns.Add("UpdDate", GetType(Date))
        tableA.Rows.Add({"aaa", New Date(2022, 1, 1)})
        tableA.Rows.Add({"bbb", New Date(2022, 1, 2)})
        tableA.Rows.Add({"ccc", New Date(2022, 1, 3)})
        tableA.Rows.Add({"ddd", New Date(2022, 1, 4)})
        Dim tableB = tableA.Clone()
        tableB.Rows.Add({"aaa", New Date(2022, 1, 1)})
        tableB.Rows.Add({"ccc", New Date(2022, 1, 2)})

        Dim dicFilePathB = tableB.AsEnumerable().
            ToDictionary(Of String, DataRow)(
                Function(x) x("FilePath"),
                Function(x) x
            )

        Dim tableC = (From row In tableA.AsEnumerable()
                      Where Not dicFilePathB.ContainsKey(row("FilePath"))
                     ).CopyToDataTable()

        For Each row In tableC.AsEnumerable()
            Console.WriteLine(row("FilePath"))
        Next

        Console.ReadKey()
    End Sub

End Module

こんなもんでどうでしょう。
Whereの条件変えれば、tableD も出来ると思います。

> 画面の実装は コピー元のファイルリスト・コピー先のファイルリスト・ 更新されたファイルリスト・新規作成されたファイルリストを4つのDataGridViewに表示させます

TableAとTableBの結果を同一DataTableの別の列にマージして、
そのDataTableに対して複数のDataView作ってフィルタ掛けたりとかでも行けるかも?

http://okwakatta.net/code2/dvw02.html

引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -