The file im trying to read is looking like this:
123,123,123h123m,123,123,123
And I have following code to try to read that:
public DataTable DataTableFromTextFile(string location, char delimiter = ',')
{
DataTable result;
string[] LineArray = File.ReadAllLines(path);
result = FormDataTable(LineArray, delimiter);
return result;
}
private static DataTable FormDataTable(string[] LineArray, char delimiter)
{
DataTable dt = new DataTable();
AddColumnToTable(LineArray, delimiter, ref dt);
AddRowToTable(LineArray, delimiter, ref dt);
return dt;
}
private static void AddRowToTable(string[] valueCollection, char delimiter, ref DataTable dt)
{
for (int i = 1; i < valueCollection.Length; i++)
{
string[] values = valueCollection[i].Split(delimiter);
DataRow dr = dt.NewRow();
for (int j = 0; j < values.Length; j++)
{
dr[j] = values[j];
}
dt.Rows.Add(dr);
}
}
private static void AddColumnToTable(string[] columnCollection, char delimiter, ref DataTable dt)
{
string[] columns = columnCollection[0].Split(delimiter);
foreach (string columnName in columns)
{
DataColumn dc = new DataColumn(columnName, typeof(string));
}
}
but it does not seem to work yet. I have tried changing some things but it then went to adding blank spaces into the DataGridView (which is called infoTabelle).
Anyone able to help me fix my problem?
****EDIT
Got it all fixed now. I changed the method where it was to put my seperated text into the DataGridView. Working like a charm now.**
You are looking for something like this:
// Simple: quotation "..." e.g. "123,456",789 is not implemented
private static DataTable FromCsvSimple(string path, char delimiter = ',') {
// Try avoiding ReadAllLines; use ReadLines
// Where - let's skip empty lines (if any)
var lines = File
.ReadLines(path)
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line => line.Split(delimiter));
DataTable result = new DataTable();
foreach (string[] items in lines) {
// Do we have any columns to add?
for (int c = 0; c < items.Length; ++c)
while (c >= result.Columns.Count)
result.Columns.Add();
result.Rows.Add(items);
}
return result;
}
...
DataTable myTable = FromCsvSimple(#"c:\MyCsv.csv", ';');
Related
I am trying to convert the content of a Clipboard to Datatable.
I was trying to use the following code from the URL: http://www.seesharpdot.net/?p=221
private void PasteFromExcel()
{
DataTable tbl = new DataTable();
tbl.TableName = "ImportedTable";
List<string> data = new List<string>(ClipboardData.Split('\n'));
bool firstRow = true;
if (data.Count > 0 && string.IsNullOrWhiteSpace(data[data.Count - 1]))
{
data.RemoveAt(data.Count - 1);
}
foreach (string iterationRow in data)
{
string row = iterationRow;
if (row.EndsWith("\r"))
{
row = row.Substring(0, row.Length - "\r".Length);
}
string[] rowData = row.Split(new char[] { '\r', '\x09' });
DataRow newRow = tbl.NewRow();
if (firstRow)
{
int colNumber = 0;
foreach (string value in rowData)
{
if (string.IsNullOrWhiteSpace(value))
{
tbl.Columns.Add(string.Format("[BLANK{0}]", colNumber));
}
else if (!tbl.Columns.Contains(value))
{
tbl.Columns.Add(value);
}
else
{
tbl.Columns.Add(string.Format("Column {0}", colNumber));
}
colNumber++;
}
firstRow = false;
}
else
{
for (int i = 0; i < rowData.Length; i++)
{
if (i >= tbl.Columns.Count) break;
newRow[i] = rowData[i];
}
tbl.Rows.Add(newRow);
}
}
this.WorkingTableElement.WorkingTable = tbl;
tableImportGrid.DataSource = null;
tableImportGrid.RefreshDataSource();
tableImportGrid.DataSource = tbl;
tableImportGrid.RefreshDataSource();
tableImportGrid.Refresh();
}
But the following part of the code:
List<string> data = new List<string>(ClipboardData.Split('\n'));
is causing me some trouble. I understand that the ClipboardData should already refer to Clipboard content, but I tried to do that with DataObject, but this did not work.
Maybe someone has a good idea how to implement this or some guidelines how to go forward. I have not been exposed to C# much and mostly done my programming in Python.
Split is a function available to the String class, so I'd assume ClipboardData should be a string.
This can be retrieved by calling: System.Windows.Forms.Clipboard.GetText(), rather than Clipboard.GetDataObject(), which I assume you are calling at the moment.
On calling the GetText() method, the selected cells are converted to their textual representation, with each cell separated by a space (or tab?), and each line separated by a newline character ('\n'). Something like this:
1 2 3 4 5 6
a b c d e f
TL;DR; you should call Clipboard.GetText(), rather than Clipboard.GetDataObject().
I have searched several threads and cannot seem to find a C# solution. I have a string list and a datatable in C#. I need to be able to iterate through my data table's rows, then iterate through my list to obtain a header value (row[0]) and use that to assign to a variable.
Here is what I have so far:
private void setInformation(DataTable dt, List<string> text)
{
foreach(DataRow row in dt.Rows)
{
if (dt.Rows.IndexOf(row) != 0)
{
for (int i = 0; i <= text.Count; i++)
{
string s;
string ValueNeeded;
s = text[i];
ValueNeeded = dt.Columns.IndexOf(text).ToString();
//needs to be the current dt rows value for the header /
//row(0) with that string identifier
//in VB its something like
//DT.Rows(0).Item(text).ToString
}
}
}
}
All I have is the first row's string value; as I iterate through the DT, I'll need to get that "cell's value by leveraging the first rows value. I need the current cell each time.
You can get the value of any cell by referencing the row[index] and the column name string
string xyz= dt.Rows[0]["columnName"].ToString();
OK so assuming the List<string> text parameter contains values of the first row (not the column names) in your DataTable, and you're looking to get the corresponding cell in each row, something like this should work (haven't tested it)
private void setInformation(DataTable dt, List<string> text)
{
var cache = new Dictionary<string, int>(); //cache column numbers
foreach(var entry in text) cache[entry] = getColumnNumberByValue(dt, entry);
for(int i=1; i < dt.Rows.Count; i++)
{
foreach(var entry in text)
{
var columnIndex = cache[entry];
if(columnIndex != -1)
{
var valueNeeded = dt.Rows[i][columnIndex].ToString();
}
}
}
}
private int getColumnNumberByValue(DataTable dataTable, string text)
{
for(int i=0; i < dataTable.Columns.Count; i++)
{
if(dataTable.Rows[0][i].ToString() == text) return i;
}
return -1;
}
I would like to take the schema of a DataTable and import that into a comma separated string. So far I have the code shown below but I would really like this to be a one-liner solution if that is possible.
List<string> columns = new List<string>();
foreach (var column in MyDataTable.Columns)
columns.Add(column.ToString());
string schema = string.Join(",", columns);
Is there a more concise way to do this?
This previous post answers it nicely.
https://stackoverflow.com/a/28503521/1572750
public static string DataTableToCSV(this DataTable datatable, char seperator)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < datatable.Columns.Count; i++)
{
sb.Append(datatable.Columns[i]);
if (i < datatable.Columns.Count - 1)
sb.Append(seperator);
}
sb.AppendLine();
foreach (DataRow dr in datatable.Rows)
{
for (int i = 0; i < datatable.Columns.Count; i++)
{
sb.Append(dr[i].ToString());
if (i < datatable.Columns.Count - 1)
sb.Append(seperator);
}
sb.AppendLine();
}
return sb.ToString();
}
Usage
MyDataTable.ToCsvFile("mycsv.csv")
... code ...
Note: this will be slightly slower than a few other examples but it is compliant with proper escaping for CSV as in RFC 4180
public static class CsvFileEx
{
public static void ToCsvFile(this DataTable dt, string filename, bool includeHeaders = true)
{
dt.ToCsvLines(includeHeaders: includeHeaders).WriteAsLinesToFile(filename);
}
public static IEnumerable<string> ToCsvLines(this DataTable dt, string seperator = #"""", bool includeHeaders = true)
{
if (includeHeaders)
yield return string.Join(seperator, dt.Columns
.Cast<DataColumn>()
.Select(dc => #"""" + dc.ColumnName.Replace(#"""", #"""""") + #""""));
foreach (var row in dt.Rows.Cast<DataRow>())
yield return string.Join(seperator, row.ItemArray
.Select(i => #"""" + (i ?? "").ToString().Replace(#"""", #"""""") + #""""));
}
public static void WriteAsLinesToFile(this IEnumerable<string> lines, string filename)
{
using (var writer = new StreamWriter(filename))
foreach (var line in lines)
writer.WriteLine(line);
}
}
I need help :-)
I have a file.txt with content like below :
00001 JhonKey 023301923
00002 Hercules 023039910
I want to load this file to datagridview through datatable and the result should be saved in a datagrid like below :
COL1 | COL2 | COL3
-----------------------------------
00001 | JhonKey | 023301923
00002 | Hercules | 023039910
I'm trying this code :
using (StreamReader SR = new StreamReader(txtFileName))
{
int row = 0;
string line;
while ((line = SR.ReadLine())!= null)
{
string[] Columns = line.Split(',');
dataGridView2.Rows.Add();
for (int i = 0; i < Columns.Length; i++)
{
dataGridView2[i, row].Value = Columns[i];
}
row++;
}
}
but the result is not as expected. It looks wrong, everything is wirtten in the first column, shown below :
COL1 | COL2 | COL3
--------------------------------------------------------
00001 JhonKey 023301923 | |
00002 Hercules 023039910 | |
Take look on line string[] Columns = line.Split(',');
You try to split line by comma, but no commas in the file. Try split by space.
Like
string[] Columns = line.Split(' ');
Or
string[] Columns = line.Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries)
using System.Data;
using System.IO;
public class FromYourFileToGrid
{
public static DataTable DataTableFromYourTextFile(string directory, char splitter=',')
{
DataTable result;
string[] LineArray = File.ReadAllLines(directory);
result = FormDataTable(LineArray, splitter);
return result;
}
private static DataTable FormDataTable(string []LineArray, char splitter)
{
bool IsHeaderSet = false;
DataTable dt = new DataTable();
AddColumnToTable(LineArray, splitter, ref dt);
AddRowToTable(LineArray, splitter, ref dt);
return dt;
}
private static void AddRowToTable(string []valueCollection, char splitter, ref DataTable dt)
{
for (int i = 1; i < valueCollection.Length; i++)
{
string[] values = valueCollection[i].Split(splitter);
DataRow dr = dt.NewRow();
for (int j = 0; j < values.Length; j++)
{
dr[j] = values[j];
}
dt.Rows.Add(dr);
}
}
private static void AddColumnToTable(string []columnCollection, char splitter, ref DataTable dt)
{
string[] columns = columnCollection[0].Split(splitter);
foreach (string columnName in columns)
{
DataColumn dc = new DataColumn(columnName, typeof(string));
dt.Columns.Add(dc);
}
}
}
You added coloumns and rows in the same loop. This is false way to create grid. You should add rows and coloumns in the differents method.Above class will create your grid and then add coloumn, rows to your grid.You can call above class's methods with :
dataGridView1.DataSource = FromYourFileToGrid.DataTableFromYourTextFile("file.txt", '|');
And then your datas will be added coloumns and rows correctly. And u should read more and more tutorial. Because this questions were asked in Stackoverflow.You can read this Reading from .txt file, then exporting data to DataGridView question. I hope this code help you.
I am trying to convert an array of strings to a DataGridView with little success so far. The method below is called for that purpose, but it doesn't seem to return any table.
While debugging I can see that I fetch the correct values from cont.GetAllEmployee() but when the debug goes to ConvertListToDataTable(list) the debugging does not show that method which is something unusual.
This is my current code :
private DataTable ConvertListToDataTable(List<WindowsFormsApplication1.ServiceReference1.ArrayOfString> list)
{
DataTable table = new DataTable();
List<string> columnNames = list[0];
for (int i = 0; i < columnNames.Count; i++)
{
table.Columns.Add(columnNames[i].ToString());
}
foreach (var array in list)
{
table.Rows.Add(array);
}
return table;
}
List <WindowsFormsApplication1.ServiceReference1.ArrayOfString> list = cont.GetAllEmployee();
dataGridView.DataSource = ConvertListToDataTable(list);
New rows must be instanciated by DataTable.NewRow() method to obtain new DataRow with the same scheme as DataTable.
private DataTable ConvertListToDataTable(List<WindowsFormsApplication1.ServiceReference1.ArrayOfString> list)
{
DataTable table = new DataTable();
List<string> columnNames = list[0];
for (int i = 0; i < columnNames.Count; i++)
{
table.Columns.Add(columnNames[i].ToString());
}
foreach (var array in list)
{
var NewRow = table.NewRow();
for(int i = 0; i < columnNames.Count)
{
NewRow[columnNames[i]] = array[i];
}
table.Rows.Add(NewRow);
}
return table;
}
List <WindowsFormsApplication1.ServiceReference1.ArrayOfString> list = cont.GetAllEmployee();
dataGridView.DataSource = ConvertListToDataTable(list);
dataGridView.DataBind();