I'm trying to develop an application which will take the data from a datagrid and based on a drop down menu choice return a csv file with only the selected client . My code is shown below , This links to a previous question I posted howeever I am still getting no values back and I really need to sort this out so I'm wondering if anyone can either see were i'm going wrong or else provide alternatives
//Master inventory export
private void ExportClass_Click(object sender, EventArgs e)
{
StringBuilder str = new StringBuilder();
objSqlCommands2 = new SqlCommands("MasterInventory", "ClientName");
string strString = str.ToString();
string Filepath = txtSaveShareClass.Text.ToString();
str.Append("ISIN ,FundName,Status,Share CCY,Benchmark,NAV Freq,CLASSCODE,SIMULATION,HEDGED,FUNDCCY");
StringManipulation sm = new StringManipulation();
foreach (DataRow dr in this.CalcDataSet.MasterInventory)
{
foreach (object field in dr.ItemArray)
{
str.Append(field.ToString() + ",");
}
str.Replace(",", "\n", str.Length - 1, 1);
}
try
{
System.IO.File.WriteAllText(Filepath, str.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Write Error :" + ex.Message);
}
List<string[]> lsClientList = objStringManipulation.parseCSV(Filepath,cmbClientList .Text.ToCharArray());
foreach (string[] laClient in lsClientList)
{
sm.parseCSV2(Filepath, cmbClientList.Text.ToCharArray());
List<string[]> newFoo = lsClientList.Where(x => x.Contains(cmbClientList.Text)).ToList();
List<string[]> Results = sm.parseCSV2(Filepath, cmbClientList.Text.ToCharArray()).Where(x => x.Contains(cmbClientList.Text)).ToList();
//Refreshs the Client table on display from the
System.IO.File.WriteAllText(Filepath, Results.ToString());
}
this.TableAdapter.Fill(this.CalcDataSet.MasterInventory);
dataGridView2.Update();
}
If all of your variables are filling properly and your Results list contains the data that you expect, then the problem is with your WriteAllText call. You have:
System.IO.File.WriteAllText(Filepath, Results.ToString());
That is not going to produce the output that you seem to expect. It will likely just give you the class name.
Results is a List<string[]>. If you want to output that as a CSV, then you have to enumerate it:
using (var outfile = new StreamWriter(Filepath))
{
foreach (var line in Results)
{
StringBuilder sb = new StringBuilder();
foreach (var field in line)
{
sb.Append(field + ",");
}
sb.Length = sb.Length -1;
outfile.WriteLine(sb.ToString());
}
}
Related
i am making a quiz application for my computing coursework and i am working on the end screen and in the end screen i have method called savescore()
the savescore() is meant to save the users' username,score and time into a text file. the savescore() method saves the users details into a text-file called scores perfectly but my problem is that when i write the user details into the text file i want the data to be written into the scores text file in order of descending score and i cant figure out how to do that.
private void SaveScore()
{
string file = #"..\..\textfiles\scores.txt";
try
{
//
// Create file if not exists
//
if (!File.Exists(file))
{
File.Create(file).Dispose();
}
//
// Create DataTable
//
DataColumn nameColumn = new DataColumn("name", typeof(String));
DataColumn scoreColumn = new DataColumn("score", typeof(int));
DataColumn timeColumn = new DataColumn("time", typeof(long));
DataTable scores = new DataTable();
scores.Columns.Add(nameColumn);
scores.Columns.Add(scoreColumn);
scores.Columns.Add(timeColumn);
//
// Read CSV and populate DataTable
//
using (StreamReader streamReader = new StreamReader(file))
{
streamReader.ReadLine();
while (!streamReader.EndOfStream)
{
String[] row = streamReader.ReadLine().Split(',');
scores.Rows.Add(row);
}
}
Boolean scoreFound = false;
//
// If user exists and new score is higher, update
//
foreach (DataRow score in scores.Rows)
{
if ((String)score["name"] == player.Name)
{
if ((int)score["score"] < player.Score)
{
score["score"] = player.Score;
score["time"] = elapsedtime;
}
scoreFound = true;
break;
}
}
//
// If user doesn't exist then add user/score
//
if (!scoreFound)
{
scores.Rows.Add(player.Name, player.Score, elapsedtime);
}
//
// Write changes to CSV (empty then rewrite)
//
File.WriteAllText(file, string.Empty);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("name,score,time");
foreach (DataRow score in scores.Rows)
{
stringBuilder.AppendLine(score["name"] + "," + score["score"] + "," + score["time"]);
}
File.WriteAllText(file, stringBuilder.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Error saving high score:\n\n" + ex.ToString(), "Error");
}
}
so i someone could edit my current code to save the user details in descending order in terms of the score that would be fantastic and thanks in advance.
You can use the DataTable.Select method to achieve that. With the select method you can filter and sort the row in a table.
Here is the changed foreach statement that uses the method to sort the data.
foreach (DataRow score in scores.Select(null, "score DESC"))
{
stringBuilder.AppendLine(score["name"] + "," + score["score"] + "," + score["time"]);
}
I am creating an application in which user search word in docx file and get paragraph number which is contained that word. Almost my application work fine but the problem which I was facing is that I get repeating file name and get each paragraph in new listview row. Lets see the image for more understanding.
Image.
I just want searched file names and all paragraphs in one row of listview by separate with ','comma. Lets see the desire image.
See Below code which I try
private void button2_Click(object sender, EventArgs e)
{
this.listView1.Items.Clear();
try
{
foreach (var filePath in Search(this.textBox1.Text, this.textBox2.Text, this.checkBox1.Checked, this.checkBox2.Checked, this.radioButton2.Checked))
{
var file = new FileInfo(filePath);
this.listView1.Items.Add(new ListViewItem(new string[] { file.Name, string.Format("{0:0.0}", file.Length / 1024d), file.FullName, toDisplay }));
}
}
catch (Exception ex)
{
MessageBox.Show(this, string.Format("Exception details:\n{0}", ex), string.Format("Exception '{0}' occurred.", ex.GetType()), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static IEnumerable<string> Search(string directory, string searchString, bool searchSubdirectories, bool caseSensitive, bool useRegex)
{
/*
* Below is the list where we insert all paragraph of docx file.
*/
var paragph = new List<string>();
/*
* Below I am using foreach loop by using this I get all docx files from a selected directory.
*/
foreach (var filePath in Directory.GetFiles(directory, "*.docx", searchSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
{
string docxText;
int counter = 0;
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
docxText = new DocxToStringConverter(stream).Convert();
string[] lines = docxText.Split(new string[] { Environment.NewLine },StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
if (line.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
{
//MessageBox.Show((counter + 1).ToString() + ": " + line);
paragph.Add((counter + 1).ToString());
arrparagh = paragph.ToArray();
toDisplay = string.Join(",", arrparagh);
//MessageBox.Show(toDisplay);
yield return filePath;
}
counter++;
}
}
}
I believe you need to move your yield return out of the inner foreach loop. Like:
paragph.Clear();
foreach (string line in lines)
{
if (line.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
{
//MessageBox.Show((counter + 1).ToString() + ": " + line);
paragph.Add((counter + 1).ToString());
arrparagh = paragph.ToArray();
toDisplay = string.Join(",", arrparagh);
//MessageBox.Show(toDisplay);
}
counter++;
}
yield return filePath;
With your yield return where it is now, it returns out of the function and gets displayed after every line that matches. Moving the yield return out of that inner loop should make it return only after each file has been fully searched.
I'm having hard times exporting DB table in CSV file using LINQ. I've tried few things from related topics, but it was all way too long and I need a simpliest solution. There has to be something.
With this code is problem, that file is created, but empty. When I tried to debug, query is fine, there's everything I want to export. What am I doing wrong?
private void Save_Click(object sender, RoutedEventArgs e)
{
StreamWriter sw = new StreamWriter("test.csv");
DataDataContext db = new DataDataContext();
var query = from x in db.Zbozis
orderby x.Id
select x;
foreach (var something in query)
{
sw.WriteLine(something.ToString());
}
}
Edit: Ok, I tried all your suggestions, sadly with same result (CSV was created, but in it was 10x Lekarna.Zbozi (Name of project/db + name of table)).
So I used a method, that I've found (why reinventing a wheel, huh).
public string ConvertToCSV(IQueryable query, string replacementDelimiter)
{
// Create the csv by looping through each row and then each field in each row
// seperating the columns by commas
// String builder for our header row
StringBuilder header = new StringBuilder();
// Get the properties (aka columns) to set in the header row
PropertyInfo[] rowPropertyInfos = null;
rowPropertyInfos = query.ElementType.GetProperties();
// Setup header row
foreach (PropertyInfo info in rowPropertyInfos)
{
if (info.CanRead)
{
header.Append(info.Name + ",");
}
}
// New row
header.Append("\r\n");
// String builder for our data rows
StringBuilder data = new StringBuilder();
// Setup data rows
foreach (var myObject in query)
{
// Loop through fields in each row seperating each by commas and replacing
// any commas in each field name with replacement delimiter
foreach (PropertyInfo info in rowPropertyInfos)
{
if (info.CanRead)
{
// Get the fields value and then replace any commas with the replacement delimeter
string tmp = Convert.ToString(info.GetValue(myObject, null));
if (!String.IsNullOrEmpty(tmp))
{
tmp.Replace(",", replacementDelimiter);
}
data.Append(tmp + ",");
}
}
// New row
data.Append("\r\n");
}
// Check the data results... if they are empty then return an empty string
// otherwise append the data to the header
string result = data.ToString();
if (string.IsNullOrEmpty(result) == false)
{
header.Append(result);
return header.ToString();
}
else
{
return string.Empty;
}
}
So I have a modified version of previous code:
StreamWriter sw = new StreamWriter("pokus.csv");
ExportToCSV ex = new ExportToCSV();
var query = from x in db.Zbozis
orderby x.Id
select x;
string s = ex.ConvertToCSV(query,"; ");
sw.WriteLine(s);
sw.Flush();
Everything is fine, except it export every line in one column and does not separate it. See here -> http://i.stack.imgur.com/XSNK0.jpg
Question is obvious then, how to divide it into columns like I have in my DB?
Thanks
You are not closing the file. Either use "using"
using(StreamWriter sw = new StreamWriter("test.csv"))
{
..............
}
or simply try this
File.WriteAllLines("test.csv",query);
My below code first writes an exclamation point (!) delimited Header to a .txt file and then loops through each item and subItem in a ListView Control, placing each record value onto a new line in my .txt file. All the values are needed for user review while in the ListBox, but when writing to the file, I need to only write the fields that are used in the next step, using the .txt file as datasource for MS Word MailMerge document.
Instead of looping through and appending every record field value to my StringBuilder, I need a way to get only the values where the ListView Column Header is the following:
memno
name
address1
address2
address3
sal
fuldate
sys
private void btnMerge_Click(object sender, EventArgs e)
{
try
{
string docLoc = "";
string docSource = "";
StringBuilder sb;
// Change this to the DataSource FilePath
StreamWriter sw = new StreamWriter("C:\\Users\\NAME\\Desktop\\Test2.txt");
string fileHeaderTxt = "memno!name!address1!address2!city!state!zip!old_addr1!old_addr2!old_city!old_state!old_zip!sys!fuldate!sex!lname!sal!address3";
sb = new StringBuilder();
sb.Append(fileHeaderTxt);
sw.WriteLine(sb.ToString());
sb.Clear();
if (lvData.Items.Count > 0)
{
foreach (ListViewItem lvI in lvData.Items)
{
sb = new StringBuilder();
foreach (ListViewItem.ListViewSubItem lvSI in lvI.SubItems)
{
sb.Append(string.Format("{0}!", lvSI.Text));
}
sw.WriteLine(sb.ToString());
}
sw.WriteLine();
}
//sb.Clear();
sw.Close();
MessageBox.Show("Complete");
if (rbPrint.Checked)
{
Print(docLoc, docSource);
}
if (rbCommit.Checked)
{
Commit_NetFYI();
}
}
catch (Exception ex)
{
MessageBox.Show("Source:\t" + ex.Source + "\nMessage: \t" + ex.Message + "\nData:\t" + ex.Data);
}
finally
{
//
}
}
I've been hammering away at this for last couple hours and just can't seem to get it. Anyone have some ideas?
EDIT:
I modified my code using Grammarian's solution, but it seems I am missing something. Each loop iteration writes a line containing all previous looped values, plus the new value.
Rough Example:
Header1!Header2!Header3!Header4
1!2!3!4
1!2!3!4!5!6!7!8
1!2!3!4!5!6!7!8!9!10!11!12
1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16
etc.
Here is my current code:
private void btnMerge_Click(object sender, EventArgs e)
{
try
{
string docLoc = "";
string docSource = "";
StringBuilder sb;
// Change this to the DataSource FilePath
StreamWriter sw = new StreamWriter("C:\\Users\\NAME\\Desktop\\Test2.txt");
string fileHeaderTxt = "memno!name!address1!address2!city!state!zip!old_addr1!old_addr2!old_city!old_state!old_zip!sys!fuldate!sex!lname!sal!address3";
sb = new StringBuilder();
sb.Append(fileHeaderTxt);
sw.WriteLine(sb.ToString());
sb.Clear();
if (lvData.Items.Count > 0)
{
foreach (ListViewItem lvI in lvData.Items)
{
var indices = new int[] { 0, 1, 2, 3, 12, 13, 16, 17 };
foreach (int i in indices)
{
sb.Append(string.Format("{0}!", lvI.SubItems[i].Text));
}
sw.WriteLine(sb.ToString());
sb.Clear();
}
sw.WriteLine();
}
}
}
EDIT2:
Got it, wasn't clearing out my stringBuilder object after each time through my first loop. Edited code above to reflect working code.
Rather than always just iterating all subitems, make an array of subitem indices in the order you want, and iterate the indices.
var indices = new [] { 0, 1, 2, 4, 9 }; // whatever you want
foreach (int i in indices)
{
sb.Append(string.Format("{0}!", lvI.SubItems[i].Text));
}
My Usecase is to read data from a textfile by browsing to the location of the file containing the data to be quoted.the data from the file is save in a list. i use arraylist to get the data and loop through the arraylist and concatenate each string then create output file to store the data in single column as demostrated below
Example of a string:
20050000
40223120
40006523
sample out put:
'20050000',
'40223120',
'40006523'
But my code is currently displaying the output in the format:
'20050000'20050000,
'40223120'20050000,
'40006523'40006523
Pls help.
public List<string> list()
{
List<string> Get_Receiptlist = new List<string>();
String ReceiptNo;
openFileDialog1.ShowDialog();
string name_of_Textfile = openFileDialog1.FileName;
try
{
StreamReader sr = new StreamReader(name_of_Textfile);
{
while ((ReceiptNo = sr.ReadLine()) != null)
{
Get_Receiptlist.Add(ReceiptNo);
} // end while
MessageBox.Show("Record saved in the Data list");// just for testing purpose.
}// end StreamReader
}
catch (Exception err)
{
MessageBox.Show("Cannot read data from file");
}
return Get_Receiptlist;
}
private void button2_Click(object sender, EventArgs e)
{
string single_quotation = "'";
string comma = ",";
string paths = #"C:\Users\sample\Desktop\FileStream\Output.txt";
if (!File.Exists(paths))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(paths))
{
string[] receipt = list().ToArray();
foreach (string rec in receipt)
{
string quoted_receipt = single_quotation + rec + single_quotation + rec + comma;
sw.WriteLine(quoted_receipt);
sw.WriteLine(Environment.NewLine);
}//foreach
sw.Close();
MessageBox.Show("Finish processing File");
}//end using
}// end if
}
In your method button2_Click you have bad loop:
string[] receipt = list().ToArray();
foreach (string rec in receipt)
{
string quoted_receipt = single_quotation + rec + single_quotation + rec + comma;
sw.WriteLine(quoted_receipt);
sw.WriteLine(Environment.NewLine);
}//foreach
First I'm not even sure its Java ... but if it was Java, then I would replace this fragment with this:
List<String> values = list();
for (int i = 0; i < values.size(); i++)
{
String rec = values.get(i);
StringBuilder quoted_receipt = new StringBuilder();
if (i > 0)
{
// add comma only if the first iteration already passed
quoted_receipt.append(comma);
}
quoted_receipt.append(single_quotation).append(rec).append(single_quotation);
sw.WriteLine(quoted_receipt.toString());
sw.WriteLine(Environment.NewLine);
}