2015-09-25 37 views
0

例如,我有一張名爲EmployeeSheet的工作表,它只是公司中每個員工姓名的第一個和最後一個單個列。假設這個列表格式完全格式化並且沒有重複項,因此每個單元格在此表單中都是唯一的。如何以編程方式在多個工作表中找到Excel單元格中的重複值

現在我在公司各部門的紙張,如FinanceSheetITSheetSalesSheet。每個表單都有一個位置(因爲每個表單中沒有相同的佈局)每個部門的員工列表。但是,任何1個員工名稱應該只在所有部門表單之間出現一次(這不包括EmployeeSheet)。

下面是我能想到的解決方案,但不知道如何實現,將是製作一個多維數組(在學校學習了一點,依稀記得如何使用)。

僞像:

arrEmployees = {"Tom Hanks", "Burt Reynolds", "Your Mom"} 
arrFinance = {"Tom Hanks"} 
arrIT = {"Burt Reynolds"} 
arrSales = {"Your Mom"} 
arrSheets = {arrEmployees, arrFinance, arrIT, arrSales} 

雖然我已經能夠通過使用

Sheets shts = app.Worksheets; 
Worksheet ws = (Worksheet)sheets.get_Item("EmployeeSheet"); 
Excel.Range empRange = (Excel.Range)worksheet.get_range("B2"); 
string empVal = empRange.Value2.ToString(); 

但與該進程得到單細胞值和範圍爲字符串獲得一個單元格的值一個字符串,我不知道如何將它放到我的數組元素中,更不用說一系列的值。

我敢肯定我的方法不是最有效率的,甚至不可能,但這就是爲什麼我在這裏尋求幫助,所以任何提示都表示讚賞。


編輯:這是最終爲我工作的解決方案。感謝Ian Edwards解決方案。

Dictionary<string, List<Point>> fields = new Dictionary<string, List<Point>>(); 
fields["Finance"] = new List<Point>() { new Point(2,20)}; 
fields["Sales"] = new List<Point>(); 
for (int row = 5; row <= 185; row += 20) {fields["Sales"].Add(new Point(2,row));} 

List<string> names = new List<string>(); 
List<string> duplicates = new List<string>(); 
foreach (KeyValuePair<string, List<Point>> kp in fields) 
{ 
    Excel.Worksheet xlSheet = (Excel.Worksheet)workbook.Worksheets[kp.Key]; 
    foreach (Point p in kp.Value) 
    { 
    if ((xlSheet.Cells[p.Y, p.X] as Excel.Range.Value != null) 
    { 
     string cellVal = ((xlSheet.Cells[p.Y,p.X] as Excel.Range).Value).ToString(); 
     if (!names.Contains(cellVal)) 
     { names.Add(cellVal)) } 
     else { duplicates.Add(cellVal); } } } } 

回答

1

這裏有一個我敲在一起的小例子 - 評論應該解釋一行一行的內容。

您可以聲明要檢查名稱的工作表名稱,以及從「工作表」字典中開始查找名稱的位置。

我假設你不知道每個列表中有多少個名字 - 它將繼續向下列出每個列表直到它遇到一個空白單元格。

 // Load the Excel app 
     Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
     // Open the workbook 
     var xlWorkbook = xlApp.Workbooks.Open("XLTEST.xlsx"); 

     // Delcare the sheets and locations to look for names 
     Dictionary<string, Tuple<int, int>> worksheets = new Dictionary<string, Tuple<int, int>>() 
     { 
      // Declare the name of the sheets to look in and the 1 base X,Y index of where to start looking for names on each sheet (i.e. 1,1, = A1) 
      { "Sheet1", new Tuple<int, int>(1, 1) }, 
      { "Sheet2", new Tuple<int, int>(2, 3) }, 
      { "Sheet3", new Tuple<int, int>(4, 5) }, 
      { "Sheet4", new Tuple<int, int>(2, 3) }, 
     }; 

     // List to keep track of all names in all sheets 
     List<string> names = new List<string>(); 
     // Iterate over every sheet we need to look at 
     foreach(var worksheet in worksheets) 
     { 
      string workSheetName = worksheet.Key; 
      // Get this excel worksheet object 
      var xlWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkbook.Worksheets[workSheetName]; 
      // Get the 1 based X,Y cell index 
      int row = worksheet.Value.Item1; 
      int column = worksheet.Value.Item2; 
      // Get the string contained in this cell 
      string name = (string)(xlWorksheet.Cells[row, column] as Microsoft.Office.Interop.Excel.Range).Value; 
      // name is null when the cell is empty - stop looking in this sheet and move on to the next one 
      while(name != null) 
      { 
       // Add the current name to the list 
       names.Add(name); 
       // Get the next name in the cell below this one 
       name = (string)(xlWorksheet.Cells[++row, column] as Microsoft.Office.Interop.Excel.Range).Value; 
      } 
     } 
     // Compare the number of names to the number of unique names 
     if (names.Count() != names.Distinct().Count()) 
     { 
      // You have duplicate names! 
     } 
+0

我有一個工作表,我想檢查一列和任何重複只出現在那一列中? – Si8

1
  1. 可以使用.Range定義多個細胞(即,.Range["A1", "F500"]

https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.range.aspx

  • 然後可以使用.get_Value得到該範圍內所有單元格的內容/值。根據dotnetperls.com get_Value() is much faster than get_Range()(見'性能'部分)。使用多個範圍組合+ get_value將肯定使用get_range執行更多的單個範圍調用。
  • https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.get_value(v=vs.120).aspx

    我把它們存儲在一個Object Array

    (object[,])yourexcelRange.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault); 
    

    從那裏你可以編寫你自己的比較方法來比較多個數組。一個怪癖是,這樣做會返回1索引數組,而不是標準的基於0的索引。

    +0

    感謝您的提示 – ChrisPBacon

    相關問題