Excel Vergleich funktioniert jetzt mit Ranges statt benannten Feldern. Es läuft auch wesentlich schneller, weil der Zugriff auf die Ranges über einen Array und nicht mehr einzeln erfolgt. Diese Funktion kann jetzt auf beliebige Excel auch außerhalb vom NSW angewandt werden.

This commit is contained in:
Daniel Schick 2022-06-28 14:46:39 +02:00
parent e8a4fcb227
commit f596a53a38
3 changed files with 123 additions and 12 deletions

View File

@ -25,7 +25,7 @@ namespace ENI2.Excel
protected Dictionary<string, Name> _nameDict; protected Dictionary<string, Name> _nameDict;
protected ILog _log; protected ILog _log;
#endregion #endregion Fields
#region Construction #region Construction
@ -39,7 +39,7 @@ namespace ENI2.Excel
this._excelWorkbooks = _excelApp.Workbooks; this._excelWorkbooks = _excelApp.Workbooks;
} }
#endregion #endregion Construction
#region Properties #region Properties
@ -47,6 +47,8 @@ namespace ENI2.Excel
internal Dictionary<string, Name> NameDict { get { return _nameDict; } } internal Dictionary<string, Name> NameDict { get { return _nameDict; } }
internal Sheets Worksheets { get { return _workBook.Worksheets; } }
#endregion #endregion
#region protected methods #region protected methods
@ -143,10 +145,14 @@ namespace ENI2.Excel
if(_nameDict.ContainsKey(lookup)) if(_nameDict.ContainsKey(lookup))
{ {
var range = _nameDict[lookup].RefersToRange; var range = _nameDict[lookup].RefersToRange;
range.Interior.Color = color; Colorize(range, color);
// range.Worksheet.Tab.ColorIndex = XlColorIndex.xlColorIndexAutomatic; }
range.Worksheet.Tab.Color = color; }
}
internal void Colorize(Range range, int color)
{
range.Interior.Color = color;
range.Worksheet.Tab.Color = color;
} }
#endregion #endregion

View File

@ -42,6 +42,20 @@ namespace ENI2.Excel
} }
} }
private static string GetExcelColumnName(int columnNumber)
{
string columnName = "";
while (columnNumber > 0)
{
int modulo = (columnNumber - 1) % 26;
columnName = Convert.ToChar('A' + modulo) + columnName;
columnNumber = (columnNumber - modulo) / 26;
}
return columnName;
}
public static string Compare(string sourcePath, string targetPath, out string errorMessage) public static string Compare(string sourcePath, string targetPath, out string errorMessage)
{ {
string fileName = Path.GetTempPath() + Guid.NewGuid().ToString() + ".xlsx"; string fileName = Path.GetTempPath() + Guid.NewGuid().ToString() + ".xlsx";
@ -51,10 +65,11 @@ namespace ENI2.Excel
try try
{ {
File.Copy(targetPath, fileName); File.Copy(targetPath, fileName);
ExcelReader source = new ExcelReader(sourcePath); ExcelReader source = new ExcelReader(sourcePath, true, false);
ExcelReader comparison = new ExcelReader(fileName, false); ExcelReader comparison = new ExcelReader(fileName, false, false);
/* /* erste Variante Vergleich über Namen der Zellen
// loop through named cells // loop through named cells
foreach (string name in comparison.NameDict.Keys) foreach (string name in comparison.NameDict.Keys)
{ {
@ -90,6 +105,77 @@ namespace ENI2.Excel
} }
*/ */
// Zweite Version durch alle Sheets werden Zellen der "used range" miteinander verglichen
foreach(Worksheet sourceSheet in source.Worksheets)
{
Worksheet targetSheet = null;
foreach(Worksheet sheet in comparison.Worksheets)
{
if (sourceSheet.Name.Equals(sheet.Name))
{
targetSheet = sheet;
break;
}
}
if (targetSheet == null) continue;
System.Diagnostics.Trace.WriteLine(string.Format("Processing sheet {0}", targetSheet.Name));
if(GetSheetRange(sourceSheet, out int sourceRows, out int sourceCols) && GetSheetRange(targetSheet, out int targetRows, out int targetCols))
{
// read source into 2 dim array
string rangeString = string.Format("A1:{0}{1}", GetExcelColumnName(Math.Max(sourceCols, targetCols)), Math.Max(sourceRows, targetRows));
object[,] sourceArray = sourceSheet.get_Range(rangeString).Value;
// read target into 2 dim array
object[,] targetArray = targetSheet.get_Range(rangeString).Value;
for (int rowidx = 1; rowidx <= Math.Max(sourceRows, targetRows); rowidx++)
{
for( int colidx = 1; colidx <= Math.Max(sourceCols, targetCols); colidx++)
{
string sourceText = null;
if(sourceArray[rowidx,colidx] != null) sourceText = sourceArray[rowidx,colidx].ToString();
string targetText = null;
if(targetArray[rowidx,colidx] != null) targetText = targetArray[rowidx, colidx].ToString();
if (sourceText == null)
{
if (targetText != null)
{
string targetRangeName = string.Format("{0}{1}", GetExcelColumnName(colidx), rowidx);
comparison.Colorize(targetSheet.Range[targetRangeName], diffColor);
counter++;
}
}
else if (targetText == null)
{
if (sourceText != null)
{
string targetRangeName = string.Format("{0}{1}", GetExcelColumnName(colidx), rowidx);
comparison.Colorize(targetSheet.Range[targetRangeName], diffColor);
counter++;
}
}
else if ((sourceText != null) && (targetText != null))
{
if (!sourceText.Equals(targetText))
{
string targetRangeName = string.Format("{0}{1}", GetExcelColumnName(colidx), rowidx);
// turn cell blue
comparison.Colorize(targetSheet.Range[targetRangeName], diffColor);
counter++;
}
}
}
}
}
else
{
errorMessage = "failed to get sheet ranges";
}
}
comparison.Save(fileName); comparison.Save(fileName);
errorMessage = string.Format("{0} differences found", counter); errorMessage = string.Format("{0} differences found", counter);

View File

@ -33,13 +33,15 @@ namespace ENI2.Excel
internal Dictionary<string, string> ImportValues { get; } = new Dictionary<string, string>(); internal Dictionary<string, string> ImportValues { get; } = new Dictionary<string, string>();
public ExcelReader(string filePath, bool openReadonly = true) public ExcelReader(string filePath, bool openReadonly = true, bool createNameFields = true)
{ {
this._workBook = _excelWorkbooks.Open(filePath, 0, openReadonly, 5, "", "", false, XlPlatform.xlWindows, "", false, false, 0, false, false, false); this._workBook = _excelWorkbooks.Open(filePath, 0, openReadonly, 5, "", "", false, XlPlatform.xlWindows, "", false, false, 0, false, false, false);
this.InitNameFields(); if(createNameFields)
this.InitNameFields();
// Determine if this is a Dakosy or BSMD Sheet // Determine if this is a Dakosy or BSMD Sheet
_sheetType = (_nameDict.Count > 10) ? SheetTypeEnum.BSMD : SheetTypeEnum.DAKOSY; if(createNameFields)
_sheetType = (_nameDict.Count > 10) ? SheetTypeEnum.BSMD : SheetTypeEnum.DAKOSY;
} }
public SheetTypeEnum SheetType { get { return _sheetType; } } public SheetTypeEnum SheetType { get { return _sheetType; } }
@ -584,6 +586,23 @@ namespace ENI2.Excel
return null; return null;
} }
internal string ReadCellAsText(string sheetName, int row, int col)
{
try
{
Worksheet workSheet = (Worksheet)_workBook.Worksheets[sheetName];
string result = workSheet.Range[row, col].Text.ToString();
if (!result.IsNullOrEmpty())
result = result.Trim().Clean();
return result;
}
catch (Exception e)
{
_log.Warn(e.Message);
}
return null;
}
// TODO THIS IS NOT WORKING // TODO THIS IS NOT WORKING
internal string ReadTextFromDropdown(string sheetName, string range) internal string ReadTextFromDropdown(string sheetName, string range)
{ {