Why the result is always appear on the 1st row? - c#

I'm exporting data from SQLite into .csv but I got problem on rows why the result is always appear in the 1st row? did I miss something??
RESULT:
My Code:
private void DataExport()
{
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Choose file to save to",
FileName = ".csv",
Filter = "CSV (*.csv)|*.csv",
FilterIndex = 0,
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};
if (saveFileDialog.ShowDialog() == true)
{
SQLiteCommand cmd = new SQLiteCommand();
String sSQL;
sSQL = "select * from Tile1";
cmd.CommandText = sSQL;
clsCon.con.Open();
cmd.Connection = clsCon.con;
SQLiteDataReader dr2;
dr2 = cmd.ExecuteReader();
dr2.Read();
DataSet _dataSet = new DataSet();
DataTable _dataTable = new DataTable();
for (var i = 0; i < dr2.FieldCount; i++)
{
_dataTable.Columns.Add("" + dr2.GetName(i) + "", typeof(string));
_dataTable.Rows.Add("" + dr2.GetValue(i) + "");
}
var rows = _dataTable.Rows;
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = _dataTable.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
sb.AppendLine(string.Join(",", fields));
}
File.WriteAllText(saveFileDialog.FileName, sb.ToString());
clsCon.con.Close();
}
}

it looks the DataTable object has not been filled correctly, check the part here:
for (var i = 0; i < dr2.FieldCount; i++)
{
_dataTable.Columns.Add("" + dr2.GetName(i) + "", typeof(string));
_dataTable.Rows.Add("" + dr2.GetValue(i) + "");
}
I guess you tried to set up columns of the data table here, but you can't append rows in the same time, you actually add each column values of the first row into different rows. The table you generated would be like this:
col1 col2 col3 col4
row1 val(1,1)
row2 val(1,2)
row3 val(1,3)
row4 val(1,4)
val(x,y) means value at column y and row x in database.
#Darin Dimitrov 's solution works very well for your issue.

Try simplifying your code a bit, I mean those DataTables and DataSets are driving me nuts:
private void DataExport()
{
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Choose file to save to",
FileName = ".csv",
Filter = "CSV (*.csv)|*.csv",
FilterIndex = 0,
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};
if (!saveFileDialog.ShowDialog())
{
return;
}
using (var conn = new SQLiteConnection(ConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT * FROM Tile1";
using (var reader = cmd.ExecuteReader())
using (var writer = new StreamWriter(saveFileDialog.FileName))
{
var columnNames = Enumerable
.Range(0, reader.FieldCount)
.Select(reader.GetName);
string header = string.Join(", ", columnNames);
writer.WriteLine(header);
while (reader.Read())
{
var values = Enumerable
.Range(0, reader.FieldCount)
.Select(reader.GetValue);
string valuesRow = string.Join(", ", values);
writer.WriteLine(valuesRow);
}
}
}
}

Related

C# Cannot access DataTables column via its columnname

I have a DataTable which I save into a CSV file.
If I now read that CSV file and fill the value of it into a new DataTable the first column has a questionmark before it. Like '?Strasse'.
I guess there is a encoding issue, but I don't know how to fix it.
Code that generates CSV:
private static void SaveProgressToCSV(List<DataTable> dts)
{
int count = 0;
_pathToCSVs = new List<string>();
foreach (DataTable dt in dts)
{
count++;
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in dt.Rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field =>
string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
sb.AppendLine(string.Join(",", fields));
}
File.WriteAllText(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + #"\save"+ count + ".csv", sb.ToString(), Encoding.UTF8);
_pathToCSVs.Add(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + #"\save" + count + ".csv");
}
}
Code that reads CSV:
private static void ReadCSVIntoDataTable()
{
DataTable = new List<System.Data.DataTable>();
foreach (String pathToSave in _pathToSave)
{
DataTable dt = new System.Data.DataTable();
string pathOnly = Path.GetDirectoryName(pathToSave);
string fileName = Path.GetFileName(pathToSave);
string sql = #"SELECT * FROM [" + fileName + "]";
using (OleDbConnection connection = new OleDbConnection(
#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
";Extended Properties=\"Text;HDR=Yes;CharacterSet=65001;\""))
using (OleDbCommand command = new OleDbCommand(sql, connection))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
adapter.Fill(dt);
}
DataTable.Add(dt);
}
}
Like #juharr mentioned in the comments, I tried a CSV parser library.
The one I choose was the GenericParser.
Here the code including the GenericParser that fixed my encoding issue:
private static void ReadCSVIntoDataTable()
{
foreach (String pathToSave in _pathToSave)
{
var adapter = new GenericParsing.GenericParserAdapter(pathToSave, Encoding.UTF8);
adapter.FirstRowHasHeader = true;
DataTable dt = adapter.GetDataTable();
DataTableToExpose.Add(dt);
}
}
Thanks for the help #everyone.

Get DocumentText from Excel

I need to get all document formatted text from an excel spreadsheet.
I need a better solution that this. This achieves my goal but does not scale at all!
StringBuilder strData = new StringBuilder();
var worksheets = ReferenceDocument.Worksheets;
foreach (Excel._Worksheet worksheet in worksheets)
{
foreach (var cell in worksheet.UsedRange.Cast<Excel.Range>())
{
object value = cell.Text;
string strValue = value == null ? null : value.ToString();
if (!String.IsNullOrWhiteSpace(strValue)) strData.AppendLine(strValue);
}
}
EDIT: I've tried calling worksheet.UsedRange.Text to get an array of strings, but unfortunately it returns System.DbNull and not an array.
I couldn't find anything in the Excel object model I could use. I solved issue by using OleDb
StringBuilder strData = new StringBuilder();
ReferenceDocument.SaveCopyAs(strSomeTempFile);
var cnnStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended properties=\"Excel 8.0;IMEX=1;HDR=NO\"", strSomeTempFile);
var cnn = new OleDbConnection(cnnStr);
try
{
cnn.Open();
var schemaTable = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach(DataRow schemaRow in schemaTable.Rows)
{
string worksheetName = schemaRow["table_name"].ToString().Replace("'", "");
string sql = String.Format("select * from [{0}]", worksheetName);
var da = new OleDbDataAdapter(sql, cnn);
var dt = new DataTable();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
foreach (DataColumn col in dt.Columns)
{
var value = row[col.ColumnName];
if (!(value is System.DBNull)) strData.AppendLine(value.ToString());
}
}
}
catch (Exception e)
{
// handle error
throw;
}
finally
{
cnn.Close();
}
return strData;

Displaying data in a datagrid

I am trying to display these xml strings in a datagrid. I don't know much about datasets, but it does not seem to keep the data previously entered. Here is my code.
C#:
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string rdr = reader[i].ToString();
dataList.Add(rdr);
string column = reader.GetName(i);
const string xmlAttributeFormat = "{0} = \"{1}\" ";
xmlString = xmlString + String.Format(xmlAttributeFormat, column, dataList[i]);
}
string FinalXMLString = "<row " + xmlString + " />";
StringReader streamreader = new System.IO.StringReader(FinalXMLString);
XmlTextReader xmlreader = new System.Xml.XmlTextReader(streamreader);
dataSet = new System.Data.DataSet();
dataSet.ReadXml(xmlreader);
xmlString = "";
dataList.Clear();
FinalXMLString = "";
}
I have a while loop that is going through the query and then a for loop to put the values in a list. This is working perfectly. The data is then being put into a dataset which is then binded to the datagrid. The only problem is it only shows the data from the last line read from the query. How do I make it show all of the rows from the query in the datagrid? Any help would be appreciated. Thanks in advanced.
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
string rdr = reader[i].ToString();
dataList.Add(rdr);
string column = reader.GetName(i);
}
}
Display_Grid(myGrid,dataList)
public static void Display_Grid(DataGrid d, List<string> S1)
{
ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
DataColumn cl = new DataColumn(column, typeof(string));
cl.MaxLength = 200;
dt.Columns.Add(cl);
int i = 0;
foreach (string s in S1)
{
DataRow rw = dt.NewRow();
rw["Description"] = S1[i];
i++;
}
d.ItemsSource = ds.Tables[0].AsDataView();
}
you pass the name of your datagrid (d) and the string List (s1) as parameters ad inside the code you define the name of the columhn header of to be shown (I have written Description).
In your case S1=datalist.
if datalist contains e.g 3 elements then the method will iterate through those and produce 3 rows...

Select and Insert command OLEDB Command c#

I have a excel sheet with two tabs so i want to get a row from one tab and insert into another,i thought it would be same like in sqlserver or mysql . Just select and insert..
I am using this query but it says syntax error not sure what is wrong in it.
testCommand.CommandText = "Insert into [ActiveLicenses$]( Select * from [companies$]
where [License Number] = '" + lnumber + "')";
testCommand.ExecuteNonQuery();
UPDATE
Is there any way to delete the rows directly from excel sheet?
You can use SQL to extract the data from Excel:
using (OleDbDataAdapter da = new OleDbDataAdapter(
"SELECT " + columns + " FROM [" + worksheetName + "$]", conn))
{
DataTable dt = new DataTable(tableName);
da.Fill(dt);
ds.Tables.Add(dt);
}
Unfortunately inserting into excel doesn't work this way. I am pretty sure you cant specify a cell to write to using OleDb Insert Command, it will automatically go to the next open row in the specified column. You can workaround it with an update statement:
sql = "Update [Sheet1$A1:A10] SET A10 = 'YourValue'";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
Personally I would use VSTO rather than oleDB. Once you have extracted the cell simply open up the spreadsheet with code and insert the data:
Excel.Workbook wb = xlApp.Workbooks.Open(filePath);
rng = wb.Range["A1"];
rng.Value2 = "data";
A faster method.
I take all the licenses into a DataTable and remove the ones not required takes less than 1 minute. and then simply export DataTable to Csv so i have the file ready in less than 1 minute.
Sample below:
static List<string> licensecAll = new List<string>();
DataTable dt = new DataTable();
OleDbDataAdapter dp = new OleDbDataAdapter("select * from [companies$]", testCnn);
dp.Fill(dt);
if (dt.Rows.Count > 0)
{
for (int i = dt.Rows.Count-1; i >= 0; i--)
{
string lnum = dt.Rows[i][0].ToString();
Console.WriteLine("LICENSE NUMBER" + lnum);
if (!licensecAll.Contains(lnum))
{
Console.WriteLine("ROW REMOVED");
dt.Rows.RemoveAt(i);
}
}
}
Then simply run datatable to csv....
public static void DataTable2CSV(DataTable table, string filename, string seperateChar)
{
StreamWriter sr = null;
try
{
sr = new StreamWriter(filename);
string seperator = "";
StringBuilder builder = new StringBuilder();
foreach (DataColumn col in table.Columns)
{
builder.Append(seperator).Append(col.ColumnName);
seperator = seperateChar;
}
sr.WriteLine(builder.ToString());
foreach (DataRow row in table.Rows)
{
seperator = "";
builder = new StringBuilder();
foreach (DataColumn col in table.Columns)
{
builder.Append(seperator).Append(row[col.ColumnName]);
seperator = seperateChar;
}
sr.WriteLine(builder.ToString());
}
}
finally
{
if (sr != null)
{
sr.Close();
}
}
}

The First Column of the excel file to put in string variable C#?

What i need id to take the first column of an excel file and put that column in a string variable but numbers that will be taken from excel to be separated with blank space.
For Example:
Excel file:
1
3
4
56
76
7
876
23
43
(in column)
and string in C#
string number = "1 3 4 56 76 7 876 23 43"
Any code will help me
I have made the connection with excel file and i have created the dataset/datatable
but now i can not take those numbers as the sample above ?
If you have the data in a datset...you can do something like this....
////TRY THIS!!!
DataSet dsExcelContent = new DataSet();
//Fill from db
//
StringBuilder builder = new StringBuilder();
foreach (DataRow row in dsExcelContent.Tables[0].Rows)
{
builder.Append(row[0].ToString());
builder.Append(" ");
}
Console.WriteLine(builder.ToString());
.....More exact to your code....
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [sheet1$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet dsExcelContent = new DataSet();
DataTable dsExcelContent1 = new DataTable();
objAdapter1.Fill(dsExcelContent);
dataGridView1.DataSource = dsExcelContent1;
objConn.Close();
int test = dsExcelContent.Tables[0].Rows.Count;
StringBuilder builder = new StringBuilder();
foreach (DataRow row in dsExcelContent.Tables[0].Rows)
{
builder.Append(row[0].ToString());
builder.Append(" ");
}
//s has the data you want.....
string s = builder.ToString();
//REST OF YOUR CODE.....
Have a link - Reading Excel Document
Here's what I would do...first open the spreadsheet with this code.
xlApp = New Excel.Application
filePath = "FILENAME"
xlWorkBook = xlApp.Workbooks.Open(filePath)
xlWorkSheet = xlWorkBook.Worksheets(1)
Then read through the column like this
For data As Integer = 0 To 8
Dim obj As Excel.Range = CType(xlWorkSheet.Cells(data, 1), Range)
If obj.Value IsNot Nothing Then
MyArray(data) = obj.Value
Else
Exit Do
End If
Next
Then you should have all your data in MyArray then loop through and create a string with spaces and you should be good. This code is in VB but it should give you a good idea of the commands and structure to use.
private void Form1_Load(object sender, EventArgs e)
{
String sConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=unsorted.xls;Extended Properties=""Excel 12.0;HDR=NO;""";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [sheet1$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet dsExcelContent = new DataSet();
DataTable dsExcelContent1 = new DataTable();
objAdapter1.Fill(dsExcelContent);
dataGridView1.DataSource = dsExcelContent1;
objConn.Close();
int test = dsExcelContent.Tables[0].Rows.Count;
foreach(DataRow row in dsExcelContent.Tables[0].Rows)
{
StringBuilder builder = new StringBuilder();
foreach (DataColumn col in dsExcelContent.Tables[0].Columns)
{
builder.Append(row[col].ToString());
builder.Append(" ");
}
string s = builder.ToString();
this.label1.Text = s;
string[] numbers = s.Split(' ');
ArrayList numberList = new ArrayList();
int i;
foreach (String num in numbers)
{
if (Int32.TryParse(num, out i))
{
numberList.Add(i);
}
else
Console.WriteLine("'{0}' is not a number!", num);
}
this.listBox1.DataSource = numberList;
}
}
}
You just want to loop through the rows in the Dataset now:
var numberStr = EmptyStr;
foreach (DataRow dr in MyDataSet.Tables[0].Rows)
{
numberStr = EmptyStr ? numberStr += dr[0].ToString() : numberStr += " " + dr[0].ToString();
}
Updated Solution
private void Form1_Load(object sender, EventArgs e)
{
String s = String.Empty;
String sConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;DataSource=unsorted.xls;Extended Properties=""Excel 12.0;HDR=NO;""";
using (OleDbConnection conn = new OleDbConnection(sConnectionString))
{
conn.Open();
DataTable schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow schemaRow in schemaTable.Rows)
{
string sheet = schemaRow["TABLE_NAME"].ToString();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + sheet + "]", conn);
cmd.CommandType = CommandType.Text;
DataTable outputTable = new DataTable(sheet);
output.Tables.Add(outputTable);
new OleDbDataAdapter(cmd).Fill(outputTable);
}
// populate string with value from rows
foreach (DataRow dr in MyDataSet.Tables[0].Rows)
{
s = String.Empty ? s += dr[0].ToString() : s += " " + dr[0].ToString();
}
dataGridView1.DataSource = dsExcelContent1;
objConn.Close();
}
this.label1.Text = s;
string[] numbers = s.Split(' ');
ArrayList numberList = new ArrayList();
int i;
foreach (String num in numbers)
{
if (Int32.TryParse(num, out i))
{
numberList.Add(i);
}
else
{
Console.WriteLine("'{0}' is not a number!", num);
}
}
this.listBox1.DataSource = numberList;
}

Categories

Resources