2012-09-19 3 views
0

나는 다음과 같은 코드가 있습니다foreach를 사용할 때 DataTable 행이 변경되었는지 확인하는 방법은 무엇입니까?

int sequence = 1; //This is incremented every time the Account changes 
int numberOfItems; //This is reset after the Account changes 
decimal totalAmount = 0m; //This is reset after the Account changes 
string prevRow; //not sure how to handle this 

foreach(DataRow row in dt.Rows) 
{ 
    //I am stuck here 
    if(row["Account"]) == prevRow) 
    { 
    numberOfItems++; 
    totalAmount += Convert.ToDecimal(row["TotalAmount"]); 
    } 
    else 
    { 
    //reset everything and increase sequence 
    numberOfItems = 0; 
    totalAmount = 0m; 
    sequence++ 
    } 

} 

내 초기 테이블 데이터가 포함될 수 있습니다

ABC를, 50.0
ABC, DEF 50.0
, 60.0
GHI를, 70.0

for를 사용하여 반복하면서 abc의 numberOfItems는 2, 1은 def, 1은 ghi에 대해 사용해야합니다. abc의 totalAmount는 def의 경우 100.0, def의 경우 60.0, ghi의 경우 70.0이어야합니다. 순서는 abc의 경우 1, def의 경우 2, ghi의 경우 3입니다.

for 루프를 실행할 때주의해야 할 점은 첫 번째 테이블에서 여러 행을 건너 뛰고 있다는 것입니다. 따라서 else에 두 번째 테이블을 만들 때 numberOfItems 및 totalAmount는 여전히 0입니다. 두 번째 테이블은 어떤 같은

ABC, 100, 2, DEF 1
, 60, 1, 2
GHI, 70 (1), CSV 값의 마지막 숫자는 순서와 개수 3

바로 전에 계정 당 numberOfItems입니다.

for (int i = 0; i < dt.Rows.Count; i++) 
      { 
       DataRow row = dt.Rows[i]; 
       DataRow prevRow = i > 0 ? dt.Rows[i - 1] : null; 

       if (prevRow != null && row[1] == prevRow[1]) 
       { 
        numberOfItems++; 
        totalAmount += Convert.ToDecimal(row[2]); 
        row[3] = "D"; 
        row[4] = c; 
        row[5] = sequence; 

       } 
       else 
       { 
        dt2.Rows.Add("N", 
         c, 
         row[1], 
         row[2], 
         row[3], 
         numberOfItems, 
         totalAmount, 
         sequence); 

        numberOfItems = 0; 
        totalAmount = 0m; 
        sequence++; 
       } 
      } 
+0

'foreach'는 이전 행을 알지 못합니다. 그렇다면 단순히 for 루프를 사용하지 않는 것이 어떻습니까? –

+0

@TimSchmelter - 그것에 대해 생각했습니다. 어떻게 그걸 할 수 있니? 답변을 제공해 주시겠습니까? – Xaisoft

답변

0

foreach 행은 이전 행을 알지 못합니다. 그렇다면 단순히 for-loop을 사용하지 않으시겠습니까? 당신이 using System.Linq을 추가 할 필요가

var groups = dt.AsEnumerable() 
    .GroupBy(r => r.Field<String>("Account")) 
    .Select((g, i) => new { 
     Account = g.Key, 
     TotalAmount = g.Sum(r => r.Field<double>("TotalAmount")), 
     Count = g.Count(), 
     Id = i + 1, 
    }); 

foreach (var grp in groups) 
    Console.WriteLine("{0},{1},{2},{3}" 
     ,grp.Account, grp.TotalAmount, grp.Count, grp.Id); 

참고 : 이제 내가 Linq-To-DataSet를 사용하는 제안 질문을 업데이트 한 것을

for(int i = 0; i < dt.Rows.Count; i++) 
{ 
    DataRow row = dt.Rows[ i ]; 
    DataRow prevRow = i > 0 ? dt.Rows[ i - 1 ] : null; 

    if(prevRow != null && row["Account"] == prevRow["Account"]) 
    { 
     // ... 
    } 
} 

.

+0

Tim, 저는 이것에 대해 몇 가지 문제를 겪고 있습니다. 예를 통해 내 게시물을 업데이트하고 무슨 일이 일어나는지 알려 드리겠습니다. – Xaisoft

+0

자세한 내용은 게시물을 업데이트하십시오. – Xaisoft

+0

@Xaisoft : 내 대답을 편집했습니다. –

1

당신은 사용할 수 있습니다 DataTable.GetChanges

링크 : http://msdn.microsoft.com/en-us/library/k2552649.aspx

var changeTable = table.GetChanges(); 
foreach(var item in changeTable.Rows) 
{ 
..... 

} 

수정 된 행의 경우 사용할 수있는 인수 DataRowState.Modified

table.GetChanges(DataRowState.Modified); 
+0

위의 코드 예제가 있습니까? 특정 행 변경을 확인할 수 있습니까? – Xaisoft

+0

그는 _changes_를 얻고 싶지 않습니다.이 행의 필드가 이전 행의 필드와 같은지 알고 싶습니다. –

+0

@TimSchmelter - 맞습니다. – Xaisoft

0
int sequence = 1; //This is incremented every time the Account changes 
int numberOfItems; //This is reset after the Account changes 
decimal totalAmount = 0m; //This is reset after the Account changes 
string prevRow = null; //not sure how to handle this 

foreach(DataRow row in dt.Rows) 
{ 
    //I am stuck here 
    if((row["Account"]) == prevRow) 
    { 
    numberOfItems++; 
    totalAmount += Convert.ToDecimal(row["TotalAmount"]); 
    } 
    else 
    { 
    //reset everything and increase sequence 
    numberOfItems = 0; 
    totalAmount = 0m; 
    sequence++; 
    } 
    prevRow = row["Account"]; 

} 

나는 다음을 넣었다. 시퀀스의 증가 후에

+0

첫 번째 계정에서는 코드가 실패합니다.첫 번째 실행시 prevRow는 null이되므로 현재 계정으로 설정 한 후 다음 계좌에서 현재 계좌 == 마지막 계좌인지 확인합니다. 이는 항상 첫 번째 계좌에 대해 수행됩니다. –

+0

또한 IF 문에 추가 닫는 괄호가 있습니다 (원본 코드에서 복사 됨) –

+0

감사합니다. 내 대답을 편집했습니다. –

0
int sequence = 1; //This is incremented every time the Account changes 
int numberOfItems; //This is reset after the Account changes 
decimal totalAmount = 0m; //This is reset after the Account changes 
String prevAccount == ""; //not sure how to handle this 

foreach(DataRow row in dt.Rows) 
{ 
    //I am stuck here 
    if(row["Account"] == prevAccount) 
    { 
     numberOfItems++; 
     totalAmount += Convert.ToDecimal(row["TotalAmount"]); 
    } 
    else 
    { 
     //reset everything and increase sequence 
     numberOfItems = 0; 
     totalAmount = 0m; 
     sequence++; 
    } 
    prevAccount = row["Account"]; 
} 
+0

구현과 Lajos의 구현의 차이점은 무엇입니까? – Xaisoft

+0

처음에는 그의 접근 방식을 보지 못했지만, 두 가지 차이점이 있습니다 - prevRow가 null인지 확인하기위한 추가 검사가 있습니다. 이전에 ""초기화 한 경우 필요하지 않습니다. 11 번 줄에 오타가있어 컴파일 오류가 발생합니다. (IF 문에 추가로 닫는 괄호) –

+0

또한 그의 코드는 첫 번째 계정을 건너 뛸 수있는 버그가 있습니다. (내 대답은 그의 답변을 참조하십시오.) –

관련 문제