How to add an element with comma to my csv? - c#

Hello I have a code like this:
public string dataToCsv(Dictionary<string, List<string>> data, long qty, string segment)
{
string dateToday = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");
string user = Environment.UserName;
var pathToCsv = "C:/Users/" + user + "/Documents/"+ segment + "-" + dateToday + ".csv";
StringBuilder sb = new StringBuilder();
String csv = String.Join(",",
data.Select(d => d.Key));
sb.Append(csv + Environment.NewLine);
for (int i = 0; i < qty; i++) {
String csv1 = String.Join(",",
data.Select(d => string.Join(",", d.Value.Skip(i).Take(1))));
sb.Append(csv1 + Environment.NewLine);
}
System.IO.File.WriteAllText(pathToCsv, sb.ToString());
return pathToCsv;
}
Works pretty fine but when an element value has a comma. That value is separated and lag the columns of the csv. I need if the element has a comma put with them in the csv. Is there any way to do this?
Maybe if I change the separator from the dictionary but donĀ“t know how to do it.
My Dictionary has a list of strings.

Related

Accessing List values when having few strings inside a value

So I have the following code:
void ReadFromCsv()
{
using (var reader = new StreamReader(#"d:\test.csv", Encoding.Default))
{
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
}
Console.WriteLine(listA);
}
}
which is reading from my csv file and an example of a line I get is:
50,2,10,201,10,9090339,24-OCT-21 09.38.38.679000 AM,123456789,24/10/2021 09:39:23,22/10/2021 09:39:37,Sm123456789-SM-20211031-VSR-000123.pdf,,,,,26/01/2022 13:08:58,,2,,0
first of all, why are there many commas around the end of the line?
second of all, what if I wanted to access the value "10" (which is the 5th value ) of that string line, is that possible?,
or going further, my task is to check for that 5th value and if its 5 for example, I'd want to take every row with 5thvalue=5 and create a csv for them, if 5thvalue=10 I want to create a csv for those records, and so on. but one task at a time, how do I access that value?
1: commas around the end of the line mean first item of lines is empty ""
2: you can get 5th value as below:
string _list = "50,2,10,201,10,9090339,24-OCT-21 09.38.38.679000 AM,123456789,24/10/2021 09:39:23,22/10/2021 09:39:37,Sm123456789-SM-20211031-VSR-000123.pdf,,,,,26/01/2022 13:08:58,,2,,0";
var fiveIndex = _list.Split(',')[4];
3:
then you can get list of lines that have a value of fiveIndex
var result =_list.Split(',').Select((v, i) => new { value = v, index = i }).Where(item => item.value == fiveIndex);
In your example, line 3 and line 5 have a value of 10(index=2, index=4). Then you can save these lines in csv file.
ended up doing:
string chargeMonth = DateTime.Now.ToString("yyyyMM");
var fileCreationDate = DateTime.Now.ToString("yyyyMMdd");
string fileCreationTime = DateTime.Now.ToString("HHmmss");
string constVal = "MLL";
string fileType = "HIYUV-CHEVRA";
string[] values;
string header, sumRow;
string line, compId;
string inputFile = "records.CSV";
Dictionary<string, System.IO.StreamWriter> outputFiles = new Dictionary<string, System.IO.StreamWriter>();
using (System.IO.StreamReader file = new System.IO.StreamReader("D:\\" + inputFile, Encoding.Default))
{
header = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
values = line.Split(",".ToCharArray());
compId = values[3];
if (!outputFiles.ContainsKey(compId))
{
string outputFileName = constVal + "-" + fileType + "-" + (String.Format("{0:00000}", Int32.Parse(compId))) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime + ".CSV";
outputFiles.Add(compId, new System.IO.StreamWriter("D:\\" + outputFileName));
outputFiles[compId].WriteLine(header);
}
outputFiles[compId].WriteLine(line);
}
}
foreach (System.IO.StreamWriter outputFile in outputFiles.Values)
{
outputFile.Close();
}
and the mission is done.

Search anywhere in DataGridView

I'm trying to write a program which will made a datagridview based on a text file. See code below.
private void Button1_Click(object sender, EventArgs e)
{
ls_datenTabelle.Clear();
ls_datenTabelle.Columns.Clear();
string kdstr = (comboBox1.SelectedItem.ToString());
string fileName = "ls.txt";
string fileName2 = kdstr + ".txt";
string sourcePath = #"H:\import_directoy\customer\" + kdstr;
string tempPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string dmitempPath = #"program_name\";
string targetPath = Path.Combine(tempPath, dmitempPath);
File.Delete(targetPath + "output");
string sourceFileName = Path.Combine(sourcePath, fileName);
string destFile = Path.Combine(targetPath, fileName2);
Directory.CreateDirectory(targetPath);
File.Copy(sourceFileName, destFile, overwrite: true);
using (var output = File.Create(targetPath + "output"))
{
foreach (var file in new[] { "H:\\directoy1\\directoy2\\index.config", destFile })
{
using (var input = File.OpenRead(file))
{
input.CopyTo(output);
}
}
}
string[] raw_text = File.ReadAllLines(targetPath + "output", Encoding.Default);
string[] data_col = null;
int x = 0;
foreach (string text_line in raw_text)
{
data_col = text_line.Split(';');
if (x == 0)
{
for (int i = 0; i <= data_col.Count() - 1; i++)
{
ls_datenTabelle.Columns.Add(data_col[i]);
}
x++;
}
else
{
ls_datenTabelle.Rows.Add(data_col);
}
}
ls_dataGridView.DataSource = ls_datenTabelle;
this.Controls.Add(ls_dataGridView);
ls_dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
ls_dataGridView.AllowUserToAddRows = false;
}
Now I want to search all over this datatable/datagridview and I will show the rows if the search function found the searchvalue in any column.
But I dodn't know how. The header of the table could change every day. So this code doesn't work for me:
public void findingValue(object sender, EventArgs e)
{
string searchValue = textBox1.Text;
DataView data = ls_datenTabelle.DefaultView;
ls_dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
data.RowFilter = string.Format("Name like '" + searchValue + "%'");
}
The program will find only rows where the searchValue is in the "Name" column and not one of the other 18 (umknown) columns.
Here is an example which uses Linq to loop over the columns in the DataTable:
if (searchValue == "") data.RowFilter = "";
else
{
var cols = ls_datenTabelle.Columns.Cast<DataColumn>().Select(x => x.ColumnName);
var filter = cols.Select(x => x + " like '" + searchValue + "%'")
.Aggregate((a, b) => a + " OR " + b);
data.RowFilter = filter;
}
First we collect the column names and then we build a filter from them, each part connectd with a OR clause.
You could also use Join or good old loops..
Note that this assumes that all columns allow searching for strings, i.e. no numbers etc..
If this is not true you will want to either pick only the string columns or change the filter for non-string columns, if searching them makes any sense.
To restrict the search to string columns simply insert
.Where(x => x.DataType == typeof(string))
between Cast and Select, so that cols contains only searchable columns..
If instead you want to search numeric columns you could write the filter like this:
var filter = cols.Select(x => "Convert(" + x + ", 'System.String') like '"
+ searchValue + "%'").Aggregate((a, b) => a + " OR " + b);
This uses the Convert function of the expression syntax . But why would one search for numbers starting with some digits..?
Here is a test with 2 string, 1 numeric and one datetime columns. The filter works for all; note that for the test I have added an extra '%' to extend the search to the whole values, not just the start..

Array of string into a string ready for JSON formatting

I have an array of string values obtained from a method and I want to convert this array into a HTML readable format for getting/posting (eg. value=[12,21])
I have tried the following:
string[] array1 = methodToGetStringArray(); //assuming [12,21] for example
string finalString = "value="+array1; //intended output is value=[12,21]
Which of course doesn't work.
I would like to know the method to provided the value as shown above.
You can try,
string finalString = String.Format("value=[{0}]", string.Join(", ", array1));
finalString should return,
value=[12, 21]
Try like this:
string[] array1 = methodToGetStringArray();
string json = JsonConvert.SerializeObject(array1);
Refer JSON.NET
you can try this
string finalString = "Value = [" + string.Join(",", array1) + "]";
Use string.Join method:
string finalString = "value=[" + string.Join(",",array1) + "]";
Or JavaScriptSerializer:
var serializer = new JavaScriptSerializer();
var finalString = "value=" + serializer.Serialize(array1);
List<string> list = new List<string>(array1);
var a = "value=[" + list.Aggregate((x, y) => x + "," + y) + "]";

Adding text items from a csv file, to a listbox only when certain a string matches a string from that csv file

So I've been trying to figure out how to bring an entire line of a .csv file but only the ones who's first string matches another one.
This is what I got so far, all im getting back in my listbox is info from the same random line.
If you guys can help me with the logic it would help out a lot thanks
cbocustinfo.Items.Clear();
lstcustinfo.Items.Clear();
StreamReader infile, transdata;
infile = File.OpenText(#"E:\AS2customers.csv");
transdata= File.OpenText(#"E:\AS2data.csv");
string[] custinfo, names;
string[] custtrans;
do
{
custtrans = transdata.ReadLine().Split(',');
if (custinfo[1] == custtrans[0])
{
lstcustinfo.Items.Add(custtrans[3] + " " + custtrans[4]);
}
}
while (transdata.EndOfStream != True);
infile.Close();
transdata.Close();
Here is where I initialize custinfo
do
{
custinfo = infile.ReadLine().Split(',');
names = custinfo[0].Split(' ');
cbocustinfo.Items.Add(names[0] +" "+ names[1]+ " " + custinfo[1]);
}
while (infile.EndOfStream != true);
If I understand what you're trying to do correctly, maybe it would be easier to just read the files into two strings, then do the splitting and looping over those. I don't know your file formats, so this may be doing unnecessary processing (looping through all the transactions for every customer).
For example:
cbocustinfo.Items.Clear();
lstcustinfo.Items.Clear();
var customers = File.ReadAllText(#"E:\AS2customers.csv")
.Split(new []{Environment.NewLine}, StringSplitOptions.None);
var transactions = File.ReadAllText(#"E:\AS2data.csv")
.Split(new []{Environment.NewLine}, StringSplitOptions.None);
foreach (var customer in customers)
{
var custInfo = customer.Split(',');
var names = custInfo[0].Split(' ');
cbocustinfo.Items.Add(names[0] + " " + names[1]+ " " + custinfo[1]);
foreach (var transaction in transactions)
{
var transInfo = transaction.Split(',');
if (custInfo[1] == transInfo[0])
{
lstcustinfo.Items.Add(transInfo[3] + " " + transInfo[4]);
}
}
}

Simle/Nested foreach to linq( Concatenate string and Datatable rows and columns)

Is there a way to change this foreach loop in LINQ.
here Dict is my dictionary and builder is a stringbuilder.
string str = "m";
string seperateChar = str + "n";
foreach (string column in dict2.Keys)
{
builder.Append(str)
.Append("\"")
.Append(column)
.Append("\"");
//builder.Append("\"");
str = seperateChar;
}
I was trying to apply nested loop on this query, can this be done too through LINQ
Lets assume its a row and columns.
foreach (DataRow row in table.Rows)
{
var res = "m" + String.Join("mn", table.Columns.ColumnName.Select(k => "\"" + k + "\""));
writer.WriteLine(res.ToString());
}
return "m" + String.Join("mn", dict2.Keys.Select(k => "\"" + k + "\""))
return "m\"" + dict1.Keys.Aggregate((a, b) => a + "\"mn\"" + b) + "\"";

Categories

Resources