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:
parent
e8a4fcb227
commit
f596a53a38
@ -25,7 +25,7 @@ namespace ENI2.Excel
|
||||
protected Dictionary<string, Name> _nameDict;
|
||||
protected ILog _log;
|
||||
|
||||
#endregion
|
||||
#endregion Fields
|
||||
|
||||
#region Construction
|
||||
|
||||
@ -39,7 +39,7 @@ namespace ENI2.Excel
|
||||
this._excelWorkbooks = _excelApp.Workbooks;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion Construction
|
||||
|
||||
#region Properties
|
||||
|
||||
@ -47,6 +47,8 @@ namespace ENI2.Excel
|
||||
|
||||
internal Dictionary<string, Name> NameDict { get { return _nameDict; } }
|
||||
|
||||
internal Sheets Worksheets { get { return _workBook.Worksheets; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected methods
|
||||
@ -143,10 +145,14 @@ namespace ENI2.Excel
|
||||
if(_nameDict.ContainsKey(lookup))
|
||||
{
|
||||
var range = _nameDict[lookup].RefersToRange;
|
||||
range.Interior.Color = color;
|
||||
// range.Worksheet.Tab.ColorIndex = XlColorIndex.xlColorIndexAutomatic;
|
||||
range.Worksheet.Tab.Color = color;
|
||||
}
|
||||
Colorize(range, color);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Colorize(Range range, int color)
|
||||
{
|
||||
range.Interior.Color = color;
|
||||
range.Worksheet.Tab.Color = color;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -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)
|
||||
{
|
||||
string fileName = Path.GetTempPath() + Guid.NewGuid().ToString() + ".xlsx";
|
||||
@ -51,10 +65,11 @@ namespace ENI2.Excel
|
||||
try
|
||||
{
|
||||
File.Copy(targetPath, fileName);
|
||||
ExcelReader source = new ExcelReader(sourcePath);
|
||||
ExcelReader comparison = new ExcelReader(fileName, false);
|
||||
ExcelReader source = new ExcelReader(sourcePath, true, false);
|
||||
ExcelReader comparison = new ExcelReader(fileName, false, false);
|
||||
|
||||
/*
|
||||
/* erste Variante Vergleich über Namen der Zellen
|
||||
|
||||
// loop through named cells
|
||||
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);
|
||||
errorMessage = string.Format("{0} differences found", counter);
|
||||
|
||||
@ -33,13 +33,15 @@ namespace ENI2.Excel
|
||||
|
||||
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.InitNameFields();
|
||||
if(createNameFields)
|
||||
this.InitNameFields();
|
||||
|
||||
// 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; } }
|
||||
@ -584,6 +586,23 @@ namespace ENI2.Excel
|
||||
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
|
||||
internal string ReadTextFromDropdown(string sheetName, string range)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user