我想在excel中将2000个数据单元与3000个其他数据单元进行比较,但这需要很长时间

时间:2015-06-09 15:35:24

标签: c# excel

我有两行数据,我希望相互比较以查找重复项。当我运行我的程序时,完成此任务将花费数小时,而Excel需要几秒钟。但我不想在Excel中这样做,因为我想自动完成它。行A = 2000长,行B = 3000数据长。

这是我做的:

static void Main(string[] args) 
        {
   excel_init("C:\\blablatest");
            for (int j = 1; j < 2000; j++)
            {
                for (int k = 1; k < 2000; k++)
                {
                    if (excel_getValue("A"+j) == excel_getValue("B"+k))
                    {
                        excel_setValue("D"+j,"1");
                    }
                    Console.WriteLine(j);
                  //**STILL LOOP TAKES HOURS**
                }
            }
            excel_close();
            Console.ReadKey();

     }
        private static Microsoft.Office.Interop.Excel.ApplicationClass appExcel;
        private static Workbook newWorkbook = null;
        private static _Worksheet objsheet = null;

    //Method to initialize opening Excel
    static void excel_init(String path)
    {
        appExcel = new Microsoft.Office.Interop.Excel.ApplicationClass();

        if (System.IO.File.Exists(path))
        {
            // then go and load this into excel
            newWorkbook = appExcel.Workbooks.Open(path, true, true);
            objsheet = (_Worksheet)appExcel.ActiveWorkbook.ActiveSheet;
        }
        else
        {
            Console.WriteLine("Unable to open file!");
            System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel);
            appExcel = null;
        }

    }
    static void excel_setValue(string cellname, string value)
    {
            objsheet.get_Range(cellname).set_Value(Type.Missing, value);
    }

    //Method to get value; cellname is A1,A2, or B1,B2 etc...in excel.
    static string excel_getValue(string cellname)
    {
        string value = string.Empty;
        try
        {
            value = objsheet.get_Range(cellname).get_Value().ToString();
        }
        catch
        {
            value = "";
        }

        return value;
    }

    //Method to close excel connection
    static void excel_close()
    {
        if (appExcel != null)
        {
            try
            {
                newWorkbook.Close();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel);
                appExcel = null;
                objsheet = null;
            }
            catch (Exception ex)
            {
                appExcel = null;
                Console.WriteLine("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }
    }
}

(怎么样)我可以加快这个???

2 个答案:

答案 0 :(得分:2)

通过在Excel内进行比较,您付出了巨大的开销。您应该做的是提取数据并直接在您的应用程序中进行比较。

最简单的方法是将Excel范围转换为数组:

var rowAArray = objsheet.Range["A1","A2000"].Value; //object[,] typed array
var rowBArray = objsheet.Range["B1", "B2000"].Value; //object[,] typed array

现在你只需要比较两个阵列:

 for (int j = 1; j < 2000; j++)
 {
      for (int k = 1; k < 2000; k++)
      {
           if (rowBArray[k, 1] == rowAArray[j, 1])
               objsheet.Cells[j, 4].Value = 1; //Set value in cell "D*"
      }
  }

如果你正在处理数值,你将不得不忍受装箱/拆箱惩罚,但它仍然比使用Excel执行比较要快得多。

尚未测试代码,但它应该可以工作。

答案 1 :(得分:1)

尽管InBetween可以很好地解决您的问题,并且在消除巨额开销方面会更快,但我必须补充一点,您不需要比较所有2000 * 3000条目以查找重复值,因为您有两个排序列表。类似的工作可以找到here

让我们将您的两个列表,即A和B(列号)排序到E和G. F怎么样?存储A的原始行号,为E.例如,如果是字符串&#34; aabbb&#34;在A384,现在是E1,在F1存储384。然后将两个列表作为上面的链接进行比较,例如,如果您在E644上有重复项,请将单元格标记为&#34; D&#34; +(F644的值)为1。

最初你进行了O(AB)比较,通过这样做,你有O(AlogA + BlogB)进行排序。 (比较只需要O(max(A,B))。)

注意:在我看来,实现这一点并不容易,也没有错误。我建议先试试InBetween的答案。考虑在我的建议仍然缓慢的情况下应用我的建议。