remove spaces between columns exported to textfile - c#

I am using c# windows application to get data from database and display on datagridview and exporting to text file
I want to remove empty spaces between below 4 columns .
2
vehicle control services ltd
Brom
Malkit
i get 2 vehicle control services ltd brom mal, but i want it to be like 2vehicle control services ltdBromMlkit
this is my code.
string stringSql = " SELECT distinct " +
"'" + comboBox6.Text + "' as RecordType" +
" , left([Claimant Name] +' ',30) " +
" , left([Claimant Address1] +' ',30) " +
" , left([Claimant Address2] +' ',30) as ClaimantAddress2 " +
" , left([Claimant Address3] +' ',30) as
exporting to text file code
if (obj == null || obj == Convert.DBNull)
return "";
// if string has no ','
if (obj.ToString().IndexOf(",") == -1)
return obj.ToString();
// remove backslahes
return "\"" + obj.ToString() + "\"";
}
private void ExportDatatviewToCsv(string iFilename, DataView dv)
{
// Open output stream
StreamWriter swFile = new StreamWriter(iFilename);
// Rows of Data
foreach (DataRowView rowData in dv)
{
string[] colData = new string[dv.Table.Columns.Count];
for (int i = 0; i < dv.Table.Columns.Count; i++)
{
object obj = rowData[i];
colData[i] = GetWriteableValueForCsv(obj);
}
// Write data in row
swFile.WriteLine(string.Join(" ", colData));
}
// Close output stream
swFile.Close();
}
private void btnSave_Click(object sender, EventArgs e)
{
if (myDataset == null)
{
return;
}
if (myDataset.Tables[0].Rows.Count == 0)
{
return;
}
DataView vwExport = new DataView(myDataset.Tables[0]);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "TXT file|*.txt";
sfd.FileName = "ee " + ".txt";
if (sfd.ShowDialog() == DialogResult.OK)
{
if (sfd.FileName != "")
{
ExportDatatviewToCsv(sfd.FileName, vwExport);
MessageBox.Show("File has been saved as: " + Environment.NewLine + sfd.FileName + Environment.NewLine + Environment.NewLine + "NB: This dataset has been ordered by t_reference in ascending order. If being combined with an existing dataset - that dataset will also need to be sorted in this way.", "Operation complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

Just to make it clear what I think you are asking...
You currently get this for each line:
2 vehicle control services ltd brom mal
but you want it like this for each line (which let me point out makes absolutely no sense at all, it doesn't look very usable):
2vehicle control services ltdBromMlkit
If that is the case then in your code just replace this line:
swFile.WriteLine(string.Join(" ", colData));
with this line:
swFile.WriteLine(string.Join("", colData));
Notice that it will now join the string with an empty string, rather than joining with the single space that you don't want.

Related

Check if a folder exists with only a part of the name in C#

I have created a code to create folders with two Textboxes.
Textbox1 - customer number (XXXX).
Textbox2 - customer name.
I would like to be able to check if the customer number exists before creating the folder.
The newly created folder will be the combination of the two Textboxes (this is already solved).
I just need to be able to determine if the folder exists only with the customer number, as it is probably created with (customer number + customer name).
Current working code:
{
string no = textBox1.Text;
string client = textBox2.Text;
string carpeta = #"C:\" + no + " " + client;
string sourcePath = #"C:\main";
string destinationPath = #"C:\" + no + " " + client;
textBox1.Clear();
textBox2.Clear();
try
{
if (Directory.Exists(carpeta))
{
DialogResult y;
y = MessageBox.Show("Folder already exists\nDo you want to open it?", "AE.", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (y == DialogResult.Yes)
{
System.Diagnostics.Process.Start(#"C:\" + no + " " + client);
}
else
{
Close();
}
}
else
{
DialogResult x;
x = MessageBox.Show("The folder doesn't exist\nWant to create a folder?." + "\n" + no + " " + client, "AE.", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (x == DialogResult.Yes)
{
Directory.CreateDirectory(carpeta);
FileSystem.CopyDirectory(sourcePath, destinationPath, UIOption.AllDialogs);
System.Diagnostics.Process.Start(#"C:\" + no + " " + client);
}
else
{
Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.Message);
}
}
You could also each time you need the folder just do that:
public static void Main()
{
var username = "someuser";
var usernumber = "ABC123";
var mainDirectory = #"C:\Path\To\The\Main\Dir";
var pathToTheUserDirectory = Path.Combine(mainDirectory, $"{username}-{usernumber}");
// This line will create the directory if not exist or take the existing directory.
var directoryInfo = Directory.CreateDirectory(pathToTheUserDirectory);
var directoryPath = directoryInfo.FullName;
// ...
// or
// directoryInfo.Delete(recursive: true);
}
string[] dirs = Directory.GetDirectories(#"c:\", txtTextBox.Text + "*");
this will only get directrories starting with the desired Text
Edit: This is only a good solution if the customer number has fixed places (in you exaple 4 from 0000-9999)
Microsoft Documentation - check example below

C# Creating white space lines between assembled .text

private void btnAssemble_Click(object sender, EventArgs e)
{
txtAssembled.Text = (cboTitle.Text + txtFirstName.Text[0] + txtMiddle.Text + txtLastName.Text + "\r\n" +txtStreet.Text + "\r\n"+ cboCity.Text);
}
I'm trying to get 1 character white space inbetween cboTitle.Text, txtFirname.Text, txtMiddle.Text, and txtLastName, but they all output the information together, but I want them spaced evenly. what do I need to do? thanks in advance.
I'm going to post some other code thats below the one above in my project, just in case it might be relevant.
string AssembleText(string Title, string FirstName, string MiddleInitial, string LastName, string AddressLines, string City )
{
string Result = "";
Result += Title + " ";
Result += FirstName.Substring(0, 2) + " ";
// Only append middle initial if it is entered
if (MiddleInitial != "")
{
Result += MiddleInitial + " ";
}
Result += LastName + "\r\n";
// Only append items from the multiline address box
// if they are entered
if ( AddressLines != "")
{
Result += AddressLines + "\r\n";
}
//if (AddressLines.Length > 0 && AddressLines.ToString() != "")
//{
// Result += AddressLines + "\r\n";
//}
Result += City;
return Result;
}
}
}
If you just want a space between those specific fields in btnAssemble_Click, you can just insert them like this:
string myStr = foo + " " + bar + " " + baz;
So your first function would be modified to read:
private void btnAssemble_Click(object sender, EventArgs e)
{
txtAssembled.Text = (cboTitle.Text + " " + txtFirstName.Text[0] + " " + txtMiddle.Text + " " + txtLastName.Text + "\r\n" + txtStreet.Text + "\r\n" + cboCity.Text);
}
A few other comments:
It's not clear to me what the AssembleText() function you posted has to do with this. I am confused though, as I see a few lines appending spaces at the end just like I mentioned above.
Using the String.Format() function may make this code easier to read and maintain.
Using Environment.NewLine instead of "\r\n" will make the string contain the newline character defined for that specific environment.
Using a StringBuilder object may be faster over concatenation when building strings inside of a loop (which may not apply here).
Using String.format() should feet the bill. It also make your code easy to read.
txt.assembled.text = String.Format("{0} {1} {2} {3}",
cboTitle.Text,
txtFirstName.Text[0],
txtMiddle.Text,
txtLastName.Text
);
It would be like this
private void btnAssemble_Click(object sender, EventArgs e)
{
txtAssembled.Text = (cboTitle.Text + " " + txtFirstName.Text[0] + " " +txtMiddle.Text + " " + txtLastName.Text + "\r\n" +txtStreet.Text + "\r\n"+ cboCity.Text);
}
It seems that you want String.Join; whenever you want to combine strings with a delimiter, say, " " (space) all you need is to put
String combined = String.Join(" ",
cboTitle.Text,
txtFirstName.Text[0],
txtMiddle.Text,
txtLastName.Text);
Complete implementation (joining by space and new line) could be
txtAssembled.Text = String.Join(Environment.NewLine,
String.Join(" ",
cboTitle.Text,
txtFirstName.Text[0],
txtMiddle.Text,
txtLastName.Text),
txtStreet.Text,
cboCity.Text);

how to increase the size of array or free the memory after each iteration. Error: Index was outside the bounds of the array c#

I read data from a text file which is 27 MB file and contains 10001 rows, I need to handle large data. I perform some kind of processing in each row of data and then write it back to a text file. This is the code I have am using
StreamReader streamReader = System.IO.File.OpenText("D:\\input.txt");
string lineContent = streamReader.ReadLine();
int count = 0;
using (StreamWriter writer = new StreamWriter("D:\\ft1.txt"))
{
do
{
if (lineContent != null)
{
string a = JsonConvert.DeserializeObject(lineContent).ToString();
string b = "[" + a + "]";
List<TweetModel> deserializedUsers = JsonConvert.DeserializeObject<List<TweetModel>>(b);
var CreatedAt = deserializedUsers.Select(user => user.created_at).ToArray();
var Text = deserializedUsers.Where(m => m.text != null).Select(user => new
{
a = Regex.Replace(user.text, #"[^\u0000-\u007F]", string.Empty)
.Replace(#"\/", "/")
.Replace("\\", #"\")
.Replace("\'", "'")
.Replace("\''", "''")
.Replace("\n", " ")
.Replace("\t", " ")
}).ToArray();
var TextWithTimeStamp = Text[0].a + " (timestamp:" + CreatedAt[0] + ")";
writer.WriteLine(TextWithTimeStamp);
}
lineContent = streamReader.ReadLine();
}
while (streamReader.Peek() != -1);
streamReader.Close();
This code helps does well up to 54 iterations as I get 54 lines in the output file. After that it gives error "Index was outside the bounds of the array." at line
var TextWithTimeStamp = Text[0].a + " (timestamp:" + CreatedAt[0] + ")";
I am not very clear about the issue if the maximum capacity of array has been violated, if so how can I increase it or If I can write the individual line encountered in loop through
writer.WriteLine(TextWithTimeStamp);
And clean the storage or something that can solve this issue. I tried using list insead of array , still issue is the same.Please help.
Change this line
var TextWithTimeStamp = Text[0].a + " (timestamp:" + CreatedAt[0] + ")";
to
var TextWithTimeStamp = (Text.Any() ? Text.First().a : string.Empty) +
" (timestamp:" + (CreatedAt.Any() ? CreatedAt.First() : string.Empty) + ")";
As you are creating Text and CreatedAt collection objects, they might be empty (0 total item) based on some scenarios and conditions.
Those cases, Text[0] and CreatedAt[0] will fail. So, before using the first element, check if there are any items in the collection. Linq method Any() is used for that purpose.
Update
If you want to skip the lines that do not contain text, change this lines
var TextWithTimeStamp = Text[0].a + " (timestamp:" + CreatedAt[0] + ")";
writer.WriteLine(TextWithTimeStamp);
to
if (Text.Any())
{
var TextWithTimeStamp = Text.First().a + " (timestamp:" + CreatedAt.First() + ")";
writer.WriteLine(TextWithTimeStamp);
}
Update 2
To include all the stringss from CreatedAt rather than only the first one, you can add all the values in comma separated strings. A general example
var strings = new List<string> { "a", "b", "c" };
var allStrings = string.Join(",", strings); //"a,b,c"

How to import into a template excel file (C#)

I have the code below to save data into a excel file(.csv).
private void SavedataToolStripMenuItem_Click(object sender, EventArgs e)
{
now_status.Text = "save data to excel";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{[![enter image description here][1]][1]
selectedFileName = saveFileDialog1.FileName + ".csv";
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("Shift_JIS");
System.IO.StreamWriter sr = new System.IO.StreamWriter(selectedFileName, false, enc);
int rowCountA = int.Parse(objA_n.Text);
int rowCountB = int.Parse(objB_n.Text);
string field;
field = "Saved Data" + "\r\n" + "Numb,Time(S),AX,AY,BX,BY" + "\r\n";
sr.Write(field);
for (int i = 1; i < rowCountA + 1; i++)
{
string fieldA;
fieldA = "A" + dn_objA[i].ToString() + "," + dtime_objA[i].ToString() + "," + dx_objA[i].ToString() + "," + dy_objA[i].ToString() + ",," + "\r\n";
sr.Write(fieldA);
}
for (int i = 1; i < rowCountB + 1; i++)
{
string fieldB;
fieldB = "B" + dn_objB[i].ToString() + "," + dtime_objB[i].ToString() + ",,," + dx_objB[i].ToString() + "," + dy_objB[i].ToString() + "\r\n";
sr.Write(fieldB);
}
sr.Close();
sr.Close();
}
}
This Generates a simple excel file like this below. Object values will be inserted below the second row.
Is there a way to do the same thing, but into a template excel file? I have an excel file like the one below.
I would like the imported data to show on the left hand side of the excel file.
Also, I want to use macros that I made in the second excel file shown.

Reading Multiple XML files

I have Created a small XML tool, to find the numbers of element present in Multiple XML files.
This code gives the fine result for the elements which are must in XML files.
But when it comes to specific elements, which may be present or not in XML files, Software give me result as:
10/8/2012 11:27:51 AM
C:\Documents and Settings\AlaspuMK\Desktop\KS\success\4CPK-PMF0-004D-P565-00000-00.xml
Instance: 0
10/8/2012 11:27:51 AM
C:\Documents and Settings\AlaspuMK\Desktop\KS\success\4CPK-PMF0-004D-P566-00000-00.xml
Instance: 0
10/8/2012 11:27:51 AM
C:\Documents and Settings\AlaspuMK\Desktop\KS\success\4CPK-PMF0-004D-P567-00000-00.xml
Instance: 0
10/8/2012 11:27:51 AM
C:\Documents and Settings\AlaspuMK\Desktop\KS\success\4CPK-PMG0-004D-P001-00000-00.xml
**Instance: 11**
10/8/2012 11:27:51 AM
C:\Documents and Settings\AlaspuMK\Desktop\KS\success\4CPK-PMG0-004D-P002-00000-00.xml
Instance: 0
Now here the problem is XML files may be 500-1000 when i search the tag which may be present or not the tool gives me result for each and every files. In this case specific tag present instance may be 0 or multiple.
Can any one suggest the changes in my Code to find the file name in which instance is greater than 0. and if instance > 0 print it in text box.
My current code:
public void SearchMultipleTags()
{
if (txtSearchTag.Text != "")
{
try
{
//string str = null;
//XmlNodeList nodelist;
string folderPath = textBox2.Text;
DirectoryInfo di = new DirectoryInfo(folderPath);
FileInfo[] rgFiles = di.GetFiles("*.xml");
foreach (FileInfo fi in rgFiles)
{
int i = 0;
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(fi.FullName);
//rtbox2.Text = fi.FullName.ToString();
foreach (XmlNode node in xmldoc.GetElementsByTagName(txtSearchTag.Text))
{
i = i + 1;
//
}
rtbox2.Text += DateTime.Now + "\n" + fi.FullName + " \nInstance: " + i.ToString() + "\n\n";
//rtbox2.Text += fi.FullName + "instances: " + str.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show("Invalid Path or Empty File name field.");
}
}
else
{
MessageBox.Show("Dont leave field blanks.");
}
}
If I understand correctly, you want to display text only if the i is greater than 0?
if(i > 0 )
rtbox2.Text += DateTime.Now + "\n" + fi.FullName + " \nInstance: " + i.ToString() + "\n\n";
Use
if(i > 0)
rtbox2.Text += DateTime.Now + "\n" + fi.FullName + " \nInstance: " + i.ToString() + "\n\n";
instead of simple
rtbox2.Text += DateTime.Now + "\n" + fi.FullName + " \nInstance: " + i.ToString() + "\n\n";
You could always just use this code inside the try block:
rtbox2.Text =
String.Join(Environment.NewLine + Environment.NewLine,
from fi in (new DirectoryInfo(textBox2.Text)).GetFiles("*.xml")
let xd = XDocument.Load(fi.FullName)
let i = xd.Descendants(txtSearchTag.Text).Count()
where i > 0
select String.Join(Environment.NewLine, new []
{
DateTime.Now.ToString(),
fi.FullName,
i.ToString(),
}));
Does it all in one line (bar the formatting). :-)

Categories