how to dynamically get a single value from a datatable in C#? - c#

I am new at C#, I have a DataTable named dt; Now I want to get the values from it's each row and a specific column named "Number" from which I can calculate a third column to add. But cant' do it. Any ideas? Please help me.
foreach (DataRow dRow in dt.Rows)
{
int number = dt.Rows[0].Field<int>(1);
dRow[Ratio] = Convert.ToString(((number * 100) / grandTotal)) + " %";
}

Use a loop and the Field method, presuming that Number is an int:
foreach(DataRow row in dt.Rows)
{
int number = row.Field<int>("Number");
// do your calculation
row.SetField("ThirdColumn", someValue);
}

Related

print an entire table in C#

I'm trying to print the content of a DataTable, starting with the column headers, followed by the content of the table tupples.
output.Add($"Table : [{dataTable.TableName}]");
string strColumnNames = "";
foreach (DataColumn col in dataTable.Columns)
{
if (strColumnNames == "")
strColumnNames = col.ColumnName.PadLeft(col.MaxLength - col.ColumnName.Length); // (*)
else strColumnNames = strColumnNames + "|" +
col.ColumnName.PadLeft(col.MaxLength - col.ColumnName.Length); // (*)
}
output.Add($"[{strColumnNames}]");
foreach (DataRow dataRow in dataTable.Rows)
{
string temp = "";
for (int i = 0; i < dataRow.ItemArray.Count(); i++)
{
if (i == 0)
temp = dataRow.ItemArray[i].ToString(); // (**)
else temp += "|" + dataRow.ItemArray[i].ToString(); // (**)
}
output.Add($"[{temp}]");
}
The (*) parts in this code are using the MaxLength property of the DataColumns maximum length in order to get a column-like output.
I would like to do the same in the (**) parts, but I don't know how to access the corresponding DataColumn, starting from the dataRow object.
Does anybody have an idea?
Thanks in advance
You already have the dataTable instance available. dataTable.Columns[i] should give you the appropriate DataColumn.
Datatable has already been instantiated here. If you want to print the datacolumn you should use dataTable.Column[i] for the appropriate column.

How to embed an attribute in a DataRow?

I am doing my project, in which I have a database of books. I have loaded that database in DataTable "Books". There is another DataTable "Watermark_books", which contains all attribute as "Books" datatable has, as well as an extra attribute which is watermark of each row.
I have to calculated watermark, now I have to embed that watermark attribute in "Watermark_books" datatable.
Kindly have a look on code which i have written.
int ky= 0;
double attrib = CalculateWatermarkAttribute(i, j, out ky);
DataRow dataRow = dataSet.Tables["Watermark_Books"].NewRow();
DataRow tmpRow = dataSet.Tables["Books"].Select("id=" + ky)[0];
dataRow.ItemArray = tmpRow.ItemArray; // this copies all columns of one row to new row
dataRow.ItemArray[7] = attrib; // this line of code is not working
dataSet.Tables["Watermark_Books"].Rows.Add(dataRow);
Can anyone point out what is wrong with above mentioned line of code....
Thanks in advance...
Try below code:
int ky= 0;
double attrib = CalculateWatermarkAttribute(i, j, out ky);
DataRow dataRow = dataSet.Tables["Watermark_Books"].NewRow();
DataRow tmpRow = dataSet.Tables["Books"].Select("id=" + ky)[0];
foreach (System.Data.DataColumn column in dataSet.Tables["Watermark_Books"].Columns)
{
if (column.ColumnName == "WatermarkColumn")
dataRow["WatermarkColumn"] = attrib;
else
dataRow[column.ColumnName] = tmpRow[column.ColumnName];
}

Find a string in all DataTable columns

I am trying to find a fast way to find a string in all datatable columns!
Followed is not working as I want to search within all columns value.
string str = "%whatever%";
foreach (DataRow row in dataTable.Rows)
foreach (DataColumn col in row.ItemArray)
if (row[col].ToString() == str) return true;
You can use LINQ. It wouldn't be any faster, because you still need to look at each cell in case the value is not there, but it will fit in a single line:
return dataTable
.Rows
.Cast<DataRow>()
.Any(r => r.ItemArray.Any(c => c.ToString().Contains("whatever")));
For searching for random text and returning an array of rows with at least one cell that has a case-insensitive match, use this:
var text = "whatever";
return dataTable
.Rows
.Cast<DataRow>()
.Where(r => r.ItemArray.Any(
c => c.ToString().IndexOf(text, StringComparison.OrdinalIgnoreCase) > 0
)).ToArray();
If you want to check every row of every column in your Datatable, try this (it works for me!).
DataTable YourTable = new DataTable();
// Fill your DataTable here with whatever you've got.
foreach (DataRow row in YourTable.Rows)
{
foreach (object item in row.ItemArray)
{
//Do what ya gotta do with that information here!
}
}
Don't forget to typecast object item to whatever you need (string, int etc).
I've stepped through with the debugger and it works a charm. I hope this helps, and good luck!
This can be achieved by filtering. Create a (re-usable) filtering string based on all the columns:
bool UseContains = false;
int colCount = MyDataTable.Columns.Count;
string likeStatement = (UseContains) ? " Like '%{0}%'" : " Like '{0}%'";
for (int i = 0; i < colCount; i++)
{
string colName = MyDataTable.Columns[i].ColumnName;
query.Append(string.Concat("Convert(", colName, ", 'System.String')", likeStatement));
if (i != colCount - 1)
query.Append(" OR ");
}
filterString = query.ToString();
Now you can get the rows where one of the columns matches your searchstring:
string currFilter = string.Format(filterString, searchText);
DataRow[] tmpRows = MyDataTable.Select(currFilter, somethingToOrderBy);
You can create a routine of search with an array of strings with the names of the columns, as well:
string[] elems = {"GUID", "CODE", "NAME", "DESCRIPTION"};//Names of the columns
foreach(string column in elems)
{
string expression = string.Format("{0} like '%{1}%'",column,
txtSearch.Text.Trim());//Search Expression
DataRow[] row = data.Select(expression);
if(row.Length > 0) {
// Some code here
} else {
// Other code here
}
}
You can get names of columns by using ColmunName Method. Then, you can search every column in DataTable by using them. For example, follwing code will work.
string str = "whatever";
foreach (DataRow row in dataTable.Rows)
{
foreach (DataColumn column in dataTable.Columns)
{
if (row[column.ColumnName.ToString()].ToString().Contains(str))
{
return true;
}
}
}
You can create a filter expression on the datatable as well. See this MSDN article. Use like in your filter expression.
string filterExp = "Status = 'Active'";
string sortExp = "City";
DataRow[] drarray;
drarray = dataSet1.Customers.Select(filterExp, sortExp, DataViewRowState.CurrentRows);
for (int i=0; i < drarray.Length; i++)
{
listBox1.Items.Add(drarray[i]["City"].ToString());
}

How to sum columns in a dataTable?

How can I get a sum for all the columns in a datatable? Say I had the following table. How can I calculate the "total" row? It should be easy to add total row to a datatable.
Columns hits uniques sigups, etc...
Rows
1 12 1 23
2 1 0 5
3 6 2 9
total 19 3 37
Update
I ended up with this. It was the only thing I could get to work.
For Each col As DataColumn In TotalsTable.Columns
If col.DataType.Name = "DateTime" Then
count = count + 1
Continue For
End If
Dim colTotal As Double = 0
Dim value As Double
For Each row As DataRow In TotalsTable.Rows
If Double.TryParse(row(col), value) Then
colTotal += Double.Parse(row(col))
End If
Next
totalRow(count) = colTotal
count = count + 1
Next
There is also a way to do this without loops using the DataTable.Compute Method. The following example comes from that page. You can see that the code used is pretty simple.:
private void ComputeBySalesSalesID(DataSet dataSet)
{
// Presumes a DataTable named "Orders" that has a column named "Total."
DataTable table;
table = dataSet.Tables["Orders"];
// Declare an object variable.
object sumObject;
sumObject = table.Compute("Sum(Total)", "EmpID = 5");
}
I must add that if you do not need to filter the results, you can always pass an empty string:
sumObject = table.Compute("Sum(Total)", "")
Try this:
DataTable dt = new DataTable();
int sum = 0;
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn dc in dt.Columns)
{
sum += (int)dr[dc];
}
}
I doubt that this is what you want but your question is a little bit vague
Dim totalCount As Int32 = DataTable1.Columns.Count * DataTable1.Rows.Count
If all your columns are numeric-columns you might want this:
You could use DataTable.Compute to Sum all values in the column.
Dim totalCount As Double
For Each col As DataColumn In DataTable1.Columns
totalCount += Double.Parse(DataTable1.Compute(String.Format("SUM({0})", col.ColumnName), Nothing).ToString)
Next
After you've edited your question and added more informations, this should work:
Dim totalRow = DataTable1.NewRow
For Each col As DataColumn In DataTable1.Columns
totalRow(col.ColumnName) = Double.Parse(DataTable1.Compute("SUM(" & col.ColumnName & ")", Nothing).ToString)
Next
DataTable1.Rows.Add(totalRow)
You can loop through the DataColumn and DataRow collections in your DataTable:
// Sum rows.
foreach (DataRow row in dt.Rows) {
int rowTotal = 0;
foreach (DataColumn col in row.Table.Columns) {
Console.WriteLine(row[col]);
rowTotal += Int32.Parse(row[col].ToString());
}
Console.WriteLine("row total: {0}", rowTotal);
}
// Sum columns.
foreach (DataColumn col in dt.Columns) {
int colTotal = 0;
foreach (DataRow row in col.Table.Rows) {
Console.WriteLine(row[col]);
colTotal += Int32.Parse(row[col].ToString());
}
Console.WriteLine("column total: {0}", colTotal);
}
Beware: The code above does not do any sort of checking before casting an object to an int.
EDIT: add a DataRow displaying the column sums
Try this to create a new row to display your column sums:
DataRow totalsRow = dt.NewRow();
foreach (DataColumn col in dt.Columns) {
int colTotal = 0;
foreach (DataRow row in col.Table.Rows) {
colTotal += Int32.Parse(row[col].ToString());
}
totalsRow[col.ColumnName] = colTotal;
}
dt.Rows.Add(totalsRow);
This approach is fine if the data type of any of your DataTable's DataRows are non-numeric or if you want to inspect the value of each cell as you sum. Otherwise I believe #Tim's response using DataTable.Compute is a better.
It's a pity to use .NET and not use collections and lambda to save your time and code lines
This is an example of how this works:
Transform yourDataTable to Enumerable, filter it if you want , according a "FILTER_ROWS_FIELD" column, and if you want, group your data by a "A_GROUP_BY_FIELD".
Then get the count, the sum, or whatever you wish.
If you want a count and a sum without grouby don't group the data
var groupedData = from b in yourDataTable.AsEnumerable().Where(r=>r.Field<int>("FILTER_ROWS_FIELD").Equals(9999))
group b by b.Field<string>("A_GROUP_BY_FIELD") into g
select new
{
tag = g.Key,
count = g.Count(),
sum = g.Sum(c => c.Field<double>("rvMoney"))
};
for (int i=0;i<=dtB.Columns.Count-1;i++)
{
array(0, i) = dtB.Compute("SUM([" & dtB.Columns(i).ColumnName & "])", "")
}

c# getting item in row from datatable

foreach (DataRow row in dt.Rows)
{
string[] temprow={"","","",row[3].ToString()};
dtworklist.Rows.Add(temprow);
}
dt is my datatable. i need to get the 3rd element in the row and put it into an array. the above is what i tried so far with no luck. how do i do it?
Try this:
int i=0;
List<string> l=new List<string>();
foreach (DataRow row in dt.Rows)
{
l.Add(Convert.ToString(row[2]));
}
string[] stringArray=l.ToArray();
what if you try:
foreach (DataRow row in dt.Rows)
{
DataRow added = dtworklist.NewRow();
int columnOfInterest = 2; // could be the column name as a string too
added[columnOfInterest] = row[columnOfInterest];
}
Note that I have used index of 2 because the first index in the list is zero. If you want the third item you would be interested in index 2.

Categories