2016-09-30 34 views
0

我是編碼方面的新手,並試圖檢查電子表格中的重複行。電子表格有50列,除了兩列外,每列都必須進行比較。如果行重複,它將把它們合併成一行,REQNUM和AUTHNUM列中的數量將被合計。我發現的大多數樣本都使用「Field」(「列名稱」)。由於大量的列,我想使用排除兩個我不需要比較的變量。在數據表中查找除了兩個以外的多列數據副本

例如:
之前。點表示更多列
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
:-----:| :-----:| :----:| ... | :----------:| :-----------:| ....
x | y | z | ... | 1 | 1
x | y | z | ... | 2 | 3


COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
------- | ------ | ------ | ... | ------------ | ------------ | ....
x | y | z | ... | 3 | 4

這是我的代碼,它看起來很接近但不完全正確。我期待重複行的結果,所以後來我可以通過一個foreach來運行它,它將總結和刪除多餘的行。 dtrow讓我得到我想要的列(感謝Linq Excluding a column)。當我嘗試在我的查詢中使用這個變量時,我沒有得到任何結果,如果我刪除了「g.Count()> 1」,我得到所有與他們缺少兩列的行。我想保留結果中的所有兩列,而不必在稍後添加它們。

 var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList(); 

     var checkExcel = dtExcel.Rows.Cast<DataRow>() 
      .GroupBy(x => dtRow.Select(c => x[c])) 
      .Where(g => g.Count() > 1) 
      .Select(gr => gr); 
     //.CopyToDataTable(); 

感謝Ken的幫助。這對我所需要的很好。我使用了groupby子句,因此我可以將副本組合成一行並添加數字字段。也通過創建一個我在IF語句中使用的密鑰進行分組。

 var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList(); 

     var excelDup = dtExcel.Rows.Cast<DataRow>() 
      .GroupBy(x => String.Join("", dtRow.Select(c => x[c]))) 
      .Select(g => 
      { 
       var row = g.First(); 
       row.SetField("REQNUM", g.Sum(x => x.Field<double>("REQNUM"))); 
       row.SetField("AUTHNUM", g.Sum(x => x.Field<double>("AUTHNUM"))); 
       return row; 
      }) 
      .CopyToDataTable(); 

我還使用了where子句來爲datarow比較創建一個變量,並且不需要任何密鑰。 //創建除三個以外的所有列的變量。它在接下來的查詢中使用 VAR dtExcelRow = dtExcel.Columns .Cast()。將(C => c.ColumnName!= 「TITLE」 & & c.ColumnName!= 「REQSTR」 & & c.ColumnName!=「 AUTHSTR「)ToList(); VAR dtListRow = dtList.Columns .Cast()。將(C => c.ColumnName!= 「TITLE」 & & c.ColumnName!= 「REQSTR」 & & c.ColumnName!= 「AUTHSTR」)。ToList( );

  // Querys create datarow list for compare 
      IEnumerable<DataRow> eRow = dtExcel.AsEnumerable() 
       .Where(w => dtExcelRow.Select(c => w[c]).Any()) 
       .Select(x => x); 
      IEnumerable<DataRow> lRow = dtList.AsEnumerable() 
       .Where(w => dtListRow.Select(c => w[c]).Any()) 
       .Select(x => x); 

      // 1st compare gets list of new records that have changes or are new. 2nd is list of old records being change. 
      var newRecords = eRow.AsEnumerable().Except(lRow.AsEnumerable(), DataRowComparer.Default); 
      var oldRecords = lRow.AsEnumerable().Except(eRow.AsEnumerable(), DataRowComparer.Default); 
+0

由於肯這是我想出了它,因爲我需要什麼樣的工作的偉大。 – fmrjrhd

+0

var dtRow = dtExcel.Columns.Cast ().Where(c => c.ColumnName!=「REQNUM」&& c.ColumnName!=「AUTHNUM」)。ToList(); var excelDup = dtExcel.Rows。Cast()() .GroupBy(x => String.Join(「」,dtRow.Select(c => x [c]))) 。Select(g => var row = g.First() ; row.SetField(「REQSTR」,g.Sum(x => x.Field (「REQSTR」))); row.SetField(「AUTHNUM」,g.Sum(x => x.Field ( 「AUTHNUM」))); return row; })。CopyToDataTable(); – fmrjrhd

回答

0

你不能僅僅通過組的dtRow.Select(c => x[c])數據,因爲它是一個IEnumerable,他們可能有相同的內容,但他們仍然是不同的IEnumerable

如果他們string,你可以組數據被加入字符串:

x => String.Join("", dtRow.Select(c => x[c])) 
+0

謝謝肯。這讓我得到了一個長字符串中的行的結果,仍然缺少列REQNUM和AUTHNUM。我想我需要行保持一個IEnumerable,所以我可以總結重複行的列REQNUM和AUTHNUM。我正在查看錯誤的查詢嗎?分組依據獲取與列匹配的行,然後選擇組有多於一行的位置。 – fmrjrhd

+0

我不確定你的意思。長字符串應該僅用作分組鍵,例如'g.Key'是一個字符串。所以列REQNUM和AUTHNUM不應該丟失,查詢結果仍然是'IEnumerable'。 –

+0

感謝您回覆肯。我按照你提到的方式保留了這個組,並且改變了我的選擇並糾正了這個問題。我有我的原始問題的新代碼。再次感謝您的幫助。 – fmrjrhd

相關問題