2011-02-24 63 views
0

所有我想要做的是打开2 Excel文件(Sheet1),具有相同的确切结构,但可能有不同的数值,通读它们并创建第三个文件与“新”减“基地”。如果这两个值都相同,则无论是显示0还是0.00或完全不显示都无关紧要。新( - )BASE =结果Excel电子表格

例:新建文件

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 

有没有人对如何做到这一点的想法?或者我可以找到类似的参考资料?谢谢。

我得到了一个由同事创建的代码,其中他做了一些非常相似的事情。我试图addapt他的代码,结果至今:

库文件:只要有一个数值显示为红色

新文件:只要有一个数值显示为红色

最终的文件:空,但相同的单元格用红色和黄色着色。

我希望有一个更清洁的方式来做到这一点,以下代码的任何recomendations?

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); 
     } 
    } 
+2

有多远,你在你的代码得到?你能打开一个excel并引用这些值吗?尝试发布一些代码,以便我们可以看到你在哪里。 – jlafay 2011-02-24 22:21:11

+1

你似乎要求一个起点,但你似乎也有代码,你说的是正确的事情,你只需要修改。你在哪里遇到适应这些代码的问题? – Chris 2011-02-25 16:06:36

回答

0

想通了:

public bool createReport_NewMinusBase(string currentWorkingDirectory, string Book1, string Book2, double tolerance) 
{ 
    tolerance = 0.0001; 
    myExcel.Application excelApp = new myExcel.Application(); // Creates a new Excel Application 
    excelApp.Visible = false; // Makes Excel visible to the user. 
    excelApp.Application.DisplayAlerts = false; 

    //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 
    //xlApp.Workbooks.Open(reportFolder + reportName, 0, false, 5, "", "", false, myExcel.XlPlatform.xlWindows, "", true, false, 0, true, false, 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.Workbook excelWorkbook3 = excelApp.Application.Workbooks.Add(myExcel.XlWBATemplate.xlWBATWorksheet); 

    myExcel.Worksheet wsBase; 
    myExcel.Worksheet wsDiff; 
    myExcel.Worksheet wsNew; 


    try 
    { 
     wsBase = (myExcel.Worksheet)excelApp.Workbooks[Book1].Sheets["Sheet1"]; 
     wsNew = (myExcel.Worksheet)excelApp.Workbooks[Book2].Sheets["Sheet1"]; 
     wsDiff = (myExcel.Worksheet)excelWorkbook3.Worksheets.get_Item(1); 
    } 
    catch 
    { 
     throw new Exception("Excel file does not contain properly formatted worksheets"); 

    } 


    //Copy Sheet from Excel Book "NEW" to "NEW(-)BASE" 
    myExcel.Worksheet source_sheet; 
    source_sheet = (myExcel.Worksheet)excelApp.Workbooks[Book2].Sheets["Sheet1"]; 
    source_sheet.UsedRange.Copy(); 
    wsDiff.Paste(); 




    //Determine working area 
    int row = 0; 
    int col = 0; 
    int maxR = 0; 
    int maxC = 0; 

    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; 

    //=================================================== 
    //Compare Cells 
    //=================================================== 

    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 they are not equivilante 
      if (!equiv(objNew, objBase, tolerance)) 
      { 
       wereDifferences = true; 

       //Mark differing cells 
       ((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)) 
       {        
        ((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red); 
       } 
       else if (objNew.GetType().ToString() == "System.String") 
       { 
        ((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red); 
       } 
       else 
       { 
        ((myExcel.Range)wsDiff.Cells[row, col]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow); 
        ((myExcel.Range)wsDiff.Cells[row, col]).Value2 = ((myExcel.Range)wsNew.Cells[row, col]).Value2 - ((myExcel.Range)wsBase.Cells[row, col]).Value2; 
       } 
      } 
      else //They are equivalent 
      {       
       if ((objNew == null)) 
       { 
       } 
       else if (objNew.GetType().ToString() == "System.String") 
       { 
       } 
       else 
       {        
        ((myExcel.Range)wsDiff.Cells[row, col]).Value2 = ((myExcel.Range)wsNew.Cells[row, col]).Value2 - ((myExcel.Range)wsBase.Cells[row, col]).Value2; 
       } 
      } 
     } 
    } 


    // Copy formatting 
    myExcel.Range range1 = wsBase.get_Range((myExcel.Range)wsBase.Cells[1, 1], (myExcel.Range)wsBase.Cells[maxR, maxC]); 
    myExcel.Range range2 = wsDiff.get_Range((myExcel.Range)wsDiff.Cells[1, 1], (myExcel.Range)wsDiff.Cells[maxR, maxC]); 
    range1.Copy(); 
    range2.PasteSpecial(myExcel.XlPasteType.xlPasteColumnWidths); 

    excelApp.Workbooks[Book1].Close(false, false, false); 
    excelApp.Workbooks[Book2].Close(false, false, false); 

    string Book3 = "reporttestpc.xlsx"; //"reportBaseMinusNew.xlsx" 
    if (File.Exists(currentWorkingDirectory + Book3)) 
    { 
     File.Delete(currentWorkingDirectory + Book3); 
    } 

    excelWorkbook3.SaveAs(currentWorkingDirectory + Book3, Type.Missing, Type.Missing, 
         Type.Missing, false, false, myExcel.XlSaveAsAccessMode.xlNoChange, 
         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

    //excelApp.Workbooks[Book3].Close(false, false, false); 

    excelApp.Visible = true; 
    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); 
    } 
} 
///