2016-09-30 2 views
0

코딩 할 때 새로운 것으로 중복 행에 대한 스프레드 시트를 확인하려고합니다. 스프레드 시트에는 50 개의 열이 있고 두 개를 제외한 모든 열을 비교해야합니다. 행이 중복되면 행이 하나의 행으로 결합되고 열 REQNUM 및 AUTHNUM의 금액이 합산됩니다. 대부분의 샘플은 "필드 ("열 이름 ")를 사용합니다. 많은 양의 열 때문에 비교할 필요가없는 두 개를 제외시킨 변수를 사용하고 싶습니다.2 열을 제외한 여러 열이있는 데이터 테이블에서 중복 검색

예 :
이전. 점들은 더 많은 열을 나타냅니다.
COL1 | COL2 | COL3 | ... | REQNUM | AUTHNUM
: ----- : | | : ----- : | : ---- : | ... | : ---------- : | : ----------- : | ....
x | y | z | ... | 1 | 1
x | y | z | ... | 2 | COL2 | | COL3 | ... | REQNUM | 3


COL1 후 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(); 

켄에 도움을 주셔서 감사합니다. 이것은 내가 필요로하는 것에 아주 잘 맞았습니다. 중복을 하나의 행에 결합하고 숫자 필드를 추가 할 수 있도록 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(); 

또한 datarow compare와 키가 필요없는 변수를 만들기 위해 where 절을 사용했습니다. // 3을 제외한 모든 열이있는 변수를 만듭니다. 그것은 다음 질의에 사용되는 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. .Select (g => { var row = g.First())를 선택하십시오. 캐스트는 () 입니다 .GroupBy (x => String.Join ("", dtRow.Select (c => x [c] ; row.SetField ("REQSTR"(X => x.Field ("REQSTR")) g.Sum) row.SetField ("AUTHNUM"g.Sum (X => x.Field ("AUTHNUM"))); return 행; }). CopyToDataTable(); – fmrjrhd

답변

0

당신은 dtRow.Select(c => x[c])로 불과 그룹 데이터 그것이 IEnumerable이기 때문에, 그들은 동일한 콘텐츠를 가질 수 없습니다하지만 그들은 여전히 ​​IEnumerable 다릅니다.

string 경우, 수도 그룹 결합 된 문자열로 데이터 : 이것이 내가 생각 해낸하고 내가 필요한 것을 위해 큰 일을 무엇 켄에

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

감사합니다. Ken. 이것은 하나의 긴 문자열에서 행의 결과를 얻었지만 REQNUM 및 AUTHNUM 열은 여전히 ​​누락되었습니다. IEnumerable을 유지하기 위해 행이 필요하다고 생각하여 중복 행의 REQNUM 및 AUTHNUM 열을 합계 할 수 있습니다. 쿼리를 잘못 찾고 있습니까? 그룹화 기준은 열과 일치하는 행을 가져온 다음 그룹에 둘 이상의 행이있는 위치를 선택합니다. – fmrjrhd

+0

나는 당신이 무슨 뜻인지 모르겠다. 긴 문자열은'g.Key'가 문자열이되도록 그룹화 키로 만 사용해야합니다. 따라서 REQNUM과 AUTHNUM 열은 누락되어서는 안되며 질의 결과는 여전히 'IEnumerable'이다. –

+0

Ken에 답해 주셔서 감사합니다. 나는 당신이 언급 한 방식대로 groupby를 지키고 나의 선택을 변경하고 문제를 바로 잡았다. 내 원래의 질문에 새 코드가 있습니다. 도움에 다시 한번 감사드립니다. – fmrjrhd

관련 문제