/// Copyright(c) 2015-2016 pakkin. All Rights Reserved. /// [改訂履歴] /// 2015.11.30 作成 /// 2016.01.27 最終セルが結合セルのケースに対応 /// 2016.01.29 SortedListのReverse時の余計なインスタンス生成を削除 using System; using System.IO; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using System.Linq; using System.Security.Cryptography; namespace ConsoleApplication1 { class Program { public static void Main(string[] args) { string[] checkFiles = new string[] { @"C:\temp\1\comp.xlsx", @"C:\temp\2\comp.xlsx", @"C:\temp\3\comp.xlsx" }; Console.WriteLine("result:{0}", Program.ExcelDataComp(checkFiles)); Console.ReadKey(true); } private static bool ExcelDataComp(string[] inFiles) { if (inFiles.Length < 2) return true; // バイナリレベルで同じであれば終了 using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) using (FileStream fs1 = new FileStream(inFiles[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { bool binaryComp = true; var bs1 = md5.ComputeHash(fs1); for (int i = 1; i < inFiles.Length; i++) { using (FileStream fs2 = new FileStream(inFiles[i], FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var bs2 = md5.ComputeHash(fs2); if (!bs1.SequenceEqual(bs2)) binaryComp = false; } } if (binaryComp) return true; } // 同名ファイルは開けないので比較用にコピー Dictionary<int, Dictionary<string, string>> compFiles = new Dictionary<int, Dictionary<string, string>>(); string startupPath = new FileInfo(Environment.CommandLine.Replace("\"", "")).Directory.ToString(); for (int i = 0; i < inFiles.Length; i++) { Dictionary<string, string> dic = new Dictionary<string, string>(); dic["baseFile"] = inFiles[i]; dic["compFile"] = startupPath + string.Format(@"\compData{0}.xlsx", i); compFiles[i] = dic; File.Copy(dic["baseFile"], dic["compFile"], true); } // セル内のデータで比較する object[] pLastCell = new object[] { 11, Type.Missing }; object[] pOpen = Enumerable.Repeat(Type.Missing, 15).ToArray(); Object[,] xlsData1 = null; // object:× Object:○ Object[,] xlsData2 = null; // object:× Object:○ SortedList<string, object> comList = new SortedList<string, object>(); try { Type classType = Type.GetTypeFromProgID("Excel.Application"); comList["01xApp"] = Activator.CreateInstance(classType); comList["01xApp"].GetType().InvokeMember("DisplayAlerts", BindingFlags.SetProperty, null, comList["01xApp"], new object[] { false }); comList["01xApp"].GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, comList["01xApp"], new object[] { false }); comList["02boks"] = comList["01xApp"].GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, comList["01xApp"], null); pOpen[0] = compFiles[0]["compFile"]; comList["03bok1"] = comList["02boks"].GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, comList["02boks"], pOpen); comList["04sts1"] = comList["03bok1"].GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, comList["03bok1"], null); int stCount1 = (int)comList["04sts1"].GetType().InvokeMember("Count", BindingFlags.GetProperty, null, comList["04sts1"], null); // 比較対象ファイル数分繰り返し for (int i = 1; i < compFiles.Count; i++) { pOpen[0] = compFiles[i]["compFile"]; comList["03bok2"] = comList["02boks"].GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, comList["02boks"], pOpen); comList["04sts2"] = comList["03bok2"].GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, comList["03bok2"], null); int stCount2 = (int)comList["04sts2"].GetType().InvokeMember("Count", BindingFlags.GetProperty, null, comList["04sts2"], null); if (stCount1 != stCount2) return false; // 比較対象シート数分繰り返し for (int stNumber = 0; stNumber < stCount1; stNumber++) { int bulkFetchRows = 600; int bulkRowNo = -1; comList["05sht1"] = comList["04sts1"].GetType().InvokeMember("Item", BindingFlags.GetProperty, null, comList["04sts1"], new object[] { stNumber + 1 }); comList["05sht2"] = comList["04sts2"].GetType().InvokeMember("Item", BindingFlags.GetProperty, null, comList["04sts2"], new object[] { stNumber + 1 }); string stName1 = (string)comList["05sht1"].GetType().InvokeMember("Name", BindingFlags.GetProperty, null, comList["05sht1"], null); string stName2 = (string)comList["05sht2"].GetType().InvokeMember("Name", BindingFlags.GetProperty, null, comList["05sht2"], null); if (stName1 != stName2) return false; comList["06cls1"] = comList["05sht1"].GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, comList["05sht1"], null); comList["06cls2"] = comList["05sht2"].GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, comList["05sht2"], null); comList["07spc1"] = comList["06cls1"].GetType().InvokeMember("SpecialCells", BindingFlags.GetProperty, null, comList["06cls1"], pLastCell); comList["07spc2"] = comList["06cls2"].GetType().InvokeMember("SpecialCells", BindingFlags.GetProperty, null, comList["06cls2"], pLastCell); string lastAddr1 = (string)comList["07spc1"].GetType().InvokeMember("Address", BindingFlags.GetProperty, null, comList["07spc1"], null); string lastAddr2 = (string)comList["07spc2"].GetType().InvokeMember("Address", BindingFlags.GetProperty, null, comList["07spc2"], null); if (lastAddr1 != lastAddr2) return false; int lastRow = (int)comList["07spc1"].GetType().InvokeMember("Row", BindingFlags.GetProperty, null, comList["07spc1"], null); int lastColN = (int)comList["07spc1"].GetType().InvokeMember("Column", BindingFlags.GetProperty, null, comList["07spc1"], null); lastAddr1 = lastAddr1.Split(':')[lastAddr1.Split(':').Length - 1]; // 2016.01.27 insert string lastColC = lastAddr1.Replace("$", "").Replace(lastRow.ToString(), ""); for (int fullRow = 0; fullRow < lastRow; fullRow++) { // エクセルから値を取得 if (bulkRowNo <= fullRow) { if (fullRow + bulkFetchRows > lastRow) bulkFetchRows = lastRow - fullRow; bulkRowNo = fullRow + bulkFetchRows; if (comList.ContainsKey("08rng1")) { Marshal.FinalReleaseComObject(comList["08rng1"]); comList["08rng1"] = null; } if (comList.ContainsKey("08rng2")) { Marshal.FinalReleaseComObject(comList["08rng2"]); comList["08rng2"] = null; } if ("A" + (fullRow + 1) == lastColC + bulkRowNo) { object[] pRange = new object[] { "A" + (fullRow + 1) }; comList["08rng1"] = comList["06cls1"].GetType().InvokeMember("Range", BindingFlags.GetProperty, null, comList["06cls1"], pRange); comList["08rng2"] = comList["06cls2"].GetType().InvokeMember("Range", BindingFlags.GetProperty, null, comList["06cls2"], pRange); Object tmp1 = comList["08rng1"].GetType().InvokeMember("Value", BindingFlags.GetProperty, null, comList["08rng1"], null); Object tmp2 = comList["08rng2"].GetType().InvokeMember("Value", BindingFlags.GetProperty, null, comList["08rng2"], null); xlsData1 = new Object[,] { { null, null }, { null, tmp1 } }; xlsData2 = new Object[,] { { null, null }, { null, tmp2 } }; } else { object[] pRange = new object[] { "A" + (fullRow + 1), lastColC + bulkRowNo }; comList["08rng1"] = comList["06cls1"].GetType().InvokeMember("Range", BindingFlags.GetProperty, null, comList["06cls1"], pRange); comList["08rng2"] = comList["06cls2"].GetType().InvokeMember("Range", BindingFlags.GetProperty, null, comList["06cls2"], pRange); xlsData1 = (Object[,])comList["08rng1"].GetType().InvokeMember("Value", BindingFlags.GetProperty, null, comList["08rng1"], null); xlsData2 = (Object[,])comList["08rng2"].GetType().InvokeMember("Value", BindingFlags.GetProperty, null, comList["08rng2"], null); } } // エクセル行⇒擬似的バルクフェッチ配列行変換 int row = bulkFetchRows - bulkRowNo + fullRow + 1; // 比較処理 for (int col = 1; col <= lastColN; col++) { if (xlsData1[row, col] == null && xlsData2[row, col] == null) continue; if (xlsData1[row, col] == null || xlsData2[row, col] == null) return false; if (!xlsData1[row, col].Equals(xlsData2[row, col])) return false; } } Marshal.FinalReleaseComObject(comList["07spc1"]); comList["07spc1"] = null; Marshal.FinalReleaseComObject(comList["07spc2"]); comList["07spc2"] = null; Marshal.FinalReleaseComObject(comList["06cls1"]); comList["06cls1"] = null; Marshal.FinalReleaseComObject(comList["06cls2"]); comList["06cls2"] = null; Marshal.FinalReleaseComObject(comList["05sht1"]); comList["05sht1"] = null; Marshal.FinalReleaseComObject(comList["05sht2"]); comList["05sht2"] = null; } Marshal.FinalReleaseComObject(comList["04sts2"]); comList["04sts2"] = null; comList["03bok2"].GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, comList["03bok2"], null); Marshal.FinalReleaseComObject(comList["03bok2"]); comList["03bok2"] = null; } return true; } catch (Exception ex) { // 例外 Console.WriteLine("Excel Automation Error!:{0}\r\n{1}", ex.Message, ex.StackTrace); return false; } finally { // ファイルクローズ & 参照破棄(Reverse指定) foreach (string key in comList.Keys.Reverse()) { if (comList[key] == null) continue; if (key == "03bok1") comList["03bok1"].GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, comList["03bok1"], null); if (key == "03bok2") comList["03bok2"].GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, comList["03bok2"], null); if (key == "01xApp") comList["01xApp"].GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, comList["01xApp"], null); Marshal.FinalReleaseComObject(comList[key]); } // 比較用ファイルの削除 for (int i = 0; i < compFiles.Count; i++) File.Delete(compFiles[i]["compFile"]); } } } }
Copyright(c) 2014-2022 pakkin. All Rights Reserved.