My problem is that i have a foreach loop that saves every row of data into a List and then creates a TXT from the list, the problem is that my data is saved into the TXT in this form:
["ROW1","DATA1","DATA2","DATA3","ROW2","DATA4","DATA5","DATA6"]
And i want to make my txt to have the data like this:
[["ROW1","DATA1","DATA2","DATA3"],["ROW2","DATA4","DATA5","DATA6"]]
Getting each row into a separate aditional brackets brackets("[]"), how can i do this without using another List?
This is my Foreach Loop:
List<string> listaprocedure = new List<string>();
foreach (DataRow dato in myTable.Rows)
{
foreach (DataColumn datoC in myTable.Columns)
{
listaprocedure.Add(dato[datoC].ToString());
}
}
json4 = JsonConvert.SerializeObject(procedimiento2);
System.IO.File.WriteAllText(#"C:\procedure.txt", json4);
You can manually iterate through rows, writing each one as you have read it, then add , after it (except last row). Plus add [ and ] at the beginning and end.
Quite ugly, but can help if you deal with really big table.
But the best option is to populate List<List<string>> (or string[,]).
Anyway here is working example:
using (var reader = File.CreateText("C:\\procedure.txt"))
{
// Starting outer json array
reader.WriteLine("[");
for (var rowIndex = 0; rowIndex < myTable.Rows.Count; rowIndex++)
{
var row = myTable.Rows[rowIndex];
var rowValues = new List<string>(); // can be reused if needed
foreach (DataColumn column in myTable.Columns)
rowValues.Add(row[column].ToString());
var jsonRow = JsonConvert.SerializeObject(rowValues);
// Write current row
reader.Write(jsonRow);
// Add separating comma
if (rowIndex != myTable.Rows.Count - 1)
reader.WriteLine(",");
}
// End outer json array
reader.WriteLine("]");
}
Given your sample data, this works:
var query =
from dr in myTable.Rows.OfType<DataRow>()
from dc in myTable.Columns.OfType<DataColumn>()
group dr[dc].ToString() by dc.Ordinal / 4;
var json4 = JsonConvert.SerializeObject(query);
This gives me:
[["ROW1","DATA1","DATA2","DATA3"],["ROW2","DATA4","DATA5","DATA6"]]
I used this code to initialize my data:
var myTable = new DataTable();
myTable.Columns.Add("A1", typeof(string));
myTable.Columns.Add("A2", typeof(string));
myTable.Columns.Add("A3", typeof(string));
myTable.Columns.Add("A4", typeof(string));
myTable.Columns.Add("B1", typeof(string));
myTable.Columns.Add("B2", typeof(string));
myTable.Columns.Add("B3", typeof(string));
myTable.Columns.Add("B4", typeof(string));
myTable.Rows.Add("ROW1", "DATA1", "DATA2", "DATA3", "ROW2", "DATA4", "DATA5", "DATA6");
Related
I'm reading each line of a file into an array of strings:
string[] lines = File.ReadAllLines(filePath);
Each line is separated by a tab
lines[0] = "John\tPizza\tRed\tApple"
I want to load this string array into a DataGridView. I tried the following:
DataTable dt = new DataTable();
dt.Columns.Add("Name",typeof(string));
dt.Columns.Add("Food",typeof(string));
dt.Columns.Add("Color",typeof(string));
dt.Columns.Add("Fruit",typeof(string));
foreach(string s in lines)
{
dt.Rows.Add(s);
}
myDataGridView.DataSource = dt;
The problem is that all the strings are loaded to the first column of the DataGrid:
I need them to be separated like this:
You will need to split the lines on the tab. Here is an example:
foreach (string s in lines)
{
var splitLine = s.Split("\t");
dt.Rows.Add(splitLine);
}
I also found some documentation that says you need to create a new row with the NewRow() method and then fill out each column value. Here is what that would look like:
foreach (string s in lines)
{
// Split the line
var splitLine = s.Split("\t");
// Create the new row
var newRow = dt.NewRow();
newRow["Name"] = splitLine[0];
newRow["Food"] = splitLine[1];
newRow["Color"] = splitLine[2];
newRow["Fruit"] = splitLine[3];
// Add the row to the table
dt.Rows.Add(newRow);
}
How do i populate this dataTable with array of strings? Im using this template but i can only add data hardcoded... I have an string[]values which contains my data and that should be added to the datatable. I think its quite easy but i don't see it. i've been trying to loop through it but that doens't seem to work? Think im missing a crucial step.
I've created a my datatable here :
DataTable dt = new DataTable() { TableName = "MBR" };
Adding the columns to it
string[] columns = new string [l];
for (int i = 0; i < l; i++)
{
columns[i] = tags[i];
}
for (int i = 0; i < timeStamps.Count(); i++)
{
foreach (var item in tagCollection)
{
if (timeStamps[i].Date == item.time)
{
Console.WriteLine(item.time + " " + item.name );
}
}
}
dt.Columns.AddRange(columns.Select(c => new DataColumn(c.ToString())).ToArray());
And this i used in the template my collegue is working with and we need to provide the data here
var rows = new string[][]
{
new string[] {"1", "2", "false" },
new string[] { "test", "10000", "19.9" },
};
foreach (var row in rows)
{
dt.Rows.Add(row);
}
//Convert datatable to dataset and add it to the workbook as worksheet
ds.Tables.Add(dt);
workbook.Worksheets.Add(ds);
I've got many columns like 500+. And i need to add to each column a piece of data which i get from my string[]. which can contains 10 or 500+ records it depends. I need to add each record to a row. My columns are already working in this thing. I just need a way to add multiple Arrays to the table
This works for me:
DataTable dt = new DataTable() { TableName = "MBR" };
dt.Columns.Add(new DataColumn("A", typeof(string)));
dt.Columns.Add(new DataColumn("B", typeof(string)));
dt.Columns.Add(new DataColumn("C", typeof(string)));
var rows = new string[][]
{
new string[] {"1", "2", "false" },
new string[] { "test", "10000", "19.9" },
};
foreach (var row in rows)
{
dt.Rows.Add(row);
}
That gives me:
Here's how you might fill a datatable from a file of people:
var people = new DataTable();
people.Columns.Add("Name");//string
people.Columns.Add("Age", typeof(int));
people.Columns.Add("HireDate", typeof(DateTime));
people.Columns.Add("IsManager", typeof(bool));
foreach(var line in File.ReadLines("people.csv")){
var bits = line.Split(',');
dt.Rows.Add(new object[]{
bits[0], //Name
int.Parse(bits[1]), //Age
DateTime.Parse(bits[2]), //HireDate
bool.Parse(bits[3]) //IsManager
});
}
It would, of course, be preferable to use some library like Csvhelper if you're reading from a CSV - it can read into DataTables directly and is a lot more sophisticated than this example. This is just to show the process of "make a datatable, add columns, add rows by providing values for columns"
It would be better to create a strongly typed datatable for this:
Add a new DataSet type of file to your project and goive it a good name
Open it, right click the surface, choose Add DataTable, give it a sensible name
Right click the table, choose Add Column .. add a column and set its name, data type, default value etc...
Repeat until all columns are done
Using this in your code is mostly the same as above, except you make an instance of the table. It is an inner class so you create it using the name of the dataset too:
var dt = new YourDataSetNameHere.YourDataTableNameHere_DataTable();
//the columns are already added, you don't need to add them
foreach(var line in ...){
...
dt.Add_YourDataTableNameHere_Row(
bits[0], //Name
int.Parse(bits[1]), //Age
DateTime.Parse(bits[2]), //HireDate
bool.Parse(bits[3]) //IsManager
);
}
They're a lot nicer to use than regular weakly typed datatables
I'm trying to link data from my db (sqlite) to my textboxes, but I don't know exactly how...
Here's what i'm trying:
private void btnUpdate_Click(object sender, EventArgs e)
{
con.Open();
adapter = new SQLiteDataAdapter("SELECT PRECO_PRODUTO FROM INGREDIENTES WHERE NOME_PRODUTO='"+listProdutos.SelectedIndex+"'", con);
adapter.Fill(populate);
List<DataTable> precoIng = new List<DataTable>();
precoIng.Add(populate.Tables[0]);
con.Close();
tbPrecoProduto.Text = precoIng[0]; //error here
}
I think I need a way to convert the SQLiteDataTable to a string? I'm new on db stuffs. This is my table and this is my form design, if helps...
It seems as if you're trying to set the text of the TextBox to a DataTable. This doesn't quite make sense, as the type DataTable isn't the same as a string. You'd first have to extract the data out of your table like that:
var builder = new StringBuilder ();
foreach (var rowObject in precoIng [0].Rows)
{
var row = (DataRow) rowObject;
var id = row ["ID_PRODUTO"].ToString ();
var name = row ["NOME_PRODUTO"].ToString ();
var price = row ["PRECO_PRODUTO"].ToString ();
var count = row ["QNT_PRODUTO"].ToString ();
builder.AppendLine ($"Id: {id}; Name: {name}; Price: {price}; Count: {count}");
}
tbPrecoProduto.Text = builder.ToString ();
You can of course shorten this if you only want for example the price:
var builder = new StringBuilder ();
foreach (var rowObject in precoIng [0].Rows)
{
var row = (DataRow) rowObject;
var price = row ["PRECO_PRODUTO"].ToString ();
builder.AppendLine (price);
}
tbPrecoProduto.Text = builder.ToString ();
And, btw, precoIng[0] will always be the same as populate.Tables[0].
Alternatively you could write an extension method like that:
public static string GetData (this DataTable table)
{
var builder = new StringBuilder ();
foreach (DataRow row in table.Rows)
foreach (DataColumn column in table.Columns)
builder.Append (column.ColumnName).Append (": ").Append (row [column]).Append ("; ");
return builder.ToString ();
}
And then call precoIng[0].GetData() to get the data as a string.
If you want to be able to filter the data to get printed, you could do something like this:
public static string GetData (this DataTable table, List <string> columns = null)
{
var builder = new StringBuilder ();
foreach (DataRow row in table.Rows)
if (columns == null)
foreach (DataColumn column in table.Columns)
builder.Append (column.ColumnName).Append (": ").Append (row [column]).Append ("; ");
else
foreach (var column in columns)
builder.Append (column).Append (": ").Append (row [column]).Append ("; ");
return builder.ToString ();
}
I do however feel as if you don't want the data of your whole table as a string, but rather want the data to certain ids or something. To help you with this, however, I'd need more precise information.
Ok, so it seems as if what you actually want is something like this:
var preco = precoIng.FirstOrDefault ()?.Rows.Cast <DataRow> ().FirstOrDefault ()? ["PRECO_PRODUTO"]?.ToString () ?? "";
This question already has answers here:
How do I loop through items in a list box and then remove those item?
(8 answers)
Closed 9 years ago.
List<String> employeeTimings;
public string[] sTime = {"0000", "0030", "0100", "0130", "0200", "0230", "0300", "0330", "0400", "0430", "0500", "0530", "0600", "0630", "0700", "0730", "0800", "0830", "0900", "0930", "1000", "1030", "1100", "1130", "1200",
"1230", "1300", "1330", "1400", "1430", "1500", "1530", "1600", "1630", "1700", "1730", "1800", "1830", "1900", "1930", "2000", "2030", "2100", "2130", "2200", "2230", "2300", "2330"};
employeeTimings = new List<String>(sTime);
int i=0;
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Location", typeof(string)));
dt.Columns.Add(new DataColumn("Station", typeof(string)));
foreach (DataColumn dc in dt.Columns)
{
dt.Columns.Add(employeeTimings[i], typeof(string));
i++;
}
SchedulingTableDGV.DataSource = dt;
i get an error "Collection was modified; enumeration operation may not execute." how can i solve this?
You cannot add or remove from the collection you are iterating with a foreach. You need to perform adding or removing actions outside of the foreach.
foreach (DataColumn dc in dt.Columns)
{
dt.Columns.Add(employeeTimings[i], typeof(string)); // Problem.
i++;
}
Try this:
foreach (var timing in employeeTimings)
{
dt.Columns.Add(timing, typeof(string));
}
You can't modify a collection you are looping over with foreach. The solution in your case is pretty simple: Since you do not use dc inside the loop, why not use a normal for loop, like:
int length = dt.Columns.Length;
for (int i = 0; i < length; i++)
{
dt.Columns.Add(employeeTimings[i], typeof(string));
}
With LINQ you can do:
foreach (DataColumn dc in dt.Columns.OfType<DataColumn>().ToArray())
{
dt.Columns.Add(employeeTimings[i], typeof(string));
i++;
}
You are modifying the collection dt.Columns with the Add method while you are iterating over it:
foreach (DataColumn dc in dt.Columns)
{
dt.Columns.Add(employeeTimings[i], typeof(string));
i++;
}
Apart from not adding all timing strings this modifies the collection you are adding the columns to.
You should enumerate employeeTimings and add the columns like:
foreach(string s in employeeTimings)
{
dt.Columns.Add(s, typeof(string));
}
I guess your true intentions are to add the full employeeTimings list to the datatable columns
If this is right then you should loop on the list not on the columns
foreach (string s in employeeTimings)
dt.Columns.Add(s, typeof(string));
I am importing data from csv file, sometimes there are column headers and some times not the customer chooses custom columns(from multiple drop downs)
my problem is I am able to change the columns type and name but when I want to import data row into cloned table it just adds rows but no data with in those rows. If I rename the column to old values it works, let's say column 0 name is 0 if I change that to something else which I need to it won't fill the row below with data but If I change zero to zero again it will any idea:
here is my coding:
#region Manipulate headers
DataTable tblCloned = new DataTable();
tblCloned = tblDataTable.Clone();
int i = 0;
foreach (string item in lstRecord)
{
if (item != "Date")
{
var m = tblDataTable.Columns[i].DataType;
tblCloned.Columns[i].DataType = typeof(System.String);
tblCloned.Columns[i].ColumnName = item;
}
else if(item == "Date")
{
//get the proper date format
//FillDateFormatToColumn(tblCloned);
tblCloned.Columns[i].DataType = typeof(DateTime);
tblCloned.Columns[i].ColumnName = item;
}
i++;
}
tblCloned.AcceptChanges();
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.ImportRow(row);
}
tblCloned.AcceptChanges();
#endregion
in the second foreach loop when it calls to import data to cloned table it adds empty rows.
After couple of tries I came up with this solution which is working:
foreach (DataRow row in tblDataTable.Rows)
{
int x = 0;
DataRow dr = tblCloned.NewRow();
foreach (DataColumn dt in tblCloned.Columns)
{
dr[x] = row[x];
x++;
}
tblCloned.Rows.Add(dr);
//tblCloned.ImportRow(row);
}
but I will accept Scottie's answer because it is less code after all.
Instead of
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.ImportRow(row);
}
try
foreach (DataRow row in tblDataTable.Rows)
{
tblCloned.LoadDataRow(row.ItemArray, true);
}