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.
Related
Below is my class code
public class TextReaderClass
{
public DataTable ReadTextFile(string filepath)
{
DataTable dtTextFile = new DataTable();
dtTextFile.Columns.Add("Emp_Id");
dtTextFile.Columns.Add("Emp_FirstName");
dtTextFile.Columns.Add("Emp_LastName");
dtTextFile.Columns.Add("Emp_Designation");
dtTextFile.Columns.Add("Emp_Salary");
dtTextFile.Columns.Add("Emp_JoiningDate");
//CODE to add here reading from text file and filling the data table
string[] readTextfile = System.IO.File.ReadAllLines(#"D:\Rutu\datatest.txt");
//Run a loop here for each record in the text file
foreach (string line in readTextfile)
{
var cols = line.Split(';');
DataRow dtrow = dtTextFile.NewRow();
//Create an object of Data Row
dtTextFile.Rows.Add(dtrow);
//Fill the row data in DataTable
}
return dtTextFile;
}
}
I tried this CODE for reading from text file and filling the data table. Any help will be highly appreciated. Thanks
You can do like that by doing this you you also read and add it to datatable
public DataTable ReadTextFile(string filePath, int numberOfColumns)
{
DataTable tbl = new DataTable();
for(int col =0; col < numberOfColumns; col++)
tbl.Columns.Add(new DataColumn("Column" + (col+1).ToString()));
string[] lines = System.IO.File.ReadAllLines(filePath);
foreach(string line in lines)
{
var cols = line.Split(':');
DataRow dr = tbl.NewRow();
for(int cIndex=0; cIndex < 3; cIndex++)
{
dr[cIndex] = cols[cIndex];
}
tbl.Rows.Add(dr);
}
return tbl;
}
try this code.
public DataTable ReadTextFile(string filepath,int numberOfColumns)
{
DataTable dtTextFile = new DataTable();
for(int col =0; col < numberOfColumns; col++)
dtTextFile.Columns.Add(new DataColumn("Column" + (col+1).ToString()));
string[] readTextfile = System.IO.File.ReadAllLines(filepath);
foreach (string line in readTextfile)
{
var cols = line.Split(';');
DataRow dtrow = dtTextFile.NewRow();
for(int cIndex=0; cIndex < 3; cIndex++)
{
dtrow [cIndex] = cols[cIndex];
}
dtTextFile.Rows.Add(dtrow);
}
return dtTextFile;
}
And also get datatable to gridview
dataGridview.DataSource=ReadTextFile(filepath,6);
If you have a formatted text file and MS SQL Server consider using the bulk insert facility:
https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver15
An example:
BULK INSERT Sales.Orders FROM 'C:\Rutu\datatest.txt' WITH ( FORMAT='CSV');
I have a DataTables with Emails. Over the LDAP I have the Userdata. Now Id like to Increase the DataTable depending upon the EmailAdress.
myDataTable.Columns.Add(new DataColumn("LDAP_Data"));
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
//how to insert to myDataTable > LDAP_Data
}
how can I insert the new Data from LDAP to the new Column?
Thanks
If you add a row to a DataTable you have to add a row which columns match you table. This is why you get back a row if you call DataTable.Add().
Here an example how to add new rows:
static void Main(string[] args)
{
DataTable dt = new DataTable(); // Create a example-DataTable
dt.Columns.Add(new DataColumn() { ColumnName = "Name", DataType = typeof(string) }); // Add some columns
dt.Columns.Add(new DataColumn() { ColumnName = "Id", DataType = typeof(int) });
// Let's fill the table with some rows
for (int i = 0; i < 20; i++) // Add 20 Rows
{
DataRow row = dt.Rows.Add(); // Generate a row
row["Id"] = i; // Fill in some data to the row. We can access the columns which we added.
row["Name"] = i.ToString();
}
// Let's see what we got.
for (int i = 0; i < dt.Columns.Count; i++) // Loop through all columns
{
Console.Write(dt.Columns[i].ColumnName + ";"); // Write the ColunName to the console with a ';' a seperator.
}
Console.WriteLine();
foreach (DataRow r in dt.Rows) // Generic looping through DataTable
{
for (int i = 0; i < dt.Columns.Count; i++) // Loop through all columns
{
Console.Write(r[i] + ";");
}
Console.WriteLine();
}
}
You can do it by using the NewRow method:
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
DataRow row = modiTable.NewRow();
row["EMAIL"] = myLDAPData;
//You might want to specify other values as well
}
Or you can use the Add() method, as suggested in kara's answer.
myDataTable.Columns.Add(new DataColumn("LDAP_Data"));
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
var row = myDataTable.NewRow()
row["LDAP_Data"] = YOUR_DATA;
myDataTable.Rows.Add(row);
}
I'm using datatable that has two columns of text data, I just want to do abbreviations expanding for each row, so I used Dictionary and here it is a sample of my code:
private void ExpandWords()
{
DataTable DT = new DataTable();
DataRow Row;
DT.Columns.Add(new System.Data.DataColumn("Name", typeof(string)));
DT.Columns.Add(new System.Data.DataColumn("Label", typeof(string)));
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("emp", "employee");
dict.Add("dep", "department");
for (int i = 0; i < dataGridView6.Rows.Count; i++)
{
Row = DT.NewRow();
foreach(KeyValuePair<string,string> rep in dict)
{
Row[0] = dataGridView6.Rows[i].Cells[0].Value.ToString().Replace (rep.Key, rep.Value);
Row[1] = dataGridView6.Rows[i].Cells[1].Value.ToString().Replace (rep.Key, rep.Value);
}
DT.Rows.Add(Row);
dataGridView7.DataSource = DT;
}
it can be run without exceptions but it doesn't work
Why do you enumerate the dictionary in the loop of the grid-rows? Just lookup the key.
You also have to add each row in the loop, not outside, otherwise you just add the last row:
for (int i = 0; i < dataGridView6.Rows.Count; i++)
{
Row = DT.NewRow();
string abbrCell1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
string abbrCell2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
Row[0] = dict[abbrCell1];
Row[1] = dict[abbrCell2];
DT.Rows.Add(Row);
}
Edit If you want to replace all abbreviated words in the string of the datagrid cells with the not-abbreviated word in the dictionary you can use this code:
// in the loop
Row = DT.NewRow();
string abbrCell1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
string abbrCell2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
IEnumerable<string> unabbrWords1 = abbrCell1.Split()
.Select(w => dict.ContainsKey(w) ? dict[w] : w);
IEnumerable<string> unabbrWords2 = abbrCell2.Split()
.Select(w => dict.ContainsKey(w) ? dict[w] : w);
Row[0] = string.Join(" ", unabbrWords1);
Row[1] = string.Join(" ", unabbrWords2);
DT.Rows.Add(Row);
You should change it a bit otherwise you'll have same value overwritten in loop:
var value1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
var value2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
foreach (KeyValuePair<string, string> rep in dict)
{
value1 = value1.Replace(rep.Key, rep.Value);
value2 = value2.Replace(rep.Key, rep.Value);
}
DT.Rows.Add(value1, value2);
You're also missing DataBind() if you're using Web Forms at the end
dataGridView7.DataSource = DT;
dataGridView7.DataBind();
mz
In normal WinForm application you can do that:
DataTable dataTable = new DataTable();
dataTable = dataGridRecords.DataSource;
but how to do that with the WPF datagrid?
dataTable = dataGridRecords.ItemsSource;
won't work either.
In WPF you don't do this
DataGrid.ItemsSource = DataTable;
Instead you do
DataGrid.ItemsSource = DataTable.AsDataView();
In order to get DataTable back you can do something like this
public static DataTable DataViewAsDataTable(DataView dv)
{
DataTable dt = dv.Table.Clone();
foreach (DataRowView drv in dv)
dt.ImportRow(drv.Row);
return dt;
}
DataView view = (DataView) dataGrid.ItemsSource;
DataTable table = DataViewAsDataTable(view)
You don't need the DataViewAsDataTable method. Just do the following:
DataTable dt = ((DataView)dataGrid1.ItemsSource).ToTable();
try this
public static DataTable DataGridtoDataTable(DataGrid dg)
{
dg.SelectAllCells();
dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, dg);
dg.UnselectAllCells();
String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
string[] Lines = result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
for (int i = 0; i < Cols; i++)
dt.Columns.Add(Fields[i].ToUpper(), typeof(string));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0)-1; i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
{
Row[f] = Fields[f];
}
dt.Rows.Add(Row);
}
return dt;
}
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();
}