Write Data to Excel using Oledb - c#

Is it possible to write data using Oledb into a common excel ?
There are no table structure or anything, it's a user document.
When I tried, i had always an OleDbException
"INSERT" query reply :
Operation must use an application that can be updated.
"UPDATE" query reply :
No value given for one or more required parameters.
My code:
using (OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + #"C:\Users\[...]\Classeur.xls" + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;READONLY=FALSE\""))
{
connection.Open();
OleDbCommand commande = new OleDbCommand(
"INSERT INTO [Feuil1$](F1,F2,F3) VALUES ('A3','B3','C3');", connection);
commande.ExecuteNonQuery();
connection.Close();
connection.Dispose();
}
New test (without sucess !) :
using (OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + #"C:\Users\[...]\Classeur.xls" + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;READONLY=FALSE\""))
{
string column = "A";
string row = "1";
string worksheetName = "Feuil1";
string data = "TEST";
connection.Open();
string commandString = String.Format("UPDATE [{0}${1}{2}:{1}{2}] SET F1='{3}'", worksheetName, column, row, data);
OleDbCommand commande = new OleDbCommand(
commandString, connection);
connection.Close();
connection.Dispose();
}

I finally found !
Simple question of IMEX ( So many hours lost for that !)
So if anyone have the same issue :
//for reading data
Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;READONLY=FALSE\"
//for writing data
Extended Properties=\"Excel 8.0;HDR=NO;IMEX=3;READONLY=FALSE\"

This IMEX situation for Writing Data was driving me crazy for months, I had to remove it to make it work.
I just found [CheapD] answer and it works flawless, Thank you Cheap.
I would suggest to add the MODE parameter:
Extended Properties='Excel 12.0; HDR=Yes; IMEX=3; MODE=Share; READONLY=False';

Related

Updating excel values in data grid view on certain condition

I need to fetch a row value from an excel sheet in data grid view in winform.
I’m able to display the entire excel sheet in the datagridview. But, I need to display particular rows in the grid based on a current date condition.
public DataTable ReadExcel2(string fileName, string fileExt)
{
string connectionstring ;
DataTable dtexcel2 = new DataTable();
connectionstring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=YES';";
OleDbConnection connection = new OleDbConnection(connectionstring);
OleDbCommand oconn = new OleDbCommand("Select * From [POSFailures$] WHERE Date=#date");
oconn.Connection = connection;
try
{
oconn.Parameters.AddWithValue("#date", DateTime.Now.ToString("MM/dd/yyyy"));
connection.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
sda.Fill(dtexcel2);
connection.Close();
}
catch (Exception)
{
}
return dtexcel2;
}
Thanking you in advance
What seems to be happening here is that the Date parameter is not being honored, as you are getting back all of the rows. So, I used Google to figure out how to properly add parameters when using OleDbConnection. I found this:
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement
Source: https://learn.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbcommand.parameters?redirectedfrom=MSDN&view=netframework-4.8#System_Data_OleDb_OleDbCommand_Parameters
Using the example on that page, try changing your code to this:
string connectionstring;
DataTable dtexcel2 = new DataTable();
connectionstring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=YES';";
OleDbConnection connection = new OleDbConnection(connectionstring);
OleDbCommand command = new OleDbCommand("Select * From [POSFailures$] WHERE Date = ?");
command.Parameters.Add(new OleDbParameter(DateTime.Now.ToString("MM/dd/yyyy"), OleDbType.Date));
command.Connection = connection;
try
{
connection.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(command);
sda.Fill(dtexcel2);
connection.Close();
}
catch (Exception)
{
}
Please note that i've not tested this, so I can't promise it will work. But, the main point is... the answer is out there! You just need to go looking for it.

C# GetOleDbSchemaTable. Name of first Excel Worksheet and its columns

try
{
string connectionString = string.Empty;
if (Path.GetExtension(fileName) == ".xlsx")
{
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName +
";Extended Properties=Excel 12.0;";
}
else
{
Debug.Print(connectionString);
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.Combine(Server.MapPath("~/Content"), fileName) + ";Extended Properties=Excel 8.0;";
//connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path.Combine(Server.MapPath("~/Content"), fileName) + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\"";
}
OleDbCommand selectCommand = new OleDbCommand();
OleDbConnection connection = new OleDbConnection();
OleDbDataAdapter adapter = new OleDbDataAdapter();
connection.ConnectionString = connectionString;
if (connection.State != ConnectionState.Open)
connection.Open();
//connection.Get
DataTable dtSchema = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
}
connection.Open() seems to be connecting just fine. Now I have gotten a dtSchema Data Table object. I am needing to get the name of the Excel worksheet or worksheets that were gotten if any. I am also scanning the object to find out where the column names are. There is supposed to be some columns in the schema. Is it documented where the columns are?
When I do some output in my immediate window:
dtSchema.Columns[0].ToString()
"TABLE_CATALOG"
dtSchema.Columns[1].ToString()
"TABLE_SCHEMA"
dtSchema.Columns[2].ToString()
"TABLE_NAME"
dtSchema.Columns[3].ToString()
"TABLE_TYPE"
These are not the column names of the first worksheet, which is what I am looking for mainly the name of the first worksheet and its columns.
Thank you for posting..
If you want to look for column names. See the resultant COLUMN_NAME column
DataTable dtCols = this.connection.GetSchema("Columns");
TABLE_NAME is also helpful for your case to identify the Sheet.

Operation must use an updateable query when updating excel sheet

I am getting this error when trying to update excel sheet :
Server Error in '/ReadExcelData_Csharp' Application.
Operation must use an updateable query.
and here is the code that i am using :
querys = "UPDATE [Sheet1$] "+"SET [Number]=" +s.Trim()+ " WHERE [Number]=" + s2.Trim() ;
objcmc = new OleDbCommand(querys, conn);
objcmc.ExecuteNonQuery();
any help will be appreciated .
and here is the connection i used :
if (strFileType.Trim() == ".xls")
{
connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
else if (strFileType.Trim() == ".xlsx")
{
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
}
Remove the IMEX=2 (or IMEX=1) from the connection string and it will work. I have tested this crazy solution several times and removing the IMEX for some strange reason seems to do the trick (at least for xlsx files).
The following code works:
static void Main(string[] args)
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + "d:\\temp\\customers.xlsx" + ";Extended Properties=\"Excel 12.0;ReadOnly=False;HDR=Yes;\"";
string selectString = "INSERT INTO [Customers$](Id,Company) VALUES('12345', 'Acme Inc')";
OleDbConnection con = new OleDbConnection(connectionString);
OleDbCommand cmd = new OleDbCommand(selectString, con);
try
{
con.Open();
cmd.ExecuteNonQuery();
Console.WriteLine("Success");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
con.Dispose();
}
Console.ReadLine();
}
}
Thanks to RobertNet from social.msdn.microsoft.com
I used the solution provided above and removed the IMEX=2 or IMEX=1 string from the connection string. But this was not enough. In my case, the solution needed an additional work around.
But in my data base I actually needed the IMEX - because my column had mixed data types, some double values some string values. When I remove IMEX =1, I get the a runtime exception "Unable to cast object of type" because it automatically selects the column data type based on the most popular value in the column and then fails to cast the values which are not of the selected type.
I worked around this issue by changing my double and int values to string values (added a ' in the beginning of the cell value manually in excel) and removed the IMEX from the connection string. and then this solved the issue.
In my case,I changed ConnectionString and then this solved the issue.
I removed ReadOnly=False;HDR=Yes; parametes in connectionString
string _connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;\";", pathToExcelFile);

c# Excel skipping first row?

I'm importing an xls file using OleDbCommand to a ds. Problem I'm having is during the foreach on my ds its skipping for first row. I can't figure out why. Any suggestions?
cmd.CommandText = string.Format("SELECT * FROM [{0}$]", worksheetName);
conn.Open();
var adapter = new OleDbDataAdapter();
var ds = new DataSet();
adapter.SelectCommand = cmd;
adapter.Fill(ds);
var table = ds.Tables[0];
foreach(DataRow row in table.Rows){ // rest of my code }
Change the connection string (as mentioned in comment) from:
string cnn = string.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"data source={0}{1}{2};" +
"Extended Properties=Excel 8.0;",
fileLocation, fileName, fileExtension);
to:
string cnn = string.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"data source={0}{1}{2};" +
"Extended Properties=Excel 8.0;HDR=No",
fileLocation, fileName, fileExtension);
Check your connection string. Most likely it contains:
HDR=Yes
which indicates that first row is a header
Maybe you've told it to skip first row. I remember a property that sounds something like FirstRowIsHeader. I think if that is set to true, then it skips. this can be changed at point you create your connection

update excel cells with its uppercase text

i have the following problem with an excel file that i want to uppercase the values of its respective cells in C# with the next code:
DbProviderFactory factory =
DbProviderFactories.GetFactory("System.Data.OleDb");
DbConnection connection = factory.CreateConnection();
string stringConnection = String.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=NO;IMEX=1'",
excelPath);
connection.ConnectionString = stringConnection;
connection.Open();
DbCommand updateExcel =
factory.CreateCommand();
updateExcel.CommandText =
"UPDATE [sheet1$] SET lastname = UCASE(lastname), name = ucase(name)";
updateExcel.Connection = connection;
updateExcel.ExecuteNonQuery();
conection.Close();
connection.Dispose();
and it raise an oledbexception about parameters doesnt specified, anybody could help me?
If you are trying to connect to an Excel 2007 or 2010 spreadsheet you will need the following connection string...
OleDbConnection xlconnection = new OleDbConnection();
xlconnection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FileName + #";Extended Properties='Excel 12.0;HDR=YES;IMEX=1'"

Categories