I want to get the sum of only three columns for each data row in datable. I have a DT with approx 15 columns and I only want the sum of column 7, column 9 and column 10. And all the columns are of string type.
I tried few methods using LINQ but all failed.
If all columns are strings but actually represent floating point numbers:
double totalSum = dt.AsEnumerable()
.Sum(r=> double.Parse(r[7].ToString()) + double.Parse(r[9].ToString()) + double.Parse(r[10].ToString()));
If some are empty or have invalid numbers you need to use double.TryParse.
Here is the solution, it worked for me even if the column type is of string:
for (int i = 11; i < dt.Rows.Count; i++)
{
for (int j = 14; j <= 18; j += 2)
{
if (j > 17)
j -= 1;
if(!string.IsNullOrEmpty(dt.Rows[i][2].ToString()))
{
newdt.Rows.Add(dt.Rows[i][18], dt.Rows[i][19],
dt.Rows[i][j]);
}
}
}
try
{
var result = 0;
if (newdt.Rows.Count != 0)
{
result = newdt.AsEnumerable().Sum(x => Convert.ToInt32(x["Column7"]));
subdt.Rows.Add(dt.Rows[i][18], dt.Rows[i][19], result)
}
...
Please help with the code. How can you add numbers from 3,4,5 columns and transfer it to the "Total" column. At the same time, the "Total" column cannot be permanent, for example, listView1.Items [i] .SubItems [11] .Text - this solution is not appropriate, you need to possibly find the "Total" column itself because it is not permanent It can be like SubItems [ 9] 10.11, etc.
Code to write data to listView1
dataReader = await cmd1.ExecuteReaderAsync();
if (dataReader.FieldCount > 0)
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
if (i == 0)
{
listView1.Columns.Add(dataReader.GetName(0), 0, HorizontalAlignment.Left);
}
else
{
listView1.Columns.Add(dataReader.GetName(i).ToString().Replace("_", " "), 80, HorizontalAlignment.Left);
}
}
ListViewItem lv = new ListViewItem();
//
while (await dataReader.ReadAsync())
{
lv = listView1.Items.Add(dataReader[dataReader.GetName(0)].ToString().Replace('_', ' '));
for (int h = 1; h < dataReader.FieldCount; h++)
{
lv.SubItems.Add(dataReader[dataReader.GetName(h)].ToString());
}
}
}
for (int i = 1; i < listView1.Columns.Count; i++)
listView1.Columns[i].Width = -2;
This code assumes there is a column named "Total" in listView1.
(int itt = 1; itt < listView1.Items.Count; itt++)
{
int Totall =
int.Parse(listView1.Items[itt].SubItems[2].Text) +
int.Parse(listView1.Items[itt].SubItems[3].Text) +
int.Parse(listView1.Items[itt].SubItems[4].Text);
//Сумма чисел добавить во всего
listView1.Items[itt].SubItems["Total"].Text = Totall.ToString();
}
int.Parse converts a string to an integer but keep in mind it will throw an exception if the string is not numerical. If you need error checking for that consider using int.TryParse.
Also note that SubItems are 0 indexed. Meaning 0 corresponds to the first visual column, 1 corresponds to the second.
I am trying to create a 2D array from a DataTable, however Instead of getting the end result defined below. One row is not added, if that row is added, it will overwrite the column values.
Here is the end result I am looking to get:
[
//columns
['TaskID','TaskName','StartDate','EndDate','Duration','PercentComplete','Dependecies'],
//rows
['Cite','Create bibliography',null,1420649776903,1,20,'Research'], //missing row
['Complete','Hand in paper',null,1420908976903,1,0,'Cite,Write'],
['Outline','Outline paper',null,1420563376903,1,100,'Research'],
['Research','Find sources',1420390576903,1420476976903,null,100,null],
['Write','Write paper',null,1420822576903,3,25,'Research,Outline']
];
However, I get this.
[
["TaskID","TaskName","StartDate","EndDate","Duration","PercentComplete","Dependecies"],
["Complete","Hand in paper",null,1420908976903.0,1,0,"Cite,Write"],
["Outline","Outline paper",null,1420563376903.0,1,100,"Research"],
["Research","Find sources",1420390576903.0,1420476976903.0,null,100,null],
["Write","Write paper",null,1420822576903.0,3,25,"Research,Outline"]
]
I have tried:
// define the array size based on the datatable
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count, breDataTable.Columns.Count];
const int columnsArryIndex = 0;
// populate array with column names
if (breDataTable.Columns.Count > 0 && breDataTable.Rows.Count > 0)
{
// loop around columns
for (int i = 0; i <= breDataTable.Columns.Count - 1; i++)
{
// add all the column names
multiDimensionalArry[columnsArryIndex, i] = breDataTable.Columns[i].ColumnName;
}
}
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j, k] = rowItem[k];
}
}
You're missing one row when creating your array since the columns name row dosent count as a row
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count + 1, breDataTable.Columns.Count];
And you need to change your for loop to take into count the extra row
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j + 1, k] = rowItem[k];
}
}
I am using delete row index to delete a row in datagridview.
But when one row is deleted then datagridview automatically appends next row
first time any index is deleted then itscorrect but at the second time row-1 indexed row is deleted
I am using this code:
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
dataGridView1.Rows.RemoveAt(int.Parse(arr[i]));
}
you have to reduce the 'i' after you delete a row when using for loop
See the following code
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
dataGridView1.Rows.RemoveAt(int.Parse(arr[i]));
i--; }
As i see it you skew the index off the dataGridView1 the first time.
lets say you have a list with element {1,2,3,4,5} if we now remove index 3 and then 4 we the end up removing 3 and 5 giving us the list {1,2,4} but we wanted to remove 3 and 4 not 3 and 5
what i think you want to do is to get all indexes you want to remove, and the order them and remove from top to bottom so instead of removing 3 an 4 in that order you remove 4 and 3 giving us the list {1,2,5}
List<int> RemoveList = new List<int>();
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
RemoveList.Add(int.Parse(arr[i]));
}
//Remove highest index first.
RemoveList.OrderByDescending(a=>a);
for (int i = 0; i < RemoveList.Count; i++)
{
dataGridView1.Rows.RemoveAt(RemoveList[i]);
}
it's a bit weird to increase i within the for loop than decrease it. Why don't you add the items than clear all rows ?
for (int i = 0; i < path.Length; i++) {
lpath.Add(path[i].ToString());
}
dataGridView1.Rows.Clear();
I'm reordering my dataTable columns using :
dataTable.Columns[int x].SetOrdinal(int y)
However, I use it for each column and that doesn't to work for me.
For instance :
dataTable.Columns[0].SetOrdinal(1);
dataTable.Columns[1].SetOrdinal(0);
Makes a double inversion...
And in my code, I have to define where each column must be.
Is there any solution to this ?
Thank you.
This process seems easy but not really such easy. The point is whenever you change the Ordinal of a column from x to a lower ordinal a (a < x) then all the columns with ordinals between a and x will be shifted right, if x is changed to a higher ordinal b (b > x) then all the columns with ordinals between x and b wil be shifted left. We must perform some update each time a column's ordinal is changed.
You can prepare a list of your column indices in the order you want, something like this:
List<int> indices = new List<int>{1,2,0,7,4,5,3,6};
for(int i = 0; i < indices.Count; i++){
dataTable.Columns[indices[i]].SetOrdinal(i);
if(indices[i] > i){
for(int j = i; j < indices.Count; j++)
if(indices[j] >= i && indices[j] < indices[i]) indices[j]++;//Right shifted
}
else if(indices[i] < i){
for(int j = i; j < indices.Count; j++)
if(indices[j] >= indices[i] && indices[j] < i) indices[j]--;//Left shifted
}
}
Or you can also prepare a list of your ColumnName in the order you want, something like this:
List<string> columns = new List<string>{"Column2","Column1","Column5","Column3","Column6","Column4"};
//The same code as above
You should change columns order in a loop from array of column name that each column name placed in correct order in array.
For more information go to this link : How to change DataTable columns order