2012-09-19 79 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,50.0
DEF,60.0
GHI,70.0

當循環使用for,abc的numberOfItems應爲2,def爲1,ghi爲1。 abc的總金額應爲100.0,def爲60.0,ghi爲70.0。 abc的順序應該是1,def的順序應該是2,ghi的順序應該是3。

我在運行for循環時注意到的第一件事是,它跳過第一個表中的一堆行,所以當我在else中創建第二個表時,numberOfItems和totalAmount仍然是0.第二個表應該是類似:

ABC,100,如圖2所示,1
DEF,60,1,2個
GHI,70,1,3

其中在CSV值的最後一個數字是序列和數目在此之前是每個帳戶的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-loop'呢? –

+0

@TimSchmelter - 我想過這個。我會怎麼做呢?你介意提供一個答案嗎? – Xaisoft

回答

0

A foreach行不知道它是前一行。那麼你爲什麼不簡單地使用for-loop

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"]) 
    { 
     // ... 
    } 
} 

現在你已經更新了你的問題,我會建議使用Linq-To-DataSet

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); 

請注意,您需要添加using System.Linq

+0

蒂姆,我遇到了這個問題。我會用一個例子更新我的帖子,並告訴你發生了什麼 – 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將爲空,因此您將其設置爲當前帳戶,然後在下一行中檢查當前帳戶==最後一個帳戶是否爲第一個帳戶。 –

+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是否爲空,這是不需要的,如果你把它初始化爲「」,就像我做的一樣,第11行存在拼寫錯誤,會導致編譯錯誤。 (在IF語句中額外的右括號) –

+0

也他的代碼有一個錯誤,會導致第一個帳戶被跳過(請參閱我對他的回答的評論) –

相關問題