I'm trying to get a csv file into a data table but there are some things in the csv file that I am trying to omit from being entered into the data table, so I wrote it to a list first.
The csv files that i will using the software for have different sections in it for which I then split the whole list into the separate lists for those sections.
After all that was achieved, i needed to skip some lines in each list and wrote the final form i was happy with to lists respective to previous set of lists.
Now I hit a wall, I need to write each of the lists to a respective data grid.
public partial class Form1 : Form
{
String filePath = "";
//list set 1 = list box
List<String> lines = new List<String>();
List<String> accountList = new List<String>();
List<String> statementList = new List<String>();
List<String> summaryList = new List<String>();
List<String> transactionList = new List<String>();
//list set 2 = dgv
List<String> accountList2 = new List<String>();
List<String> statementList2 = new List<String>();
List<String> summaryList2 = new List<String>();
List<String> transactionList2 = new List<String>();
public Form1()
{
InitializeComponent();
}
private void btn_find_Click(object sender, EventArgs e)
{
try
{
using (OpenFileDialog fileDialog = new OpenFileDialog()
{ Filter = "CSV|* .csv", ValidateNames = true, Multiselect = false })
if (fileDialog.ShowDialog() == DialogResult.OK)
{
String fileName = fileDialog.FileName;
filePath = fileName;
}
try
{
if (File.Exists(filePath))
{
lines = File.ReadAllLines(filePath).ToList();
foreach (String line in lines)
{
String addLine = line.Replace("'", "");
String addLine2 = addLine.Replace("\"", "");
String str = line.Substring(0, 1);
int num = int.Parse(str);
if (addLine2.Length > 1)
{
String addLine3 = addLine2.Substring(2);
switch (num)
{
case 2:
accountList.Add(addLine3);
break;
case 3:
statementList.Add(addLine3);
break;
case 4:
summaryList.Add(addLine3);
break;
case 5:
transactionList.Add(addLine3);
break;
}
}
}
}
else
{
MessageBox.Show("Invalid file chosen, choose an appropriate CSV file and try again.");
}
transactionLB.DataSource = transactionList;
//var liness = transactionList;
//foreach (string line in liness.Skip(2))
// transactionList2.Add(line);
//Console.WriteLine(transactionList2);
//var source = new BindingSource();
//source.DataSource = transactionList2;
//trans_dgv.DataSource = source;
accountLB.DataSource = accountList;
summaryLB.DataSource = summaryList;
statementLB.DataSource = statementList;
}
catch (Exception)
{
MessageBox.Show("Cannot load CSV file, Ensure that a valid CSV file is selected and try again.");
}
}
catch (Exception)
{
MessageBox.Show("Cannot open File Explorer, Something is wrong :(");
}
}
}
EDIT 1:
the table has the following columns for the transaction lists (each of the lists have different columns) :
'Number' , 'Date' , 'Description1' , 'Description2' , 'Description3' , 'Amount' , 'Balance' , 'Accrued Charges'
an example of data in the lines of the transaction list:
9, 02 Sep, Petrol Card Purchase, Shell Kempton Park, 968143*7188 30 Aug, -714.45, -10661.88, 5.5
some liness do contain null values.
If I understand correctly, it seems like you're wanting to get the value of the strings in your string list to appear in your DataGridViews. This can be a little tricky because the DataGridView needs to know which property to display and strings only have the Length property (which probably isn't what you're looking for). There are a lot of ways to go about getting the data you want into the DataGridView. For example you could use DataTables and choose which column you want displayed in the DataGridView. If you want to stick with using string lists, I think you could get this to work by modifying your DataSource line to look something like this:
transactionLB.DataSource = transactionList.Select(x => new { Value = x} ).ToList();
I hope this helps! Let me know if I've misunderstood your question. Thanks!
Related
I have a csv file with multiple columns, "PROJECT NAME", "PROJECT BUILD". I am trying to populate comobobox with Project Name column only.
Project name column might have multiple repeated names but repeated names should only appear once in combobox as an option to select. For example: in column 1, under "Project Name", Toyota is listed 4 times and Honda is listed 8 Times. Combobox will have 2 things, Toyota and Honda.
Here is my code so far:
// Wehn Form Loads___________________________________________________________________________________________________
public void OnLoad(object sender, RoutedEventArgs e)
{
StreamReader sr = new StreamReader(path);
string column = sr.ReadToEnd();
string[] eachColumn = column.Split(',');
foreach (string s in eachColumn)
{
Project_Name_Combobox.Items.Add(s);
}
}
The current code gets me the entire csv content (row and column) separated by "," listed under combo box. :(. Any help is apricated.
You have to separate out the rows and columns from csv and store whatever you need separately like below.
public void OnLoad(object sender, RoutedEventArgs e)
{
StreamReader sr = new StreamReader(path);
List<string> ProjectNames = new List<string>();
int lineNumber = 1;
while (!sr.EndOfStream)
{
var EachRow = sr.ReadLine();
var Columns= EachRow.Split(',');
if(lineNumber != 1){
ProjectNames.Add(Columns[0]);
}
lineNumber++;
}
ProjectNames = ProjectNames.Distinct().ToList();
foreach(var projectName in ProjectNames){
Project_Name_Combobox.Items.Add(projectName);
}
}
I am new to C# and I have taken a small task on. The StackOverflow entry for reading a text file and saving to a list is a great start for me. I need to read a text file and send the data to an SQL database.
How to Read This Text File and store in a list using C#
The Data in List<Data> list = new List<Data>(); just keeps staying in red.
How can I stop this please?
I am a PLC engineer and I'm trying to collate data that cannot be handled by PLC. I am just trying to read the file so that I can then show the data in a Grid, with a view to populating the SQL database later.
The text file is held on a remote Linux machine. The collator is a WIndows 10 panel. The SQL can reside on teh Windows panel or remotely.
static void Main(string[] args)
{
List<Data> list = new List<Data>();
var dd = File.ReadAllLines(#"C:\Users\XXXX\Desktop\test.txt")
.Skip(1)
.Where(s => s.Length > 1).ToList();
foreach (var item in dd)
{
var columns = item.Split('\t').Where(c => c.Trim() != string.Empty).ToList();
if (columns != null && columns.Count > 0)
{
int id;
if (int.TryParse(columns[0], out id))
{
list.Add(new Data()
{
id = Convert.ToInt32(columns[0]),
Name = columns[1],
Description = columns[2],
Quantity = Convert.ToInt32(columns[3]),
Rate = Convert.ToDouble(columns[4]),
Discount = Convert.ToInt32(columns[5]),
Amount = int.Parse(columns[6])
});
}
else
{
list.Last().Description += columns[0];
}
}
}
Console.ReadLine();
}
I just keep receiving red squiggly lines on <Data. within Visual Studio
I got the code to work and I read the DAT/text file straight into a DatagridView. I am now writing the Grid to SQL.
Many thanks, sorry for latency as I've been away on-site.
String sLine = "";
try
{
//Pass the file you selected with the OpenFileDialog control to
//the StreamReader Constructor.
System.IO.StreamReader FileStream = new System.IO.StreamReader(openFileDialog1.FileName);
//You must set the value to false when you are programatically adding rows to
//a DataGridView. If you need to allow the user to add rows, you
//can set the value back to true after you have populated the DataGridView
dataGridView1.AllowUserToAddRows = false;
// Clear the DataGridView prior to reading a new text file
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
//Read the first line of the text file
sLine = FileStream.ReadLine();
//The Split Command splits a string into an array, based on the delimiter you pass.
//I chose to use a semi-colon for the text delimiter.
//Any character can be used as a delimeter in the split command.
//string[] s = sLine.Split(';');
string[] s = sLine.Split('\t');
//In this example, I placed the field names in the first row.
//The for loop below is used to create the columns and use the text values in
//the first row for the column headings.
for (int i = 0; i <= s.Count() - 1; i++)
{
DataGridViewColumn colHold = new DataGridViewTextBoxColumn();
colHold.Name = "col" + System.Convert.ToString(i);
colHold.HeaderText = s[i].ToString();
dataGridView1.Columns.Add(colHold);
}
//Read the next line in the text file in order to pass it to the
//while loop below
sLine = FileStream.ReadLine();
//The while loop reads each line of text.
while (sLine != null)
{
//Adds a new row to the DataGridView for each line of text.
dataGridView1.Rows.Add();
//This for loop loops through the array in order to retrieve each
//line of text.
for (int i = 0; i <= s.Count() - 1; i++)
{
//Splits each line in the text file into a string array
//s = sLine.Split(';');
s = sLine.Split('\t');
//Sets the value of the cell to the value of the text retreived from the text file.
dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[i].Value = s[i].ToString();
}
sLine = FileStream.ReadLine();
}
//Close the selected text file.
FileStream.Close();
}
catch (Exception err)
{
//Display any errors in a Message Box.
System.Windows.Forms.MessageBox.Show("Error "+ err.Message, "Program Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
So, I am trying to check the contents of a text file to see if any of the values contained within the List textwords exist within the text file.
However when the code is executed it always thinks the message doesn't contain any of the strings contained within the textwords List.
The code used is below.
Any help with this would be greatly appreciated.
List<string> textwords = new List<string>();
using (var UnacceptableWords = new StreamReader("fileLocation"))
{
while (!UnacceptableWords.EndOfStream)
{
string[] row = UnacceptableWords.ReadLine().Split(',');
string Column1 = row[0];
textwords.Add(Column1);
}
}
directory = new DirectoryInfo("filelocation");
files = directory.GetFiles("*.txt");
foreach (FileInfo file in files)
{
using(StreamReader Message = new StreamReader(file.FullName))
{
string MessageContents = Message.ReadToEnd();
if(MessageContents.Contains(textwords.ToString()))
{
MessageBox.Show("found a word");
}
MessageBox.Show("message clean");
}
}
The string.Cointains() method takes in a string but you are passing into it the List, which you have turned into a string.
List.ToString() != Values contained in the List as strings
To do this you must iterate through the array and pass each element of it at a time
foreach(string keyword in textwords)
{
if(MessageContents.Contains(keyword))
{
MessageBox.Show("found a word");
break;
}
}
I am trying to write a program for a school project that will read a csv file containing a name on each line and output each name and the number of times it occurrences in a list box. I would prefer for it not to be pre set for a specific name but i guess that would work also. So far i have this but now I'm stuck. The CSV file will have a name on each line and also have a coma after each name. Any help would be great thanks.
This is what I have so far:
string[] csvArray;
string line;
StreamReader reader;
OpenFileDialog openFileDialog = new OpenFileDialog();
//set filter for dialog control
const string FILTER = "CSV Files|*.csv|All Files|*.*";
openFileDialog.Filter = FILTER;
//if user opens file and clicks ok
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//open input file
reader = File.OpenText(openFileDialog.FileName);
//while not end of stream
while (!reader.EndOfStream)
{
//read line from file
line = reader.ReadLine().ToLower();
//split values
csvArray = line.Split(',');
Using Linq we can do the following:
static IEnumerable<Tuple<int,string>> CountOccurences(IEnumerable<string> data)
{
return data.GroupBy(t => t).Select(t => Tuple.Create(t.Count(),t.Key));
}
Test:
var strings = new List<string>();
strings.Add("John");
strings.Add("John");
strings.Add("John");
strings.Add("Peter");
strings.Add("Doe");
strings.Add("Doe");
foreach (var item in CountOccurences(strings)) {
Console.WriteLine (String.Format("{0} = {1}", item.Item2, item.Item1));
}
John = 3
Peter = 1
Doe = 2
To use in your case:
string filePath = "c:\myfile.txt"
foreach (var item in CountOccurences(File.ReadAllLines(filePath).Select(t => t.Split(',').First())))
Console.WriteLine (String.Format("{0} = {1}", item.Item2, item.Item1));
you can use a dictionary, where you can store the occurrence of each Name:
Dictionary<string,int> NameOcur=new Dictionary<string,int>();
...
while (!reader.EndOfStream)
{
//read line from file
line = reader.ReadLine().ToLower();
//split values
csvArray = line.Split(',');
if (NameOcur.ContainsKey(csvArray[0]))
{
///Name exists in Dictionary increase count
NameOcur[csvArray[0]]++;
}
else
{
//Does not exist add with value 1
NameOcur.Add(csvArray[0],1);
}
}
I have a CSV file which contains four columns i.e Name, Surname, Age, Data of Birth
I want to change the column Name to FullName. How can this be done in c# please?
var reader = new StreamReader(File.OpenRead(#"C:\myCSV.csv"));
var line = reader.ReadLine();
var values = line.Split(';');
var title = line.Split(',');
Console.WriteLine(title[0]);
if (title.Contains("Name"))
{
title[0] = "FullName";
}
Now I'm stuck on how should I continue to change the Column name
If you are attempting to create a new file with 3 columns instead of 4 this would be a starting point, however, you should use a csv parser. This is just a demonstration to show you how to combine the two columns.
string[] lines = System.IO.File.ReadAllLines(#"C:\myCSV.csv");
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\myCSV2.csv"))
{
foreach (string line in lines)
{
if (line==lines[0])
{ //Change Header
file.WriteLine("Fullname,Age,Date of Birth");
}
else
{
string[] values = line.Split(',');
file.WriteLine(string.Format("{0} {1},{2},{3}",
values[0],values[1],values[2],values[3]));
}
}
}