Reputation: 46651
I have the following code:
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++
}
}
My initial table may contain the data:
abc, 50.0
abc, 50.0
def, 60.0
ghi, 70.0
When looping through using for, the numberOfItems for abc should = 2, 1 for def, and 1 for ghi. The totalAmount for abc should be 100.0, 60.0 for def and 70.0 for ghi. The sequence should be 1 for abc, 2 for def, and 3 for ghi.
First thing I noticed when running the for loop is that it is skipping a bunch of rows in the first table, so when I create a second table in the else, numberOfItems and totalAmount are still 0. The second table should be something like:
abc, 100, 2, 1
def, 60, 1, 2
ghi, 70, 1, 3
where the last number in the csv values is the sequence and the number right before that is the numberOfItems per account.
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++;
}
}
Upvotes: 0
Views: 11084
Reputation: 460258
A foreach
row doesn't know it's previous row. So why don't you simply use a 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"])
{
// ...
}
}
Now that you have updated your question i would suggest to use 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);
Note that you need to add using System.Linq
.
Upvotes: 0
Reputation: 76988
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"];
}
Note that I've put a ; after the incrementation of sequence.
Upvotes: 0
Reputation: 1425
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"];
}
Upvotes: 0
Reputation: 29000
You can use DataTable.GetChanges
Link : http://msdn.microsoft.com/en-us/library/k2552649.aspx
var changeTable = table.GetChanges();
foreach(var item in changeTable.Rows)
{
.....
}
For modified rows you can use argument DataRowState.Modified
table.GetChanges(DataRowState.Modified);
Upvotes: 1