Looping a datatable columnwise - c#

I have a datatable which contains data in the following format:
Let us name this datatable as dt1
ColumnA ColumnB ColumnC
-------------------------------------
President Manager President
Manager
The data in the datatable above is provided for selection for authority selection purpose as a checklist on a web form. When the items in the checklist are checked and a button click occurs, I insert the checked items into another datatable as shown below:
Let us name this datatable as dt2
----------
Manager
President
Manager
Now I need to get the Column Names from dt1(the first datatable) where the dataitems in dt2 occurs.For example, in this scenario my required output to another datatable(say dt3) would be
--------
ColumnB
ColumnC
ColumnC
In this datatable(dt3) 'ColummB' is included as the dt2(which contains the checked texts from the checklist) has the data item 'Manager' which occurs under 'ColumnB' in dt1; 'ColumnC' occurs twice as dt2 contains 'President' and 'Manager' which occurs under 'ColumnC' in dt1.
I need an efficient loop(preferably coulmnwise for dt1) so that i can compare the values of dt1 and dt2 and add them to dt3. Please note that the data items in dt1 and dt2 are not fixed as dt1 contains data from the database and dt2 has checked values from the form. Finally the row count of the dt3 should be equal to row count of dt2 (or) a new column can be added to dt2 instead of creating dt3(still maintaining the same row count).

An idea could be loop through each row and column of datatable.
Then loop through the second datatable values
If value match select the column name.
Below is just and idea what you can do
DataTable dt1;
DataTable dt2;
DataTable dt3;
string[] ar=new string....
foreach (DataRow dr in dt1.Rows)
{
foreach (DataColumn clm in dt1.Columns)
{
//loop through each value of the other table
foreach(DataRow drow in dt2.Rows)
{
string value = drow[0].ToString();
if(value==clm)
{
//add the column name into a array
DataRow row = dt3.NewRow();
row[0]=clm.ColumnName;
dt3.Rows.Add(row);
break;
}
}
}
}

Related

Copy Datatable1 values to Datatable2 with the required columns configuration

Copy data from Datatable1 to Datattable2 only for specific columns. I have a method with List of column vlaues and Datatable as input. I need to get all the columns from input datatable and copy to new datatble.
/*Input:
columnNames in list : column1,column2,column3
datatable1 : column1,column2,column5,column6,column3
Output:
datatble2 : column1,column2,column3 (columns from list need to be copied from datatble1 to datatble2 and return datatble2)
*/
public DataTable CopyFromDatatbale(List<string> columnNames,DataTable datatable1)
{
DataTable datatble2=new DataTable();
/*
Code to copy the data from datatable1 to datatble2 with specific columns
*/
}
This is the code i am looking for...Copying data from DataTable1 to DataTable2 for specified columns .Finally in the datatable2 i have all the columns from datatble1 (Only specific columns)
//Copy Columns from Datatable1 to Datatble2 based on columns on columnList
DataView dtView = new DataView(dataTable1);
DataTable dataTable2= new DataTable();
var getColumnNamesCommaSeperated = columnList.Select(x => x.columnNames).ToArray();
dataTable2= dataTable1.Select().CopyToDataTable()
.DefaultView.ToTable(false, getColumnNamesCommaSeperated);

How to add column to datatable from another datatable

I have two data tables dt1 and dt2, both share a common column. How to map the common column and add a new column with data to data table dt1.
DataTable dt1=new DataTable();
DataTable dt2=new DataTable();
sqlDataAdapter da1=new sqlDataAdapter("select col1,col2,col3,col4 from table",connection);
dataset ds1=new dataset();
da1.fill(ds);
dt1=ds.tables[0];
similarly for dt2 the select statement is "select col1,somecol from sometable" rest is the same as dt1.
for dt1 the output is: and the output for dt2
col1 col2 col3 col4 col1 somecol
1 2 3 4 1 true
2 5 6 ... 2 false..
i tried like below:
datatable dtTotal=new datatable();
dtTotal=dt1.clone();
foreach(datacolumn col in dt2.columns)
{
if(col.columnname=="somecol")
{
dtTotal.columns.add("somecol");
dtTotal.columns["somecol"].Datatype=col.Datatype;
}
}
foreach(datarow dr in dt1.rows)
{
dtTotal.importrows(dr);
}
//here a column is added but i don't understand how to import data into that column
I want to have a outpu like below:
col1 col2 col3 col4 somecol
1 2 3 4 true
2 5 6 7 false...
I cannot write a simple join while selecting the the data itself, because the dt2 data is coming from more complex calculations. so I have to do it at datatable level only.
if number of rows in dt1 doesnt match with number of rows in dt2 then dt2 should be added new rows with default value false.
You can use the DataTable.Merge method. The command dt1.Merge(dt2) adds to dt1 the additional columns and the additional data records from dt2. The data from dt2 will overwrite the data from dt1 that share the same primary key value and the same column name.
DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
// Fill the data tables
...
// Set the default value for boolean column
dt2.Columns[4].DefaultValue = false;
// Set the primary keys
dt1.PrimaryKey = new DataColumn[] { dt1.Columns[0] }; // Use the appropriate column index
dt2.PrimaryKey = new DataColumn[] { dt2.Columns[0] }; // Use the appropriate column index
// Merge the two data tables in dt1
dt1.Merge(dt2);

How to remove time from datetime column in dataset?

I have to export data to excel sheet in asp.net c# application. Now I have wriiten below lines of code
DataTable dt = new DataTable();
dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
row["ExpiryDate"] = Convert.ToDateTime(row["ExpiryDate"]).ToShortDateString();
}
DataSet dsn = new DataSet();
DataTable dtcopy = dt.Clone();
dsn.Tables.Add(dtcopy);
WebUtility.GenrateExcel(ds, "ExpiredDocuments");
I want to first remove time from data set's Expiry date column and then pass
it to the generate Excel function so that time will not appear in Expiry date column in excel... Please help the above code is not working...
I guess, you need look through this:
https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
You should use smth like
Convert.ToDateTime(ds.Tables[0].Rows[i]["ExpiryDate"]).ToString("MM/dd/yyyy")
Or whatever you need.
These are the steps you need to do in order to accomplish what you are asking:
Create a new column of type string
Set the new column's value to ShortDateString of the corresponding "ExpiryDate" column
Remove the "ExpiryDate" column
Move the new string column to the position of the old "ExpiryDate" column
Rename the new column to "ExpiryDate"
Like so:
dt.Columns.Add("ExpiryDateString", typeof(String));
foreach(DataRow row in dt.Rows)
{
row["ExpiryDateString"] = ((DateTime)row["ExpiryDate"]).ToShortDateString();
}
int columnNumber = dt.Columns["ExpiryDate"].Ordinal;
dt.Columns.Remove("ExpiryDate");
dt.Columns["ExpiryDateString"].SetOrdinal(columnNumber);
dt.Columns["ExpiryDateString"].ColumnName = "ExpiryDate";

Adding column in a datatable with a dynamic column name in C#

DataTable dt = new DataTable();
var dr = dt1.Date;
String rr = Convert.ToString(dr);
DataColumn dc1=new DataColumn();
dc1.ColumnName = rr; dt.Columns.Add(dc1);
And if i add datarow after this like
dt.Rows.Add("hello","hello1","hello2");
dataGrid1.ItemsSource = dt.DefaultView;
the data is not displayed in the grid .
If i comment the line
dc1.ColumnName = rr;
the values are displayed properly
But i want the colmn name to be the date that is "dt1" here
pleae note that the dt1 are the date values which is dynamic and it will be incremented in each loop.
like
dt1 = dt1.AddDays(1);
Please help
Without seeing your Xaml for the data grid it's difficult to be sure but I imagine that you've specified a field name for the date column in your xaml.
To resolve this, you'll need to set AutoGenerateColumns=True and let the grid automatically find the field name.

row headers on a datatable - to be displayed in a datagridview

Is there anyway to store row header information in a datatable so that when i bind it to a datagridview, it will automatically display both the column and row headers in c#?
Linqpad Demo-Program
As far as i understood you would like to add the column name as values into the datatable / the datagridview. The following is a Linqpad-Program you can easily copy paste into Linqpad to play around. The code adds the column-names to the first row to the datatable. You can easily bind this datatable to a gridview - but beware that each column of the datatable must be of type string.
void Main()
{
GetDataTable().Dump();
}
public DataTable GetDataTable()
{
var dt = new DataTable();
dt.Columns.Add("Id", typeof(string)); // dt.Columns.Add("Id", typeof(int));
dt.Columns["Id"].Caption ="my id";
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Job", typeof(string));
dt.Rows.Add(GetHeaders(dt));
dt.Rows.Add(1, "Janeway", "Captain");
dt.Rows.Add(2, "Seven Of Nine", "nobody knows");
dt.Rows.Add(3, "Doctor", "Medical Officer");
return dt;
}
public DataRow GetHeaders(DataTable dt)
{
DataRow dataRow = dt.NewRow();
string[] columnNames = dt.Columns.Cast<DataColumn>()
.Select(x => x.ColumnName)
.ToArray();
columnNames.Dump();
dataRow.ItemArray = columnNames;
return dataRow;
}
Update 2019-06 with additional explanation and alternative code
The method GetHeaders is not the simplest option to get the headers.
Previoulsy the extension method Cast<TResult>(IEnumerable) was used on the DataColumnCollection-Class An alternative would be to just iterate over the collection - this what is done In GetHeadersNew T
public DataRow GetHeadersNew(DataTable dt)
{
DataRow row = dt.NewRow();
DataColumnCollection columns = dt.Columns;
for (int i = 0 ;i <columns.Count ;i++)
{
row[i] = columns[i].ColumnName;
}
return row;
}
This is likely more efficient because less objects and methods are involved.
As long as you can create them with the code based on the data in the row I would just add them at run time using c#. Add a column to the datatable and run through it with a foreach loop. As long as there are not too many rows this code will execute very quickly:
DataTable dt = new DataTable();
// code here to get your datatable
dt.Columns.Add("rowheader");
foreach (DataRow r in dt.Rows)
{
r["rowheader"] = "my nice row header";
}
Then output the new column rowheader as the first cell in the grid.
Another solution is to use the sql query to return an 'extra' column in the result set. for example:
Select *, 'my nice row header' as rowheader from myTable
In this way you make SQL do all the work.

Categories