OleDB selecting multiple CSVs with first row as field names in C# - c#

So my code looks like this currently, which is all fine and good
String q = "SELECT * FROM "+"test.csv";
try
{
OleDbConnection cn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\;Extended Properties=\"Text;HDR=No;FMT=Delimited\"");
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
OleDbCommand cd = new OleDbCommand(q, cn);
cn.Open();
da.SelectCommand = cd;
ds.Clear();
da.Fill(ds, "CSV");
dataGridView1.DataSource = ds.Tables[0];
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("There was an issue: " + ex.Message);
}
However, I would like to take the first row in my CSV and use that as the field names, so I can do something like
"select a.ID, a.SOMETHING_ELSE from test.csv a"
where the CSV looks something like
ID,SOMETHING_ELSE,DONT_WANT_THIS
1,blah,I don't want to see this
Yet, from what I see, about all examples on the web show nothing other than select *, and I would like my datagrid to show the headers as the field names selected, instead of F1, F2....
Is this implemented anywhere?

Change your connection string to include HDR=Yes (instead of HDR=No):
OleDbConnection cn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\;Extended Properties=\"Text;HDR=Yes;FMT=Delimited\"");
For OleDB, the HDR property in the connection string indicates whether or not the first row contains the column names.

Related

Output data from DataTables within DataSet

I currently accessing a database using multiple queries and storing the results from the queries into DatatTables. I decided since I'm using multiple DataTables to store them inside a DataSet.
I can see that data is inside the DataTables when I print them out. However when I try to access them from the DataSet to print out the data, I get nothing back; it is empty.
string querytest1 = "SELECT * FROM test1";
string querytest2 = "SELECT * FROM test2";
string querytest3 = "SELECT * FROM test3";
using(OleDbConnection connection = new OleDbConnection(connectionString)){
OleDbCommand commandtest1 = new OleDbCommand(querytest1 , connection);
OleDbCommand commandtest2 = new OleDbCommand(querytest2 , connection);
OleDbCommand commandtest3 = new OleDbCommand(querytest3 , connection);
connection.Open();
DataSet dataSet = new DataSet();
OleDbDataAdapter dataAdaptertest1 = new OleDbDataAdapter(commandResults);
OleDbDataAdapter dataAdaptertest2 = new OleDbDataAdapter(commandResults);
OleDbDataAdapter dataAdaptertest3 = new OleDbDataAdapter(commandProjects);
DataTable dataTabletest1 = new DataTable();
DataTable dataTabletest2 = new DataTable();
DataTable dataTabletest3 = new DataTable();
dataAdaptertest1.Fill(dataTabletest1 );
dataAdaptertest2.Fill(dataTabletest2 );
dataAdaptertest3.Fill(dataTabletest3 );
dataTabletest1 = dataSet.Tables.Add("test1 ");
dataTabletest2 = dataSet.Tables.Add("test2 ");
dataTabletest3 = dataSet.Tables.Add("test3 ");
Console.WriteLine("DataSet has {0} DataTables \n", dataSet.Tables.Count);
foreach (DataTable objDt in dataSet.Tables)
Console.WriteLine("{0}", objDt.TableName);
return dataSet;
Expected behaviour: is to be able to access a DataTable from the DataSet and print out the data.
Example: Print out the contents in Test1
The code is redundant. I just don't know a better way to do this.
You don't need three adapters to fill a DataSet with the results from three commands.
You can simply write:
string query1 = "SELECT * FROM test1";
string query2 = "SELECT * FROM test2";
string query3 = "SELECT * FROM test3";
DataSet dataSet = new DataSet();
using(OleDbConnection connection = new OleDbConnection(connectionString)){
connection.Open();
OleDbCommand cmd = new OleDbCommand(q1, connection);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test1");
cmd.CommandText = q2;
da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test2");
cmd.CommandText = q3;
da = new OleDbDataAdapter(cmd);
da.Fill(ds, "Test3");
}
Console.WriteLine("DataSet has {0} DataTables \n", ds.Tables.Count);
foreach (DataTable objDt in ds.Tables)
Console.WriteLine("{0}", objDt.TableName);
The trick is filling the same DataSet three times instead of three different DataTables and giving at each fill a different name for each table created.
But, don't you see that dataSet.Tables.Add() call actually creates new DataTable instance, and trying to set its TableName property to "test1 " (btw. take care, space is not allowed in TableName).
That newly created instance(s) are set to properties dataTabletest1...3 - so, you lose access to the original ones, initially populated with data from the database.
You should do something like this:
DataTable dataTabletest1 = dataSet.Tables.Add("Test1");
DataTable dataTabletest2 = dataSet.Tables.Add("Test2");
DataTable dataTabletest3 = dataSet.Tables.Add("Test3");
dataAdaptertest1.Fill(dataTabletest1);
dataAdaptertest2.Fill(dataTabletest2);
dataAdaptertest3.Fill(dataTabletest3);
Please, check: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/dataset-datatable-dataview/adding-a-datatable-to-a-dataset

Filtering by user input getting error message can not get table 0

I have wrote code following a tutorial posted here
http://csharp.net-informations.com/datagridview/csharp-datagridview-filter.htm
However I keep getting the error "Cannot find table 0", I have tried several things but none have worked
i have posted the code in my form load and the button to start the process
string connectionString = "server=localhost;user id=root;database=epas=";
string sql = "SELECT * FROM pricing sterling";
SqlConnection con = new SqlConnection(connectionString);
SqlDataAdapter dataadapter = new SqlDataAdapter(sql, con);
con.Open();
dataadapter.Fill(ds, "pricing table");
con.Close();
dataGridView1.DataSource = ds.Tables[0];
And the button
DataView dv;
dv = new DataView(ds.Tables[0], "ID = '21' ", "type Desc", DataViewRowState.CurrentRows);
dataGridView1.DataSource = dv;
Remove the spaces from the name of the datatable in
dataadapter.Fill(ds, "pricingtable");

Apply a TableStyle to a QueryTable

I can use a query table:
var sheet = (_excel.ActiveSheet as Excel.Worksheet);
var rng = sheet.Range("A1");
var qt = sheet.QueryTables.Add("ODBC;...", rng, "SELECT * FROM myTable");
qt.Refresh();
and this will import the data correctly (e.g. dates actually display as dates etc...). But when I try and access the ListObject to apply a TableStyle I get an exception.
Now if I add a list object like:
var sheet = (_excel.ActiveSheet as Excel.Worksheet);
var qt = sheet.ListObjects.Add(
Excel.Enums.XlListObjectSourceType.xlSrcQuery,
"ODBC;...",
null,
Excel.Enums.XlYesNoGuess.xlNo,
rng,
"TableStyleMedium9").QueryTable;
qt.CommandType = Excel.Enums.XlCmdType.xlCmdSql;
qt.CommandText = "SELECT * FROM myTable";
qt.Refresh();
The the dates in the query display as decimal numbers and not dates...
I could just format the columns afterwards, but the problem is that I won't actually know the query that is being run as the user types this at runtime, so I would prefer to get Excel to do this.
So essentially, what I want, is to use the first bit of code and apply a TableStyle to it.
Can anyone help?
This doesn't do coloring, but it does organize the data into a datatable, and when you're debugging with breakpoints and mouse over the datatable after its been filled you can see all the data organized into columns. What you can then do with the datatable is bind it to a datagrid view on your win forms element.
I have this DataTable DataTable = new DataTable(); as a global field at the top.
OleDbConnection conn = new OleDbConnection();
//This is making a connection to the excel file, don't worry about this I think you did it differently.
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + stringFileName + ";" + "Extended Properties=\"Excel 12.0;HDR=Yes;\""; OleDbCommand cmd = new OleDbCommand
("SELECT * FROM [" + sheetFromTo + "]", conn);
DataSet dataSet1 = new DataSet();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(cmd);
try
{
conn.Open();//opens connection
dataSet1.Clear();//empties, incase they refill it later
dataAdapter.SelectCommand = cmd;//calls the cmd up above
dataAdapter.Fill(dataSet1);//fills the dataset
dataGridView1.DataSource = dataSet1.Tables[0];//puts the dataset in the dataGridview
//important** creates a datatable from the dataset, most of our work with the server is with this datatable
DataTable dataTable = dataSet1.Tables[0];
DataTable = dataTable;
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}

OLEDB Parameterized Query

public void LoadDB()
{
string FileName = #"c:\asdf.accdb";
string query = "SELECT ID, Field1 FROM Table1 WHERE ID=? AND Field1=?";
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FileName;
OleDbConnection odc = new OleDbConnection(strConn);
dAdapter = new OleDbDataAdapter();
OleDbCommand cmd = new OleDbCommand(query,odc);
cmd.Parameters.Add("?", OleDbType.Integer, 5).Value = 1234;
cmd.Parameters.Add("?", OleDbType.BSTR, 5).Value ="asdf";
dAdapter.SelectCommand = cmd;
ds = new DataSet();
dAdapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
I'm trying to use parametrized query to bind the access file into the datagridview. It finds the column names fine, but the contents are empty.
How can I fix this issue?
Here is an example of how the parameterized queries work with CSharp, OleDB.
try
{
connw.Open();
OleDbCommand command;
command = new OleDbCommand(
"Update Deliveries " +
"SET Deliveries.EmployeeID = ?, Deliveries.FIN = ?, Deliveries.TodaysOrders = ? , connw);
command.Parameters.Add(new OleDbParameter("#EMPID", Convert.ToDecimal(empsplitIt[1])));
command.Parameters.Add(new OleDbParameter("#FIN", truckSplit[1].ToString()));
command.Parameters.Add(new OleDbParameter("#TodaysOrder", "R"));
catchReturnedRows = command.ExecuteNonQuery();//Commit
connw.Close();
}
catch (OleDbException exception)
{
MessageBox.Show(exception.Message, "OleDb Exception");
}
This will work with any sql statement, you must assign the question mark "?" to each parameter, and then below you must create the parameters and add them in the order of how you laid out the question marks to get the right data into the right field.
In my test program, the ds.Tables[0].Rows.Count datatable actually had 1 row returned (as there was one row in my test database that matched the query itself). If you put a break on this line you should be able to see whether or not data is getting into the datatable in the first place. Try this:
dataGridView1.DataSource = ds.Tables[0];
What does the front end binding of dataGridView1 look like? Running the query in Access could shed some light on the situation too.
Try without specifying column size in parameters:
cmd.Parameters.Add("?", OleDbType.Integer).Value = 1234;
cmd.Parameters.Add("?", OleDbType.BSTR).Value ="asdf";

Import Excel trough OleDbDataAdapter in C# With changing Column names

Hello well i try to import a Excel document into my DataGridView in C#.
So far it worked but there is a Column with Data in it i need to 'sort'.
If this was simple i would do "WHERE test > 0" in the OleDbDataAdapter query.
But.. The name of the Column is changing with each document and i need to use it often. So far i got this :
private void button1_Click(object sender, EventArgs e)
{
String strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=C:\\Users\\Test\\Desktop\\Test.xls;" +
"Extended Properties=Excel 8.0;";
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Test$]", strConn);
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
In the select i need to put a line witch state that the first 3 letters of the column is the same but the number that follow are not. Like:
QTA 12345,
QTA 13213,
QTA 92818.
Something like:
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Test$] WHERE [testColumn] > 0", strConn);
But then with the same first 3 letters and the last numbers who are random.
Can someone help me please?
I've tried some code and it works fine for me. Have a try:
OleDbConnection oleDbConnection = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=D:\\Users\\name\\Desktop\\test.xls;" +
"Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'");
oleDbConnection.Open();
//Get columns
DataTable dtColumns = oleDbConnection.GetSchema("Columns", new string[] { null, null, "Tabelle1$", null });
List<string> columns = new List<string>();
foreach (DataRow dr in dtColumns.Rows)
columns.Add(dr[3].ToString());
string colName = columns.Find(item => item.Substring(0,3) == "QTA");
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Tabelle1$] WHERE [" + colName + "] > 0", oleDbConnection);
da.Fill(ds);
dataGrid1.ItemsSource = ds.Tables[0].DefaultView;
oleDbConnection.Close();
Pay attention to changing the connection string to your needs.
You can trim the code, using LINQ:
string colName = (from DataRow dr in dtColumns.Rows where dr[3].ToString().Substring(0, 3) == "QTA" select dr[3].ToString()).ElementAt(0);

Categories