Remove space in column names from DataTable - c#

I have a DataTable which I populate from an excel sheet. The column names in the excel contain space between the two words i.e.
PRODUCT TYPE
SERIAL NUMBER
And I'm trying to achieve
PRODUCTTYPE or PRODUCT_TYPE
SERIALNUMBER or SERIAL_NUMBER
The DataTable columns are dynamically generated from the excel. I'm trying to remove the space between the words but I can't seem to get it to work. My current code for removing the white spaces looks like
foreach (DataRow dr in cloned.Rows)
{
foreach (DataColumn col in cloned.Columns)
{
dr[col] = dr[col].ToString().Replace(" ", "");
}
}
can someone tell me where I'm going wrong please.

You don't need to loop the rows if you want to modify the columns:
foreach(DataColumn c in cloned.Columns)
c.ColumnName = String.Join("_", c.ColumnName.Split());
Use String.Join("", c.ColumnName.Split()) if you want to remove the spaces.

First you don't need to loop the rows of the DataTable
foreach (DataColumn col in cloned.Columns)
{
col.ColumnName = col.ColumnName.Replace(" ","");
}

You can use the below methods too in your foreach loop.
public static string TrimAllWithSplitAndJoin(string str)
{
return string.Concat(str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));
}
static Regex whitespace = new Regex(#"\s+", RegexOptions.Compiled);
public static string TrimAllWithRegex(string str)
{
return whitespace.Replace(str, "");
}
foreach (DataColumn col in cloned.Columns)
{
col.ColumnName = TrimAllWithSplitAndJoin(col.ColumnName);
}

I think better to put checking process of the data column, when the column type is string then remove the space
if (col.DataType == typeof(System.String))
{
dr[col] = dr[col].ToString().Replace(" ", "");
}

Related

print an entire table in C#

I'm trying to print the content of a DataTable, starting with the column headers, followed by the content of the table tupples.
output.Add($"Table : [{dataTable.TableName}]");
string strColumnNames = "";
foreach (DataColumn col in dataTable.Columns)
{
if (strColumnNames == "")
strColumnNames = col.ColumnName.PadLeft(col.MaxLength - col.ColumnName.Length); // (*)
else strColumnNames = strColumnNames + "|" +
col.ColumnName.PadLeft(col.MaxLength - col.ColumnName.Length); // (*)
}
output.Add($"[{strColumnNames}]");
foreach (DataRow dataRow in dataTable.Rows)
{
string temp = "";
for (int i = 0; i < dataRow.ItemArray.Count(); i++)
{
if (i == 0)
temp = dataRow.ItemArray[i].ToString(); // (**)
else temp += "|" + dataRow.ItemArray[i].ToString(); // (**)
}
output.Add($"[{temp}]");
}
The (*) parts in this code are using the MaxLength property of the DataColumns maximum length in order to get a column-like output.
I would like to do the same in the (**) parts, but I don't know how to access the corresponding DataColumn, starting from the dataRow object.
Does anybody have an idea?
Thanks in advance
You already have the dataTable instance available. dataTable.Columns[i] should give you the appropriate DataColumn.
Datatable has already been instantiated here. If you want to print the datacolumn you should use dataTable.Column[i] for the appropriate column.

Don't split the string if contains in double marks

I have a text delimeted file need to convert into datatable. Given the text something like this :
Name,Contact,Email,Date Of Birth,Address
JOHN,01212121,hehe#yahoo.com,1/12/1987,"mawar rd, shah alam, selangor"
JACKSON,01223323,haha#yahoo.com,1/4/1967,"neelofa rd, sepang, selangor"
DAVID,0151212,hoho#yahoo.com,3/5/1956,"nora danish rd, klang, selangor"
And this is how i read the text file in C#
DataTable table = new DataTable();
using (StreamReader sr = new StreamReader(path))
{
#region Text to csv
while (!sr.EndOfStream)
{
string[] line = sr.ReadLine().Split(',');
//table.Rows.Add(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]);
if (IsRowHeader)//Is user want to read first row as the header
{
foreach (string column in line)
{
table.Columns.Add(column);
}
totalColumn = line.Count();
IsRowHeader = false;
}
else
{
if (totalColumn == 0)
{
totalColumn = line.Count();
for (int j = 0; j < totalColumn; j++)
{
table.Columns.Add();
}
}
// create a DataRow using .NewRow()
DataRow row = table.NewRow();
// iterate over all columns to fill the row
for (int i = 0; i < line.Count(); i++)
{
row[i] = line[i];
}
// add the current row to the DataTable
table.Rows.Add(row);
}
}
The column is dynamic, the user can add or remove the column on the text file. So I need to check how many column and set to datatable, after that I will read for each line, set value to datarow and then add row to table.
If I don't remove the semicolon inside the double marks, it will show the error "Cannot find column 5" because on the first line is only 4 column (start from 0).
What the best way to deal with text delimited?
Don't try and re-invent the CSV-parsing wheel. Use the parser built into .NET: Microsoft.VisualBasic.FileIO.TextFieldParser
See https://stackoverflow.com/a/3508572/7122.
No, just don't. Don't try and write your own CSV parser - there's no reason to do it.
This article explains the problem and recommends using FileHelpers - which are decent enough.
There is also the Lumenworks reader which is simpler and just as useful.
Finally apparently you can just use DataSets to link to your CSV as described here. I didn't try this one, but looks interesting, if probably outdated.
I usually go with something like this:
const char separator = ',';
using (var reader = new StreamReader("C:\\sample.txt"))
{
var fields = (reader.ReadLine() ?? "").Split(separator);
// Dynamically add the columns
var table = new DataTable();
table.Columns.AddRange(fields.Select(field => new DataColumn(field)).ToArray());
while (reader.Peek() >= 0)
{
var line = reader.ReadLine() ?? "";
// Split the values considering the quoted field values
var values = Regex.Split(line, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")
.Select((value, current) => value.Trim())
.ToArray()
;
// Add those values directly
table.Rows.Add(values);
}
// Demonstrate the results
foreach (DataRow row in table.Rows)
{
Console.WriteLine();
foreach (DataColumn col in table.Columns)
{
Console.WriteLine("{0}={1}", col.ColumnName, row[col]);
}
}
}

Write Rows from DataTable to Text File

public void GenerateDetailFile()
{
if (!Directory.Exists(AppVars.IntegrationFilesLocation))
{
Directory.CreateDirectory(AppVars.IntegrationFilesLocation);
}
DateTime DateTime = DateTime.Now;
using (StreamWriter sw = File.CreateText(AppVars.IntegrationFilesLocation +
DateTime.ToString(DateFormat) + " Detail.txt"))
{
DataTable table = Database.GetDetailTXTFileData();
foreach (DataRow row in table.Rows)
{
sw.WriteLine(row);
}
}
}
Not sure what I'm missing here but I think it might be the column name which I'm not sure how to set it up.
This is working fine, except, when it writes to the text file, it's writing this:
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
System.Data.DataRow
Can anyone give me a hand?
When you try to print out a DataRow like that, it is calling Object.ToString(), which simply prints out the name of the type. What you want to do is something like:
sw.WriteLine(String.Join(",", row.ItemArray));
This will print a comma separated list of all of the items in the DataRow.
Something like:
sw.WriteLine(row["columnname"].ToString());
would be more appropriate.
The below code will let you to write text file each column separated by '|'
foreach (DataRow row in dt.Rows)
{
object[] array = row.ItemArray;
for (int i = 0; i < array.Length - 1; i++)
{
swExtLogFile.Write(array[i].ToString() + " | ");
}
swExtLogFile.WriteLine(array[array.Length - 1].ToString());
}
Reference link
There is no "natural" string representation for a DataRow. You need to write it out in whatever format you desire, i.e., comma-separated list of values, etc. You can enumerate the columns and print their values, for instance:
foreach (DataRow row in table.Rows)
{
bool firstCol = true;
foreach (DataColumn col in table.Columns)
{
if (!firstCol) sw.Write(", ");
sw.Write(row[col].ToString());
firstCol = false;
}
sw.WriteLine();
}
You need to write the columns from each DataRow. Currently you are writing the DataRow object that is dataRow.ToString() hence you get string name "System.Data.DataRow" of dataRow in your file
foreach(DataRow row in table.Rows)
{
foreach(DataColumn column in table.Columns)
{
sw.WriteLine(row[column]);
}
}
Try this:
To write the DataTable rows to text files in the specific directory
var dir = #"D:\New folder\log"; // folder location
if (!Directory.Exists(dir)) // if it doesn't exist, create
Directory.CreateDirectory(dir);
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
result.Append(row[i].ToString());
result.Append(i == dt.Columns.Count - 1 ? "\n" : ",");
}
result.AppendLine();
}
string path = System.IO.Path.Combine(dir, "item.txt");
StreamWriter objWriter = new StreamWriter(path, false);
objWriter.WriteLine(result.ToString());
objWriter.Close();

Find a string in all DataTable columns

I am trying to find a fast way to find a string in all datatable columns!
Followed is not working as I want to search within all columns value.
string str = "%whatever%";
foreach (DataRow row in dataTable.Rows)
foreach (DataColumn col in row.ItemArray)
if (row[col].ToString() == str) return true;
You can use LINQ. It wouldn't be any faster, because you still need to look at each cell in case the value is not there, but it will fit in a single line:
return dataTable
.Rows
.Cast<DataRow>()
.Any(r => r.ItemArray.Any(c => c.ToString().Contains("whatever")));
For searching for random text and returning an array of rows with at least one cell that has a case-insensitive match, use this:
var text = "whatever";
return dataTable
.Rows
.Cast<DataRow>()
.Where(r => r.ItemArray.Any(
c => c.ToString().IndexOf(text, StringComparison.OrdinalIgnoreCase) > 0
)).ToArray();
If you want to check every row of every column in your Datatable, try this (it works for me!).
DataTable YourTable = new DataTable();
// Fill your DataTable here with whatever you've got.
foreach (DataRow row in YourTable.Rows)
{
foreach (object item in row.ItemArray)
{
//Do what ya gotta do with that information here!
}
}
Don't forget to typecast object item to whatever you need (string, int etc).
I've stepped through with the debugger and it works a charm. I hope this helps, and good luck!
This can be achieved by filtering. Create a (re-usable) filtering string based on all the columns:
bool UseContains = false;
int colCount = MyDataTable.Columns.Count;
string likeStatement = (UseContains) ? " Like '%{0}%'" : " Like '{0}%'";
for (int i = 0; i < colCount; i++)
{
string colName = MyDataTable.Columns[i].ColumnName;
query.Append(string.Concat("Convert(", colName, ", 'System.String')", likeStatement));
if (i != colCount - 1)
query.Append(" OR ");
}
filterString = query.ToString();
Now you can get the rows where one of the columns matches your searchstring:
string currFilter = string.Format(filterString, searchText);
DataRow[] tmpRows = MyDataTable.Select(currFilter, somethingToOrderBy);
You can create a routine of search with an array of strings with the names of the columns, as well:
string[] elems = {"GUID", "CODE", "NAME", "DESCRIPTION"};//Names of the columns
foreach(string column in elems)
{
string expression = string.Format("{0} like '%{1}%'",column,
txtSearch.Text.Trim());//Search Expression
DataRow[] row = data.Select(expression);
if(row.Length > 0) {
// Some code here
} else {
// Other code here
}
}
You can get names of columns by using ColmunName Method. Then, you can search every column in DataTable by using them. For example, follwing code will work.
string str = "whatever";
foreach (DataRow row in dataTable.Rows)
{
foreach (DataColumn column in dataTable.Columns)
{
if (row[column.ColumnName.ToString()].ToString().Contains(str))
{
return true;
}
}
}
You can create a filter expression on the datatable as well. See this MSDN article. Use like in your filter expression.
string filterExp = "Status = 'Active'";
string sortExp = "City";
DataRow[] drarray;
drarray = dataSet1.Customers.Select(filterExp, sortExp, DataViewRowState.CurrentRows);
for (int i=0; i < drarray.Length; i++)
{
listBox1.Items.Add(drarray[i]["City"].ToString());
}

How do I get the last cell in a row of a DataTable?

foreach(DataRow row in dt.Rows)
{
foreach(var cell in row.ItemArray)
{
builder.Append(cell.ToString());
if(cell != row.lastcell)
builder.Append("\t");
}
builder.Append(Environment.NewLine);
}
i need to make sure that cell!=the last cell in the row
how do i do this?
You don't need to do that. Just use string.Join instead:
string[] strings = Array.ConvertAll(row.ItemArray, x => x.ToString());
builder.Append(string.Join("\t", strings);
This would get you the last row:
row = (DataRow)table.Rows[table.Rows.Count-1];
You could completely avoid the last cell if you use a for loop:
for (int i=0; i<row.ItemArray-2;i++)
{
// do your code here, we are taking off the last cell with the -2
}
Use row.ItemArray[row.ItemArray.Length-1] to get a value of last cell
foreach(DataRow row in dt.Rows)
{
string separator = String.Empty;
foreach(var cell in row.ItemArray)
{
builder.Append(separator);
builder.Append(cell.ToString());
separator = "\t";
}
builder.Append(Environment.NewLine);
}

Categories