I have a datatable with 10 columns, but User can select the columns to be displayed so I need to create a generic code to display only the selected columns.
Current code:
string[] selectedColumns = new[] { };
DataTable columns = new DataView(table).ToTable(false, selectedColumns);
You could simply hide the columns in the datagridview (supposing you're using one)
dataGridView1.Columns["ColName"].Visible = False;
for every column that are not in selectedColumns
But if you really need to filter the dataset, I remember that you can do something like:
mydatatable.Columns.Remove("ColName");
in your datatable... or in a copy.
If you are going to show the columns in a datagridview, my option will be setting the ColumnMapping property of the datatable column like this
mydatatable.Columns["Colname"].ColumnMapping = MappingType.Hidden;
Unfortunatly I'm not at home now, so I can't test it, but as you can see, there are many options.
EDIT: In response to your request, you can deal with non selected columns like this:
for(int i = 0;i<dt.Columns.Count;i++)
{
if(!selectedColumns.Contains(dt.Columns[i].ColumnName))
{
dt.Columns[i].ColumnMapping = MappingType.Hidden;
}
}
public static void Main(string[] args)
{
DataTable act = new DataTable();
act.Columns.Add(new DataColumn("id", typeof(System.Int32)));
act.Columns.Add(new DataColumn("name"));
act.Columns.Add(new DataColumn("email"));
act.Columns.Add(new DataColumn("phone"));
DataRow dr = act.NewRow();
dr["id"] = 101;
dr["name"] = "Rama";
dr["email"] = "rama#mail.com";
dr["phone"] = "0000000001";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 102;
dr["name"] = "Talla";
dr["email"] = "talla#mail.com";
dr["phone"] = "0000000002";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 103;
dr["name"] = "Robert";
dr["email"] = "robert#mail.com";
dr["phone"] = "0000000003";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 104;
dr["name"] = "Kevin";
dr["email"] = "kevin#mail.com";
dr["phone"] = "0000000004";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 106;
dr["name"] = "TomChen";
dr["email"] = "tomchen#mail.com";
dr["phone"] = "0000000005";
act.Rows.Add(dr);
var lselColumns = new[] {"id", "name"};
var dt = act.DefaultView.ToTable(true, lselColumns);
foreach (DataRow drow in dt.Rows)
{
string drowData = string.Empty;
foreach (DataColumn r in drow.Table.Columns)
{
drowData += (drowData == string.Empty) ? drow[r] : "|" + drow[r];
}
Console.WriteLine(drowData);
}
Console.ReadLine();
}
Related
I need to copy each row in a data table with its child row, editing each row in C#.
Please check my code.
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[13] { new DataColumn("FIX1"), new DataColumn("FIX2"), new DataColumn("SEQNO")
,new DataColumn("FIX3"),new DataColumn("TRANSACTIONCODE"),new DataColumn("FIX4"),
new DataColumn("CreditAccNo"),new DataColumn("CreditBRNO"),new DataColumn("CreditDate"),
new DataColumn("1LinkCode"),new DataColumn("Debit/creditResonding"),new DataColumn("InstruementNo1"),
new DataColumn("InstruementNo2")});
da.Fill(ds);
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn column in dt.Columns)
{
row["FIX1"] = "0";
row["FIX2"] = "0";
row["SEQNO"] = "1";
row["FIX3"] = "0";
row["TRANSACTIONCODE"] = "ZNBPDR";
row["FIX4"] = "0";
row["CreditAccNo"] = "2010100002";
row["CreditBRNO"] = "2";
row["CreditDate"] = DateTime.Now.ToString("dd/MM/yyyy");
row["1LinkCode"] = "71";
row["Debit/creditResonding"] = "2";
row["InstruementNo1"] = "130row2";
row["InstruementNo2"] = "130row2";
txt += row[column.ColumnName].ToString() + "|";
}
//Add new line.
txt += "\r \n";
txt = "";
}
This is going to be my text file (30 lines)
OrderNo:37374
OrderQuantity:250
BarcodeQR:584,25478Klkd28
NormalBarcode:1565484864
.......
.......
.......
This is the code :
public DataTable DTforReport()
{
DataTable dt = new DataTable();
DataColumn col = new DataColumn("test");
col.DataType = System.Type.GetType("System.String");
dt.Columns.Add(col);
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
foreach (var line in lines)
{
var segments = line.Split(';');
foreach (var seg in segments)
{
DataRow dr = dt.NewRow();
dr[0] = seg;
dt.Rows.Add(dr);
}
}
return dt;
}
I want my output like this
OrderNo OrderQuantity BarcodeQR
37374 250 584,25478Klkd28
How can I change my code to achieve this?
You have generated only one column. Change your code like below to see your desired result:
public DataTable DTforReport()
{
DataTable dt = new DataTable();
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
DataRow dr = dt.NewRow();
for (int i = 0; i < lines.Length; i++)
{
DataColumn col = new DataColumn(lines[i].Split(':')[0]);
col.DataType = Type.GetType("System.String");
dt.Columns.Add(col);
var segment = lines[i].Split(':')[1];
dr[i] = segment;
}
dt.Rows.Add(dr);
return dt;
}
I suggest you to modify your method like the following:
public DataTable DTforReport()
{
DataTable testTable = new DataTable("Test");
testTable.Columns.Add("OrderNo");
testTable.Columns.Add("OrderQuantity");
testTable.Columns.Add("BarcodeQR");
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
foreach (var line in lines)
{
DataRow dRow = testTable.NewRow();
var segments = line.Split(';');
for (int i = 0; i < segments.Length; i++)
{
var colValues = segments[i].Split(':');
dRow[i] = colValues[1];
}
testTable.Rows.Add(dRow);
}
return testTable;
}
Few suggestions for improvement:
I have given static column names, if you want to add more or they may change in future means you can create dynamic columns in the datatable.
If you have doubts in the input values, make use of proper validation
Validations in the sense, make sure about the splitted values before accessing them through index otherwise they may ends up with IndexOutOfRangeException
DataTable dt = new DataTable();
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
var firstLine = lines.First();
var columns = firstLine.Split(';');
for (var icount = 0; icount < columns.Count(); icount++)
{
var colName = columns[icount].Contains(":") ? columns[icount].Split(':')[0] : "Column" + icount;
var dataCol = new DataColumn(colName);
dataCol.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dataCol);
}
foreach (var line in lines)
{
DataRow dr = dt.NewRow();
var segments = line.Split(';');
for (var icount = 0; icount < segments.Count(); icount++)
{
var colVal = segments[icount].Contains(":") ? segments[icount].Split(':')[1] : "";
dr[icount] = colVal;
}
dt.Rows.Add(dr);
}
*Number of column must be same in each row.
Below is the method that i used to display records based on the conditions.
I have so many rows inserted in database and the data should be displayed in such a way that:
for the first grid i need to bind from A00-B99
for the second grid bind from c00-d49
for the third grid bind from d50-d89
for the fourth grid bind from E00-E89
like that i have so many grids that which i should bind the data but it is not working.
public void BindGrid()
{
string query = "select * from tablename";
SqlDataAdapter da = new SqlDataAdapter(query, conn);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[0];
Session["dt1"] = dt;
DataTable dt2 = (DataTable)Session["dt1"];
DataRow[] dr = dt2.Select("Text >='A%' AND Text >='B%' OR Text ='C%'");
DataTable Newdt = dr.CopyToDataTable<DataRow>();
grd1.DataSource = Newdt;
grd1.DataBind();
}
What happens is the data that starts with A and B in the text column gets eliminated and from c to z gets binded to my first grid but the series with A and B should get binded to first grid and series C and D should get binded to second grid ie(c00-d49) and the series that are remaining in D should get binded to third grid(ie D50-D89) and series E should get binded to fourth grid(ie E00-E89) like that it should be done.
How can i do this?
I suggest you filter ranges out of your initial DataTable and assign each range to a new DataTable. Here is an example, of course you will continue to query for your data, but I have built the data manually for demonstration. Also shared as LinqPad Query
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Code", Type.GetType("System.String")));
DataRow r = dt.NewRow();
r[0] = "A00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "B50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "B99";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c30";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c49";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d59";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d60";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d89";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E89";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E90";
dt.Rows.Add(r);
var range1 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("A") >= 0 && d[0].ToString().CompareTo("B99") <= 0);
DataTable TableRange1 = range1.CopyToDataTable();
var range2 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("c00") >= 0 && d[0].ToString().CompareTo("d49") <= 0);
DataTable TableRange2 = range2.CopyToDataTable();
var range3 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("E00") >= 0 && d[0].ToString().CompareTo("E89") <= 0);
DataTable TableRange3 = range3.CopyToDataTable();
I am not using Entity Framework.
There are 2 Datatables, each with different no. of columns. There is one common column - ItemId
If it was Union, I would have used 'Merge', but don't know how to do a Union All for these 2 DataTables
public static void Main()
{
//First DataTable
DataTable dt1 = new DataTable();
dt1.Columns.Add("ItemId");
dt1.Columns.Add("Name");
dt1.Columns.Add("Color");
DataRow dr = dt1.NewRow();
dr["ItemId"] = "1";
dr["Name"] = "Name1";
dr["Color"] = "Color1";
dt1.Rows.Add(dr);
dr = dt1.NewRow();
dr["ItemId"] = "2";
dr["Name"] = "Name2";
dr["Color"] = "Color2";
dt1.Rows.Add(dr);
//Second DataTable
DataTable dt2 = new DataTable();
dt2.Columns.Add("ItemId");
dt2.Columns.Add("Name");
dt2.Columns.Add("Price");
DataRow dr2 = dt2.NewRow();
dr2["ItemId"] = "1";
dr2["Name"] = "Name1";
dr2["Price"] = "100";
dt2.Rows.Add(dr2);
dr2 = dt2.NewRow();
dr2["ItemId"] = "2";
dr2["Name"] = "Name3";
dr2["Price"] = "200";
dt2.Rows.Add(dr2);
}
Expected Output
ItemId Name Color Price
1 Name1 Color1
2 Name2 Color2
1 Name1 100
2 Name3 200
You can use DataTable.Merge()
If you have primary key in both the table then it will perform merge on primary key else it will directly append all the records.
In youe case make ItemID as primary key.
using System.Linq.Expressions;
......
var result1 = from row1 in dt1.AsEnumerable()
select new { Name = row1.Field<String>("Name"), Color = row1.Field<String>("Color"), Price = "" };
var result2 = from row1 in dt2.AsEnumerable()
select new { Name = row1.Field<String>("Name"), Color = "", Price = row1.Field<String>("Price") };
var res = result1.Concat(result2);
foreach (var item in res)
Console.WriteLine("{0} - {1} - {2}", item.Name, item.Color, item.Price);
Even though this question is years old, for anyone looking for another way to do this:
public static DataTable MergeTables(DataTable dt1, DataTable dt2)
{
DataTable dt3 = dt1.Clone();
foreach (DataColumn col in dt2.Columns)
{
string strColumnName = col.ColumnName;
int intColNum = 1;
while (dt3.Columns.Contains(strColumnName))
{
strColumnName = string.Format("{0}_{1}", col.ColumnName, ++intColNum);
}
dt3.Columns.Add(strColumnName, col.DataType);
}
var Mergered = dt1.AsEnumerable().Zip(dt2.AsEnumerable(), (r1, r2) => r1.ItemArray.Concat(r2.ItemArray).ToArray());
foreach (object[] rowFields in Mergered)
dt3.Rows.Add(rowFields);
return dt3;
}
Im new in asp.net. I want to know how to add a row in a gridview programatically. I was able to do it but it just displays the latest addition.
Here is my code:
DataTable dt = new DataTable();
dt.Columns.Add("Question");
dt.Columns.Add("Answer");
DataRow dr = dt.NewRow();
dr["Question"] = txtQuestion.Text;
dr["Answer"] = txtAnswer.Text;
dt.Rows.Add(dr);
dt.AcceptChanges();
gvQnA.DataSource = dt;
gvQnA.DataBind();
Its because you are creating new table each time and binding it with the grid
Do code as below may resolve your issue ...
here i am taking existing datasource and binding it again by adding two more row...
DataTable dt = gridView.DataSource as DataTable;
if (dt != null)
{
DataRow dr = dt.NewRow();
dr["Question"] = txtQuestion.Text;
dr["Answer"] = txtAnswer.Text;
dt.Rows.Add(dr);
dt.AcceptChanges();
gvQnA.DataSource = dt;
gvQnA.DataBind();
}
#Pranay is correct.In addition You can also achive that by using DataTable as property.
private DataTable Dt
{
set { ViewState.Add("Dt", value); }
get { return (DataTable)ViewState["Dt"]; }
}
...
DataRow dr = Dt.NewRow();
dr["Question"] = txtQuestion.Text;
dr["Answer"] = txtAnswer.Text;
Dt.Rows.Add(dr);
Dt.AcceptChanges();
gvQnA.DataSource = Dt;
gvQnA.DataBind();
You have added one row in your code thats why it is showing one row.
If you have added multiple rows it would have shown proper result
DataTable dt = new DataTable();
dt.Columns.Add("Question");
dt.Columns.Add("Answer");
DataRow dr = dt.NewRow();
dr["Question"] = txtQuestion.Text;
dr["Answer"] = txtAnswer.Text;
dt.Rows.Add(dr);
**DataRow dr = dt.NewRow();
dr["Question"] = "2nd row";
dr["Answer"] = "2nd row";
dt.Rows.Add(dr);**
dt.AcceptChanges();
gvQnA.DataSource = dt;
gvQnA.DataBind();
May be #Pranay is also right
Hey Just check this. This might help u
DataTable dataTable = new DataTable();
int columnsCount = // Set the number of the table's columns here.
for (int columnIndex = 0; columnIndex < columnsCount; columnIndex++)
{
DataColumn dataColumn = new DataColumn();
// Assign dataColumn properties' values here ..
dataTable.Columns.Add(dataColumn);
}
int rowsCount = // Set the number of the table's rows here.
for (int columnIndex = 0; columnIndex < columnsCount; columnIndex++)
{
DataRow dataRow = new DataRow();
dataRow["ColumnName"] = // Set the value here ..
dataTable.Rows.Add(dataRow);
}