Programatically adding a dynamic number of spaces to a string - c#

I've got a treeview control, which I want to look like this:
Just by messing around with css and a text string, I'm actually pretty close. I just need some help getting over the line.
Here is the code I'm using to generate the treeview:
void FillTree_Parent()
{ // fills the parent view of the Tree Action items
//int RoleID = Convert.ToInt32(ddlRole.SelectedValue);
using (SqlConnection con4 = new SqlConnection(ConfigurationManager.ConnectionStrings["PBRConnectionString"].ConnectionString))
{
try
{
SqlCommand cmd2 = new SqlCommand("SELECT [ACCT_GRP], [ACCT_GRP_PK], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP] FROM [ACCT_GRP_LIST] ORDER BY [ACCT_GRP] ASC", con4);
SqlDataAdapter da = new SqlDataAdapter(cmd2);
DataSet PrSet = new DataSet();
da.Fill(PrSet, "ACCT_GRP");
TreeViewAccts.Nodes.Clear();
foreach (DataRow dr in PrSet.Tables[0].Rows)
{
DateTime date = DateTime.Parse(dr["LOAD_TIMESTAMP"].ToString());
string formatted = date.ToString("MM/dd/yyyy");
TreeNode tnParent = new TreeNode();
// Here is our focus
tnParent.Text = dr["ACCT_GRP"].ToString().Replace("'", "''") +
" ········· " + "Active:" + dr["ACTIVE_FLG"].ToString() +
" ········· " + "Loaded On:" + formatted + "";
//
tnParent.Value = dr["ACCT_GRP_PK"].ToString();
tnParent.PopulateOnDemand = true;
tnParent.SelectAction = TreeNodeSelectAction.SelectExpand;
TreeViewAccts.Nodes.Add(tnParent);
FillTree_Child(tnParent, tnParent.Value);
}
}
catch (Exception ae)
{
Response.Write(ae.Message);
}
}
}
In that block marked "// Here is our focus", what I need to do is figure out how to get that first set of " ········· " to generate a dynamic number of spaces based on the fact that dr["ACCT_GRP"] can have as many as 75 characters. So, I need to determine the length of dr["ACCT_GRP"], subtract that from 75 and then generate that many spaces.
Can anyone help me with this logic? Also, as a bonus question, if anyone could tell me how to use spaces instead of "·"'s I'd appreciate it; whenever I just hit the spacebar a bunch of times and enclose it in quotes, it acts like those spaces don't even exist.

int len = dr["ACCT_GRP"].Length;
int paddingLength = 75 - len;
string padding = new string('.', paddingLength);
I get it from your question that you are viewing this in a browser (you mentioned CSS). HTML spec tells the browser to collapse all consecutive whitespace into a single space. You can use the "non-breaking space" character instead. It may be written as "&nbs p;" in HTML (minus the space between s and p) or using its Unicode representation 00 A0. So your c# code becomes:
int len = dr["ACCT_GRP"].Length;
int paddingLength = 75 - len;
string padding = new string('\u00A0', paddingLength);

Related

My database query is only querying the last element of my array

My problem in the title i have allcodes array and codes TextBox (kodTxtBox)
i will split textbox like line per element and querying all elements with for loop then
when i run it, it shows the query of only the last element of the allcodes array with the
messagebox, but the others go into else and giving error message box
some turkish words in my codes so.
aciklama = description
birim = monad
birimFiyat = Price per 1 unit
ürünler = products
ürünler.sipariskod = products.ordercode etc.
i did a lot of ways for this i used foreach all variables type is string
allCodes = kodTxtBox.Text.Split('\n');
for (int i = 0; i < allCodes.Length; i++)
{
queryString = "SELECT ürünler.siparisKod, ürünler.aciklama, ürünler.birim, ürünler.fGrup, ürünler.birimfiyat FROM ürünler WHERE (((ürünler.siparisKod)=\"" + allCodes[i] + "\"));";
using (OleDbCommand query = new OleDbCommand(queryString))
{
query.Connection = connection;
reader = query.ExecuteReader();
if (reader.Read())
{
MessageBox.Show(allCodes[i] + " Succesful");
var desc = reader["aciklama"].ToString();
var monad = reader["birim"].ToString();
var sellPrice = reader["birimFiyat"].ToString();
MessageBox.Show("Açıklama: " + desc + " Birim: " + monad + " Satış Fiyatı: " + sellPrice);
reader.Close();
}
else
{
MessageBox.Show("Hata");
}
}
}
I solved the problem by making a single query instead of multiple queries. I saved the values ​​returned in each single query into a list and at the end I made the necessary for loop using the elements of the list

Auto-Breakline PdfTable Cells PdfFileWriter c#

Im writing a Programm that retrieves Cutomer Data from a SQLite-File and stores them in a PDF-File in a PdfTable like:
PdfContents contentsTable = new PdfContents(page);
PdfTable table = new PdfTable(page, contentsTable, ArialNormal, fontSize);
table.TableArea = new PdfRectangle(border (2 * border + fontHight), (210 - border), (297 - (2 * border + 4 * linespacing + 5 * fontHight))); // <- 'border', 'fontHight' and 'linespacing' are simply variables i use to define lengths that also apear at other locations
table.SetColumnWidth(30, 75, 35, 10, 30, 22, 8);
table.HeaderOnEachPage = true;
table.MinRowHight = 5;
table.Header[0].Style = table.HeaderStyle;
table.Header[1].Style = table.HeaderStyle;
table.Header[2].Style = table.HeaderStyle;
table.Header[3].Style = table.HeaderStyle;
table.Header[4].Style = table.HeaderStyle;
table.Header[5].Style = table.HeaderStyle;
table.Header[6].Style = table.HeaderStyle;
table.Header[0].Value = "CODE";
table.Header[1].Value = "BESCHREIBUNG";
table.Header[2].Value = "MATERIALNAME";
table.Header[3].Value = "NoFl";
table.Header[4].Value = "ERGEBNIST";
table.Header[5].Value = "BEWERTUNG";
table.Header[6].Value = "ART";
// Querys the 'ANALYT' and 'RESULTS' Table and Adds the Answers into the Table in the PDF-File
using (var connection = new SQLiteConnection("Data Source = " + dbFile)) // <- 'dbFile' contains the Path to the File
{
// Opens the connection to the SQLite File
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "select A.CODE, A.BESCHERIBUNG, A.MATERIALNAME, R.NORMFLAG, R.ERGEBNIST, R.BEWERTUNG, R.ART " +
"from ANALYT A, RESULTS R " +
"and A.ANALYTX = R.ANALYTX " +
"order by A.MATERIALNAME desc, R.SORT ";
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
table.Cell[0].Value = reader[0].ToString();
table.Cell[1].Value = reader[1].ToString();
table.Cell[2].Value = reader[2].ToString();
table.Cell[3].Value = reader[3].ToString();
table.Cell[4].Value = reader[4].ToString();
table.Cell[5].Value = reader[5].ToString();
table.Cell[6].Value = reader[6].ToString();
}
contentToBeAdded = true; // <- A variable i use to determine if the processes are all successfull
}
else
{
// Code that lets the user know something went wrong
}
connection.Close();
}
table.Close();
document.CreateFile();
This code works perfectly fine in almost all circumstances, but as the entrences in the Database have been collected by hundreds of people over decades, so the data values can have a wide range in length. While the Width-VAlues i entered are adequate for most situations, there can be specific entrenceses that are far longer. As the data i work with is rather critical, I cant just ignore these few cases.
My original thought was that the PdfTable would automatically Benter a new line and make the Cell higher. But when i ran into this exact problem in my testing, I noticed that the Text just kept going and was covering the next cell.
Is there an easy fix that i can tell PdfTable to do this automatically or do i have to count the number of letters in the string and devide it maually for every value that is to long?
Since I am still rather a beginner in programming, I greatly appreciate any help and input.
I've found the solution to my question and its actually quite simple. I hope that in the future someone might have the same problem and find this helpful.
Instead of adding a simple string, use PdfFileWriter.TextBox like:
PdfFileWriter.TextBox textBox0 = new PdfFileWriter.TextBox(16, 0, 0.5); // <- 16 = TextboxWidth, 0 = FirstLineIndent, 0.5 = LineBreakFactor
textBox0.AddText(ArialNormal, fontSize, reader0); // <- ArialNormal = PdfFont Variable containing a Font, fontSize = int Variable containing the Font Size, reader0 = string Variable containing the Content
table.Cell[0].Value = textBox0;
This will add the Text, AutoLineBreak and increase the Height of the Cell.
Hope anyone finds this helpful.

when I put a csv file in Sql Server with C #, some fields are written incorrectly?

Hi I have a problem with importing a csv file into a sql server, this csv file contains articles that need to be saved in the sql server database. Once the import (done with the code c # written below) is finished, some fields imported as (Descrizione and CodArt) are not written correctly in the database and have strange characters. To download the csv file click here.
SqlServer improper import over blue line:
Import C# Code:
using (var rd = new StreamReader(labelPercorso.Text))
{
Articolo a = new Articolo();
a.db = this.db;
while (!rd.EndOfStream)
{
//setto codean e immagine =null ad ogni giro
CodEAN = "";
Immagine = "";
try
{
var splits = rd.ReadLine().Split(';');
CodArt = splits[0];
Descrizione = splits[1];
String Price = splits[2];
Prezzo = decimal.Parse(Price);
}
catch (Exception ex)
{
Console.WriteLine("Non è presente nè immagine nè codean");
}
a.Prezzo = Prezzo;
a.CodiceArticolo = CodArt;
a.Descrizione = Descrizione;
a.Fornitore = fornitore;
//manca da controllare se l'articolo è presente e nel caso aggiornalo
a.InserisciArticoloCSV();
}
}
Code of function: InserisciArticoloCSV
try
{
SqlConnection conn = db.apriconnessione();
String query = "INSERT INTO Articolo(CodArt,Descrizione,Prezzo,PrezzoListino,Fornitore,Importato,TipoArticolo) VALUES(#CodArt,#Descrizione,#Prezzo,#PrezzoListino,#Fornitore,#Importato,#TipoArticolo)";
String Importato = "CSV";
String TipoArticolo = "A";
SqlCommand cmd = new SqlCommand(query, conn);
// MessageBox.Show("CodArt: " + CodiceArticolo + "\n Descrizione :" + Descrizione + "\n Prezzo: " + Prezzo);
cmd.Parameters.AddWithValue("#CodArt", CodiceArticolo.ToString());
cmd.Parameters.AddWithValue("#Descrizione", Descrizione.ToString());
cmd.Parameters.AddWithValue("#Prezzo", Prezzo);
cmd.Parameters.AddWithValue("#PrezzoListino", Prezzo);
cmd.Parameters.AddWithValue("#Fornitore", Fornitore.ToString());
cmd.Parameters.AddWithValue("#Importato", Importato.ToString());
cmd.Parameters.AddWithValue("#TipoArticolo", TipoArticolo.ToString());
cmd.ExecuteNonQuery();
db.chiudiconnessione();
conn.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Errore nell'inserimento dell'articolo " + ex);
//MessageBox.Show("Errore nel inserimento dell'articolo: " + ex);
return false;
}
Your CSV file is not well formated , there are intermediatory Carriage Returns in between , which screws up the parsing. See the file in Notepad++ and turn on the Line Breaks , this is what you find.
So for the lines which are in format the data import is working fine , for others the logic is not working.
As others have pointed out, you have numerous problems, encoding, carriage returns and a lot of white space. In addition you are using single inserts into your database, which is very slow. I show below some sample code, which illustrates how to deal with all of these points.
IFormatProvider fP = new CultureInfo("it");
DataTable tmp = new DataTable();
tmp.Columns.Add("CodArt", typeof(string));
tmp.Columns.Add("Descrizione", typeof(string));
tmp.Columns.Add("Prezzo", typeof(decimal));
using (var rd = new StreamReader("yourFileName", Encoding.GetEncoding("iso-8859-1")))
{
while (!rd.EndOfStream)
{
try
{
var nextLine = Regex.Replace(rd.ReadLine(), #"\s+", " ");
while (nextLine.Split(';').Length < 3)
{
nextLine = nextLine.Replace("\r\n", "") + Regex.Replace(rd.ReadLine(), #"\s+", " ");
}
var splits = nextLine.Split(';');
DataRow dR = tmp.NewRow();
dR[0] = splits[0];
dR[1] = splits[1];
string Price = splits[2];
dR[2] = decimal.Parse(Price, fP);
tmp.Rows.Add(dR);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
using (var conn = db.apriconnessione())
{
var sBC = new SqlBulkCopy(conn);
conn.Open();
sBC.DestinationTableName = "yourTableName";
sBC.WriteToServer(tmp);
conn.Close();
}
Now for some explanation:
Firstly I am storing the parsed values in a DataTable. Please note that I have only included the three fields that are in the CSV. In practice you must supply the other columns and fill the extra columns with the correct values for each row. I was simply being lazy, but I am sure you will get the idea.
I do not know what encoding your csv file is, but iso-8859-1 worked for me!
I use Regex to replace multiple white space with a single space.
If any line does not have the required number of splits, I keep adding further lines (having deleted the carriage return) until I hit success!
Once I have a complete line, I can now split it, and assign it to the new DataRow (please see my comments above for extra columns).
Finally once the file has been read, the DataTable will have all the rows and can be uploaded to your database using BulkCopy. This is very fast!
HTH
PS Some of your lines have double quotes. You probably want to get rid of these as well!
You should specify the correct encoding when you read your file. Is it utf? Is it ascii with a specific code page? You should also specify the SqlDbType of your Sql parameters, especially the string parameters which will be either varchar or nvarchar and there is a big difference between them.
// what is the encoding of your file? This is an example using code page windows-1252
var encoding = Encoding.GetEncoding("windows-1252");
using (var file = File.Open(labelPercorso.Text, FileMode.Open))
using (var reader = new StreamReader(file, encoding))
{
// rest of code unchanged
}
Sql Code. Note that I added using blocks for the types that implement IDisposable like Connection and Command.
try
{
String query = "INSERT INTO Articolo(CodArt,Descrizione,Prezzo,PrezzoListino,Fornitore,Importato,TipoArticolo) VALUES(#CodArt,#Descrizione,#Prezzo,#PrezzoListino,#Fornitore,#Importato,#TipoArticolo)";
String Importato = "CSV";
String TipoArticolo = "A";
using(SqlConnection conn = db.apriconnessione())
using(SqlCommand cmd = new SqlCommand(query, conn))
{
// -1 indicates you used MAX like nvarchar(max), otherwise use the maximum number of characters in the schema
cmd.Parameters.Add(new SqlDbParameter("#CodArt", SqlDbType.NVarChar, -1)).Value = CodiceArticolo.ToString();
cmd.Parameters.Add(new SqlDbParameter("#Descrizione", SqlDbType.NVarChar, -1)).Value = Descrizione.ToString();
/*
Rest of your parameters created in the same manner
*/
cmd.ExecuteNonQuery();
db.chiudiconnessione();
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("Errore nell'inserimento dell'articolo " + ex);
//MessageBox.Show("Errore nel inserimento dell'articolo: " + ex);
return false;
}
Just in case if you are interested in exploring library to handle all parsing needs with few lines of code, you can check out the Cinchoo ETL - an open source library. Here is sample to parse the csv file and shows how to get either datatable or list of records for later to load them to database.
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("it");
using (var p = new ChoCSVReader("Bosch Luglio 2017.csv")
.Configure((c) => c.MayContainEOLInData = true) //Handle newline chars in data
.Configure(c => c.Encoding = Encoding.GetEncoding("iso-8859-1")) //Specify the encoding for reading
.WithField("CodArt", 1) //first column
.WithField("Descrizione", 2) //second column
.WithField("Prezzo", 3, fieldType: typeof(decimal)) //third column
.Setup(c => c.BeforeRecordLoad += (o, e) =>
{
e.Source = e.Source.CastTo<string>().Replace(#"""", String.Empty); //Remove the quotes
}) //Scrub the data
)
{
var dt = p.AsDataTable();
//foreach (var rec in p)
// Console.WriteLine(rec.Prezzo);
}
Disclaimer: I'm the author of this library.

Index was outside the bounds of the array in MSCORLIB.DLL

I will be amazed if I find a solution for this, since it is very specific and vague, but I figured I would try. I'll try to give as much information as humanly possible, since I've been searching for answers for some time now.
I am building a utility in C# which copies records from a file in a library on the i-series/AS400 and builds an encrypted text file with each record from the AS400 as a comma separated string. In the file, it will have values like filename, fieldvalue1, fieldvalue2, fieldvalue3. I then take that text file to another PC, and run a C# utility which copies that record into the same file name in a library over there on a different i-series machine. Unfortunately, I receive the outside bounds of the array exception in some cases, but I cannot determine why. In the record just prior to the exception, the record looks pretty much the same and it works fine. My code is below in a nutshell. I usually don't give up, but I don't expect to ever figure this out. If someone does, I'll probably sing karaoke tonight.
// Select records from AS400 file and write them to text file
Recordset rs = new Recordset();
sqlQuery = "SELECT * FROM " + dataLibrary + "." + fileName;
try
{
rs.Open(sqlQuery, con);
while (!rs.EOF)
{
int[] fieldLengths;
fieldLengths = new int[rs.Fields.Count];
String[] fieldValues;
fieldValues = new String[rs.Fields.Count];
String fullString = "";
for (i = 0; i < rs.Fields.Count; i++)
{
fieldLengths[i] += rs.Fields[i].DefinedSize;
fieldValues[i] += rs.Fields[i].Value;
}
fullString = fileName + "," + String.Join(",", fieldValues);
fullString = Functions.EncryptString(fullString);
File.AppendAllText(savefile.FileName, fullString + Environment.NewLine);
rs.MoveNext();
}
}
catch (Exception ex)
{
}
cmd.Dispose();
// This gives me a text file of filename, fieldvalue1, fieldvalue2, etc...
// Next, I take the file to another system and run this process:
while ((myString = inputFile.ReadLine()) != null)
{
int stringLength = myString.Length;
String[] valuesArray = myString.Split(',');
for (i = 0; i < valuesArray.Length; i++)
{
if (i == 0)
{
fileName = valuesArray[0];
// Create file if it doesn't exist already
createPhysicalFile(newLibrary, fileName);
SQLStatement = "INSERT INTO " + newLibrary + "." + fileName + "VALUES(";
}
else
{
if (i == valuesArray.Length - 1)
{
SQLStatement += "#VAL" + i + ")";
}
else
{
SQLStatement += "#VAL" + i + ", ";
}
}
}
try
{
using (connection)
{
try
{
connection.Open();
}
catch (Exception ex)
{
}
// Create a new SQL command
iDB2Command command = new iDB2Command(SQLStatement, connection);
for (i = 1; i < valuesArray.Length; i++)
{
try
{
command.Parameters.AddWithValue("#VAL" + i, (valuesArray[i]));
}
catch (Exception ex)
{
}
}
// Just split the array into a string to visually check
// differences in the records
String arraySplit = ConvertStringArrayToString(valuesArray);
// The query gets executed here. The command looks something
// like:
// INSERT INTO LIBNAME.FILENAME VALUES(#VAL!, #VAL2, #VAL3, #VAL4)
// There are actually 320 fields in the file I'm having a problem with,
// so it's possible I'm overlooking something. I have narrowed it down to
// field # 316 when the exception occurs, but in both cases
// field 316 is blanks (when it works and when it doesn't).
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
// Here I get the exception out of bounds error in MSCORLIB.DLL.
// Some records are added fine, while others cause this exception.
// I cannot visibly tell any major differences, nor do I see any
// errors in the AS400 job log or anything in C# that would lead me
// down a certain path.
String error = ex.Message;
}
}
For what it's worth, I found this happening one a smaller file in the system and was able to figure out what going on, after painstaking research into the code and the net. Basically, the file file has numeric fields on the i-series. Somehow, the records were written to the file on the original system with null values in the numeric fields instead of numeric values. When storing the original records, I had to do this calculation:
String fieldType = rs.Fields[i].Type.ToString();
object objValue = rs.Fields[i].Value;
if (fieldType == "adNumeric" && objValue is DBNull)
{
fieldValues[i] += "0";
}
else
{
fieldValues[i] += rs.Fields[i].Value;
}
After this, if null values were found in one of the numeric fields, it just put "0" in it's place so that when writing to the new machine, it would put a valid numeric character in there and continue on writing the rest of the values. Thanks for all the advice and moral support. :)

CSV parser to parse double quotes via OLEDB

How can I use OLEDB to parse and import a CSV file that each cell is encased in double quotes because some rows contain commas in them?? I am unable to change the format as it is coming from a vendor.
I am trying the following and it is failing with an IO error:
public DataTable ConvertToDataTable(string fileToImport, string fileDestination)
{
string fullImportPath = fileDestination + #"\" + fileToImport;
OleDbDataAdapter dAdapter = null;
DataTable dTable = null;
try
{
if (!File.Exists(fullImportPath))
return null;
string full = Path.GetFullPath(fullImportPath);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=No;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
dTable = new DataTable();
//create an OleDbDataAdapter to execute the query
dAdapter = new OleDbDataAdapter(query, connString);
//fill the DataTable
dAdapter.Fill(dTable);
}
catch (Exception ex)
{
throw new Exception(CLASS_NAME + ".ConvertToDataTable: Caught Exception: " + ex);
}
finally
{
if (dAdapter != null)
dAdapter.Dispose();
}
return dTable;
}
When I use a normal CSV it works fine. Do I need to change something in the connString??
Use a dedicated CSV parser.
There are many out there. A popular one is FileHelpers, though there is one hidden in the Microsoft.VisualBasic.FileIO namespace - TextFieldParser.
Have a look at FileHelpers.
You can use this code : MS office required
private void ConvertCSVtoExcel(string filePath = #"E:\nucc_taxonomy_140.csv", string tableName = "TempTaxonomyCodes")
{
string tempPath = System.IO.Path.GetDirectoryName(filePath);
string strConn = #"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + tempPath + #"\;Extensions=asc,csv,tab,txt";
OdbcConnection conn = new OdbcConnection(strConn);
OdbcDataAdapter da = new OdbcDataAdapter("Select * from " + System.IO.Path.GetFileName(filePath), conn);
DataTable dt = new DataTable();
da.Fill(dt);
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(ConfigurationSettings.AppSettings["dbConnectionString"]))
{
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = 50;
bulkCopy.WriteToServer(dt);
}
}
There is a lot to consider when handling CSV files. However you extract them from the file, you should know how you are handling the parsing. There are classes out there that can get you part way, but most don't handle the nuances that Excel does with embedded commas, quotes and line breaks. However, loading Excel or the MS classes seems a lot of freaking overhead if you just want parse a txt file like a CSV.
One thing you can consider is doing the parsing in your own Regex, which will also make your code a little more platform independent, in case you need to port it to another server or application at some point. Using regex has the benefit of also being accessible in virtually every language. That said, there are some good regex patterns out there that handle the CSV puzzle. Here is my shot at it, which does cover embedded commas, quotes and line breaks. Regex code/pattern and explanation :
http://www.kimgentes.com/worshiptech-web-tools-page/2008/10/14/regex-pattern-for-parsing-csv-files-with-embedded-commas-dou.html
Hope that is of some help..
Try the code from my answer here:
Reading CSV files in C#
It handles quoted csv just fine.
private static void Mubashir_CSVParser(string s)
{
// extract the fields
Regex RegexCSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
String[] Fields = RegexCSVParser.Split(s);
// clean up the fields (remove " and leading spaces)
for (int i = 0; i < Fields.Length; i++)
{
Fields[i] = Fields[i].TrimStart(' ', '"');
Fields[i] = Fields[i].TrimEnd('"');// this line remove the quotes
//Fields[i] = Fields[i].Trim();
}
}
Just incase anyone has a similar issue, i wanted to post the code i used. i did end up using Textparser to get the file and parse ot the columns, but i am using recrusion to get the rest done and substrings.
/// <summary>
/// Parses each string passed as a "row".
/// This routine accounts for both double quotes
/// as well as commas currently, but can be added to
/// </summary>
/// <param name="row"> string or row to be parsed</param>
/// <returns></returns>
private List<String> ParseRowToList(String row)
{
List<String> returnValue = new List<String>();
if (row[0] == '\"')
{// Quoted String
if (row.IndexOf("\",") > -1)
{// There are more columns
returnValue = ParseRowToList(row.Substring(row.IndexOf("\",") + 2));
returnValue.Insert(0, row.Substring(1, row.IndexOf("\",") - 1));
}
else
{// This is the last column
returnValue.Add(row.Substring(1, row.Length - 2));
}
}
else
{// Unquoted String
if (row.IndexOf(",") > -1)
{// There are more columns
returnValue = ParseRowToList(row.Substring(row.IndexOf(",") + 1));
returnValue.Insert(0, row.Substring(0, row.IndexOf(",")));
}
else
{// This is the last column
returnValue.Add(row.Substring(0, row.Length));
}
}
return returnValue;
}
Then the code for Textparser is:
// string pathFile = #"C:\TestFTP\TestCatalog.txt";
string pathFile = #"C:\TestFTP\SomeFile.csv";
List<String> stringList = new List<String>();
TextFieldParser fieldParser = null;
DataTable dtable = new DataTable();
/* Set up TextFieldParser
* use the correct delimiter provided
* and path */
fieldParser = new TextFieldParser(pathFile);
/* Set that there are quotes in the file for fields and or column names */
fieldParser.HasFieldsEnclosedInQuotes = true;
/* delimiter by default to be used first */
fieldParser.SetDelimiters(new string[] { "," });
// Build Full table to be imported
dtable = BuildDataTable(fieldParser, dtable);
This is what I used in a project, parses a single line of data.
private string[] csvParser(string csv, char separator = ',')
{
List <string> parsed = new List<string>();
string[] temp = csv.Split(separator);
int counter = 0;
string data = string.Empty;
while (counter < temp.Length)
{
data = temp[counter].Trim();
if (data.Trim().StartsWith("\""))
{
bool isLast = false;
while (!isLast && counter < temp.Length)
{
data += separator.ToString() + temp[counter + 1];
counter++;
isLast = (temp[counter].Trim().EndsWith("\""));
}
}
parsed.Add(data);
counter++;
}
return parsed.ToArray();
}
http://zamirsblog.blogspot.com/2013/09/c-csv-parser-csvparser.html

Categories

Resources