Все, что я пытаюсь сделать, это открыть 2 файла Excel (оба листа Sheet1), которые имеют одинаковую точную структуру, но могут иметь разные числовые значения, прочитать их и создать третий файл с «New» минус «Base». Если значения одинаковы в обоих случаях, не имеет значения, отображает 0 или 0,00 или вообще ничего.
Пример: Новый файл
Item Price Discount
A 10.00 1.00
B 9.00 0.00
Account
Gross Sales 980000.00
Пример: Базовый файл
Item Price Discount
A 10.00 2.00
B 9.00 0.00
Account
Gross Sales 980000.00
Пример: файл результатов
Item Price Discount
A 0.00 -1.00
B 0.00 0.00
Account
Gross Sales 0.00
У кого-нибудь есть идеи, как этого добиться? Или ссылка, где я могу найти что-то подобное? Благодарю вас.
Я получил код ниже из предыдущего примера, созданного сотрудником, где он делает что-то очень похожее. Я попытался добавить его код, результаты пока:
Базовый файл: там, где есть числовое значение, окрашивается красным
Новый файл: там, где есть числовое значение, окрашивается красным
Конечный файл: пустые, но те же ячейки окрашены в красный и желтый.
Я надеялся, что есть лучший способ сделать это, какие-либо рекомендации для следующего кода?
public bool createReport_NewMinusBase (string currentWorkingDirectory, string Book1, string Book2, double tolerance)
{
myExcel.Application excelApp = new myExcel.Application(); // Creates a new Excel Application
excelApp.Visible = true; // Makes Excel visible to the user.
int row = 0;
int col = 0;
int maxR = 0;
int maxC = 0;
//useful for COM object interaction
object missing = System.Reflection.Missing.Value;
//Return value
bool wereDifferences = false;
//Comparison objects
object objNew = null;
object objBase = null;
//source: http://www.codeproject.com/KB/office/csharp_excel.aspx
excelApp.Application.DisplayAlerts = false;
//Open BASE FILE
myExcel.Workbook excelWorkbook1 = excelApp.Workbooks.Open(currentWorkingDirectory + Book1, 0,
missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
//OPEN NEW FILE
myExcel.Workbook excelWorkbook2 = excelApp.Workbooks.Open(currentWorkingDirectory + Book2, 0,
missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
myExcel.Worksheet wsBase;
myExcel.Worksheet wsDiff;
myExcel.Worksheet wsNew;
//create reportBaseMinusNew.xlsx
excelApp.Visible = true;
excelApp.WindowState = myExcel.XlWindowState.xlMinimized;
myExcel.Workbook report = excelApp.Workbooks.Add(myExcel.XlWBATemplate.xlWBATWorksheet);
report.SaveAs(currentWorkingDirectory+ "testReport.xlsx",
Type.Missing, Type.Missing, Type.Missing,false, false, myExcel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
try
{
wsBase = (myExcel.Worksheet)excelApp.Workbooks[Book1].Sheets["Sheet1"];
wsNew = (myExcel.Worksheet)excelApp.Workbooks[Book2].Sheets["Sheet1"];
wsDiff = (myExcel.Worksheet)excelApp.Workbooks["testReport.xlsx"].Sheets["Sheet1"];
}
catch (Exception e)
{
throw new Exception("Excel file does not contain properly formatted worksheets");
}
//Determine working area
int lr1 = 0;
int lr2 = 0;
int lc1 = 0;
int lc2 = 0;
{
lr1 = wsNew.UsedRange.Rows.Count;
lc1 = wsNew.UsedRange.Columns.Count;
}
{
lr2 = wsBase.UsedRange.Rows.Count;
lc2 = wsBase.UsedRange.Columns.Count;
}
maxR = lr1;
maxC = lc1;
if (maxR < lr2) maxR = lr2;
if (maxC < lc2) maxC = lc2;
//Copy new data from report into the standard Excel file
myExcel.Worksheet reportBook2MinusBook1;
reportBook2MinusBook1 = (myExcel.Worksheet)excelApp.Workbooks["testReport.xlsx"].Sheets["Sheet1"];
//reportBook2MinusBook.Name = "New";
reportBook2MinusBook1.UsedRange.Copy((myExcel.Range)wsNew.Cells[maxR, maxC]);
//Close new data report now that we're through with it
//excelApp.Workbooks["testReport.xlsx"].Close(false, false, false);
//===================================================
//Compare Cells
//===================================================
//decolorize and otherwise standardize visual format across worksheets
wsDiff.get_Range((myExcel.Range)wsDiff.Cells[1, 1], (myExcel.Range)wsDiff.Cells[maxR, maxC]).Interior.Pattern = myExcel.XlPattern.xlPatternNone;
wsBase.get_Range((myExcel.Range)wsBase.Cells[1, 1], (myExcel.Range)wsBase.Cells[maxR, maxC]).Interior.Pattern = myExcel.XlPattern.xlPatternNone;
wsNew.get_Range((myExcel.Range)wsNew.Cells[1, 1], (myExcel.Range)wsNew.Cells[maxR, maxC]).Interior.Pattern = myExcel.XlPattern.xlPatternNone;
for (row = 1; row <= maxR; row++)
{
for (col = 1; col <= maxC; col++)
{
//Get cell values
objNew = ((myExcel.Range)wsNew.Cells[row, col]).Value2;
objBase = ((myExcel.Range)wsBase.Cells[row, col]).Value2;
if (!equiv(objNew, objBase, tolerance))
{
wereDifferences = true;
//Mark differing cells
//MessageBox.Show("test 1");
((myExcel.Range)wsNew.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
((myExcel.Range)wsBase.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
if ((objNew == null))
{
//MessageBox.Show("test 2");
((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
}
else if (objNew.GetType().ToString() == "System.String")
{
//MessageBox.Show("test 3");
((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
}
else
{
//MessageBox.Show("test 4");
((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);
}
}
}
}
//Close reports now that we're through with them
excelApp.Workbooks["testReport.xlsx"].Save();
excelApp.Workbooks["testReport.xlsx"].Close(false, false, false);
return wereDifferences;
}
/// Determines whether two objects are equivalent
/// Numbers are equivalent within the specified tolerance
/// Strings are equivalent if they are identical
/// obj1 and obj2 are the two objects being compared
/// tolerance is the maximum difference between two numbers for them to be deemed equivalent
private bool equiv(object obj1, object obj2, double tolerance)
{
if ((obj1 == null) && (obj2 == null))
{
return true;
}
else if ((obj1 == null) || (obj2 == null))
{
return false;
}
//if both are numeric
if (IsNumeric(obj1))
{
if (IsNumeric(obj2))
{
if (Math.Abs(Convert.ToDouble(obj2) - Convert.ToDouble(obj1)) < tolerance)
{
return true; //If they are within tolerance
}
else
{
return false; //If they are outside tolerance
}
}
else
{
return false; //If only one is numeric
}
}
//Now assuming both are just random strings
else
{
if ((string)obj1 == (string)obj2)
{
return true;
}
else
{
return false;
}
}
}
// Test whether a given object represents a number
internal static bool IsNumeric(object ObjectToTest)
{
if (ObjectToTest == null)
{
return false;
}
else
{
double OutValue;
return double.TryParse(ObjectToTest.ToString().Trim(),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.CurrentCulture,
out OutValue);
}
}