I'm having some trouble calculating the sum of all previous rows in a column in a data structure like DataTable
For example, we have a table with columns "Waiting Time" and "Burst Time".
Waiting Time's row values must be calculated by taking the values from previous rows in the Burst Time column(if there are such a.k.a its not the first row that we are calculating values for currently)
How can I achieve that? Is it as simple as using Compute() and passing an appropriate filter string?
EDIT: An example of what I want to do.
I have made an example. Have now idea how you populate DataTable, that is why I came up with hardcoded one.
public class Program
{
public static void Main(string[] args)
{
dataSet = new DataSet();
var dataTable = MakeTable();
var columns = dataTable.Columns;
Console.WriteLine("Defined Table");
PrintDataTable(dataTable);
foreach (DataRow dataTableRow in dataTable.Rows)
{
var id = dataTableRow["ID"];
var burstTime = dataTable.Compute("Sum(BurstTime)", $"ID < {id}");
dataTableRow["WaitingTime"] = burstTime;
}
Console.WriteLine();
Console.WriteLine("Table After Operation");
PrintDataTable(dataTable);
Console.ReadLine();
}
private static void PrintDataTable(DataTable dataTable)
{
foreach (DataRow dataTableRow in dataTable.Rows)
{
Console.WriteLine($"{dataTableRow["Id"]}\t\t| {dataTableRow["WaitingTime"]}\t\t| {dataTableRow["BurstTime"]}");
}
}
private static DataSet dataSet;
private static DataTable MakeTable()
{
// Create a new DataTable.
DataTable table = new DataTable("childTable");
DataColumn column;
DataRow row;
// Create first column and add to the DataTable.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "ID";
column.AutoIncrement = true;
column.Caption = "ID";
column.ReadOnly = true;
column.Unique = true;
// Add the column to the DataColumnCollection.
table.Columns.Add(column);
// Create second column.
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "ChildItem";
column.AutoIncrement = false;
column.Caption = "ChildItem";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
// Create third column.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "ParentID";
column.AutoIncrement = false;
column.Caption = "ParentID";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
// Create third column.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "WaitingTime";
column.AutoIncrement = false;
column.Caption = "WaitingTime";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
// Create fourth column.
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "BurstTime";
column.AutoIncrement = false;
column.Caption = "BursTime";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
dataSet.Tables.Add(table);
// Create three sets of DataRow objects,
// five rows each, and add to DataTable.
for (int i = 0; i <= 4; i++)
{
row = table.NewRow();
row["ID"] = i;
row["ChildItem"] = "Item " + i;
row["ParentID"] = 0;
row["WaitingTime"] = 0;
row["BurstTime"] = i;
table.Rows.Add(row);
}
for (int i = 0; i <= 4; i++)
{
row = table.NewRow();
row["ID"] = i + 5;
row["ChildItem"] = "Item " + i;
row["ParentID"] = 1;
row["WaitingTime"] = 0;
row["BurstTime"] = i + 5;
table.Rows.Add(row);
}
for (int i = 0; i <= 4; i++)
{
row = table.NewRow();
row["ID"] = i + 10;
row["ChildItem"] = "Item " + i;
row["ParentID"] = 2;
row["WaitingTime"] = 0;
row["BurstTime"] = i + 10;
table.Rows.Add(row);
}
return table;
}
}
The most interesting for you, I suppose:
foreach (DataRow dataTableRow in dataTable.Rows)
{
var id = dataTableRow["ID"];
var burstTime = dataTable.Compute("Sum(BurstTime)", $"ID < {id}");
dataTableRow["WaitingTime"] = burstTime;
}
The most important here, I think, is that you have to come up with your own comparison logic, i.e. the second parameter in Compute(string, string) function.
Related
Column does not belong to data table in the foreach loop iteration in C#.
I am inserting row by row records to a data table, however facing column does not belong to data table.
//Prepare Datatable and Add All Columns Here
DataTable dt = new DataTable();
DataRow row;
DataColumn dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "title";
dc.ReadOnly = false;
dc.Unique = true;
dc.AutoIncrement = false;
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "link";
dc.ReadOnly = false;
dc.Unique = true;
dc.AutoIncrement = false;
foreach (XmlNode rssNode in rssNodes)
{
XmlNode rssSubNode = rssNode.SelectSingleNode("title");
string title = rssSubNode != null ? rssSubNode.InnerText : "";
rssSubNode = rssNode.SelectSingleNode("link");
string link = rssSubNode != null ? rssSubNode.InnerText : "";
//Add new row and assign values to columns, no need to add columns again and again in loop which will throw exception
row = dt.NewRow();
//Map all the values in the columns
row["title"] = title;
row["link"] = link;
//At the end just add that row in datatable
dt.Rows.Add(row);
}
Before setting each column, you need to call dc = new DataColumn(); which you do for the first column but not the second. And after setting all the parameters of the column, you need to add it to the table dt.Columns.Add(dc);.
DataColumn dc;
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "title";
dc.ReadOnly = false;
dc.Unique = true;
dc.AutoIncrement = false;
dt.Columns.Add(dc);
dc = new DataColumn();
dc.DataType = System.Type.GetType("System.String");
dc.ColumnName = "link";
dc.ReadOnly = false;
dc.Unique = true;
dc.AutoIncrement = false;
dt.Columns.Add(dc);
I'm looking for a simple way to read a row from a data table. I'm sure this has been answered somewhere but for the life of me i cant find it.
my code is as follows:
static void Main(string[] args)
{
DataTable table1 = new DataTable("myTable");
DataColumn column;
DataRow row;
table1.PrimaryKey = new DataColumn[] { table1.Columns["idnum"] };
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.AutoIncrement = false;
column.ColumnName = "name";
column.ReadOnly = true;
column.Unique = false;
table1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.AutoIncrement = false;
column.ColumnName = "type";
column.ReadOnly = true;
column.Unique = false;
table1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.AutoIncrement = false;
column.ColumnName = "atk";
column.ReadOnly = true;
column.Unique = false;
table1.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.AutoIncrement = false;
column.ColumnName = "spd";
column.ReadOnly = true;
column.Unique = false;
table1.Columns.Add(column);
row = table1.NewRow();
row["name"] = "long sword";
row["type"] = "weapon";
row["atk"] = 7;
row["spd"] = 4;
table1.Rows.Add(row);
row = table1.NewRow();
row["name"] = "short sword";
row["type"] = "weapon";
row["atk"] = 5;
row["spd"] = 5;
table1.Rows.Add(row);
row = table1.NewRow();
row["name"] = "dagger";
row["type"] = "weapon";
row["atk"] = 3;
row["spd"] = 8;
table1.Rows.Add(row);
foreach(DataRow rowly in table1.Rows)
{
//what goes here?
}
Console.ReadKey();
}
what do i write to see the data in the row?
You can print those values by using the following code:
int rowIndex=0;
StringBuilder rowValueBuilder = new StringBuilder();
foreach (DataRow rowly in table1.Rows)
{
rowValueBuilder.AppendFormat("Row {0} Values \n", rowIndex++);
rowValueBuilder.AppendFormat("Name : {0} \n", rowly["name"]);
rowValueBuilder.AppendFormat("Type : {0} \n", rowly["type"]);
rowValueBuilder.AppendFormat("Atk : {0} \n", rowly["atk"].ToString());
rowValueBuilder.AppendFormat("Spd : {0} \n", rowly["spd"].ToString());
}
Console.WriteLine(rowValueBuilder.ToString());
How can I create a DataTable programatically? i have the following code and I was wanting to create a data table just like in Java that would allow me to create a table that I could file with data from a CSV (,) such as names, address, and phone numbers.
Code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private System.Data.DataSet dataSet;
System.Data.DataTable table = new DataTable("ParentTable");
public Form1()
{
InitializeComponent();
}
private void MakeParentTable()
{
DataColumn column;
DataRow row;
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
column.ReadOnly = true;
column.Unique = true;
table.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "ParentItem";
column.AutoIncrement = false;
column.Caption = "ParentItem";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
DataColumn[] PrimaryKeyColumns = new DataColumn[1];
PrimaryKeyColumns[0] = table.Columns["id"];
table.PrimaryKey = PrimaryKeyColumns;
dataSet = new DataSet();
dataSet.Tables.Add(table);
for (int i = 0; i<= 2; i++)
{
row = table.NewRow();
row["id"] = i;
row["ParentItem"] = "ParentItem " + i;
table.Rows.Add(row);
}
}
private void Form1_Load(object sender, EventArgs e)
{
MakeParentTable();
}
}
}
Use FileStream and StreamReader for reading data from csv file. I see that you create DataTable programmaticaly in your code.
I have a datagridview in which there are three columns .actually this is a dataprocessing application thats why i want use of keyboard(minimal use of mouse)
the code is as follows
[code languge="csharp"]
private void Form2_Load(object sender, EventArgs e)
{
DataTable odt = new DataTable();
DataColumn odc = new DataColumn();
DataColumn odcSec = new DataColumn();
DataColumn odcThird = new DataColumn();
DataColumn odcForth = new DataColumn();
odc.ColumnName = "Class";
odt.Columns.Add(odc);
odcSec.ColumnName = "Subject Name";
odt.Columns.Add(odcSec);
odcThird.ColumnName = "Grade";
odt.Columns.Add(odcThird);
odcForth.ColumnName = "GradeCollection";
odt.Columns.Add(odcForth);
DataRow odr = odt.NewRow();
odr["Class"] = "FYBA";
odr["Subject Name"] = "Hindi";
odr["Grade"] = "A";
odr["GradeCollection"] = "A,B,C,D,E";
odt.Rows.Add(odr);
DataRow odrFirst = odt.NewRow();
odrFirst["Class"] = "SYBA";
odrFirst["Subject Name"] = "English";
odrFirst["Grade"] = "B";
odrFirst["GradeCollection"] = "A,B,C,D,E";
odt.Rows.Add(odrFirst);
DataRow odrSecond = odt.NewRow();
odrSecond["Class"] = "SYBA";
odrSecond["Subject Name"] = "English";
odrSecond["Grade"] = "C";
odrSecond["GradeCollection"] = "A,B,C,D,E";
odt.Rows.Add(odrSecond);
DataRow odrThird = odt.NewRow();
odrThird["Class"] = "TYBA";
odrThird["Subject Name"] = "Marathi";
odrThird["Grade"] = "D";
odrThird["GradeCollection"] = "A,B,C,D,E";
odt.Rows.Add(odrThird);
DataRow odrForth = odt.NewRow();
odrForth["Class"] = "FYBA";
odrForth["Subject Name"] = "Telagu";
odrForth["Grade"] = "E";
odrForth["GradeCollection"] = "A,B,C,D,E";
odt.Rows.Add(odrForth);
if (odt != null && odt.Rows.Count > 0)
{
DataGridViewTextBoxColumn txtClass = new DataGridViewTextBoxColumn();
txtClass.HeaderText = "Class";
txtClass.MaxInputLength = 20;
txtClass.Width = 70;
txtClass.Name = "Class";
kryptonDataGridView1.Columns.Add(txtClass);
DataGridViewTextBoxColumn txtSubjectName = new DataGridViewTextBoxColumn();
txtSubjectName.HeaderText = "SubjectName";
txtSubjectName.MaxInputLength = 20;
txtSubjectName.Width = 70;
txtSubjectName.Name = "SubjectName";
kryptonDataGridView1.Columns.Add(txtSubjectName);
DataGridViewComboBoxColumn comboboxColumn = new DataGridViewComboBoxColumn();
comboboxColumn.HeaderText = "Grade";
comboboxColumn.DropDownWidth = 160;
comboboxColumn.Width = 90;
comboboxColumn.MaxDropDownItems = 3;
comboboxColumn.FlatStyle = FlatStyle.Flat;
kryptonDataGridView1.TabStop = true;
kryptonDataGridView1.Focus();
kryptonDataGridView1.Columns.Insert(2, comboboxColumn);
for (int i = 0; i < odt.Rows.Count; ++i)
{
string[] row1 = new string[] { odt.Rows[i]["Class"].ToString(), odt.Rows[i]["Subject Name"].ToString() };
kryptonDataGridView1.Rows.Add(row1);
string sItemNames = odt.Rows[i]["GradeCollection"].ToString();
char[] charArray = new char[] { ',' };
string[] sItemNameArray = sItemNames.Split(charArray, StringSplitOptions.RemoveEmptyEntries);
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("Name");
dt.Columns.Add(dc1);
DataRow odrinner = dt.NewRow();
odrinner["Name"] = "--Select--";
dt.Rows.Add(odrinner);
foreach (string item in sItemNameArray)
{
dt.Rows.Add(item);
}
comboboxColumn.DataSource = dt;
comboboxColumn.DisplayMember = "Name";
if (!string.IsNullOrEmpty(odt.Rows[i]["Grade"].ToString()))
{
kryptonDataGridView1.Rows[i].Cells[2].Value = odt.Rows[i]["Grade"].ToString();
}
else
{
comboboxColumn.DefaultCellStyle.NullValue = "--Select--";
}
}
}
}
[/code]
Now i want to use arrow key as well as enter key for combobox selection but when i press arrow keys then the focus goes to next row combobox column ,it is not selected that particular combo box.In the same when i use enter key then the focus goes to next column.I want when i hit enter key or arrow key then it select combobox(means focus shuld be on combobox) so that i can select items from that combo box without space hit.
You can use this code:
private void kryptonDataGridView1_CellEnter(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2)
{
kryptonDataGridView1.BeginEdit(true);
}
}
I cannot Display the value of "Price" cell on my gridview, here's my code:
DataColumn idCol2 = new DataColumn();
idCol2.DataType = System.Type.GetType("System.Int32");
idCol2.ColumnName = "Id";
table.Columns.Add(idCol2);
DataColumn SKUCol2 = new DataColumn();
SKUCol2.DataType = System.Type.GetType("System.String");
SKUCol2.ColumnName = "SKU";
table.Columns.Add(SKUCol2);
DataColumn ProdNameCol2 = new DataColumn();
ProdNameCol2.DataType = System.Type.GetType("System.String");
ProdNameCol2.ColumnName = "Product Name";
table.Columns.Add(ProdNameCol2);
DataColumn DescCol2 = new DataColumn();
DescCol2.DataType = System.Type.GetType("System.String");
DescCol2.ColumnName = "Product Description";
table.Columns.Add(DescCol2);
DataColumn PriceCol2 = new DataColumn();
PriceCol2.DataType = System.Type.GetType("System.Decimal");
PriceCol2.ColumnName = "Price";
table.Columns.Add(PriceCol2);
DataColumn[] keys2 = new DataColumn[5];
keys2[0] = idCol2;
table.PrimaryKey = keys2;
LivePOS livepos = new LivePOS(clientId, clientSecret);
_products = livepos.GetProducts(apiKey, token);
foreach (var p in _products)
{
table.Rows.Add(p.Id, p.Sku, p.Name, p.Description , p.SellingPrice);
}
table.DefaultView.Sort = "Id ASC";
dataGridView1.DataSource = table;
this.dataGridView1.DefaultCellStyle.Format = "N4";
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Cells[0].ReadOnly = false; //id
row.Cells[1].ReadOnly = true; //sku
row.Cells[2].ReadOnly = true; //name
row.Cells[3].ReadOnly = true; //description
}
Please help me :)Is there something wrong in this code? I created new instance of the datatable named "table" on my Form_Load event. All cell values are displaying correctly aside from this "Price" column.
Your Price Column should have Datatype of Double than Decimal.Take a look at this link
Decimal Vs Double
hope that helps