17

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\"";
            }
PaulStock
  • 11,053
  • 9
  • 49
  • 52
Eslam Soliman
  • 1,276
  • 5
  • 16
  • 42
  • What connection string did you use to create the `conn` object? – barrowc Oct 01 '11 at 20:29
  • i use one for xls and one for xlsx – Eslam Soliman Oct 02 '11 at 13:30
  • 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\""; } – Eslam Soliman Oct 04 '11 at 19:35
  • It's worth checking the `Mode` property of the `conn` object after it has been opened. Compare the value to the list at http://msdn.microsoft.com/en-us/library/ms675792%28v=VS.85%29.aspx to be sure that the connection is in the correct mode – barrowc Oct 04 '11 at 22:52

4 Answers4

30

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

competent_tech
  • 44,465
  • 11
  • 90
  • 113
ItsAllABadJoke
  • 316
  • 3
  • 3
  • it works with .xlsx but not with .xls i think that there is another solution but thanks it is an internal sys so we are all using new .xlsx extintion version :) – Eslam Soliman Nov 16 '11 at 08:35
  • 2
    What a solution man! past two days i was going mad cuz of this issue...thanks a ton!!! – Aditya Bokade Apr 02 '14 at 10:25
  • 1
    Is it supposed to take a lot of time..I have loop which runs 50 time and update FirstName based on diff StudentId. It takes 4-5 mins to process and the gives a success message. But when i try to open the .xls file its says "this file may be corrupted located on a server that is not responding or read-only" and i can access the file after like 20-30 mins and even the date modified time changes after 20-30 mins – arpan shah Oct 17 '14 at 21:03
  • 1
    This solution did not work because with 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 type based on the most popular value type and then fails to cast the unselected type. – Merav Kochavi Nov 01 '15 at 14:29
0

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.

Merav Kochavi
  • 4,223
  • 2
  • 32
  • 37
0

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);
Hamid
  • 1,493
  • 2
  • 18
  • 32
0

My issue was a previous connection locked the excel file into readonly mode. Needed to kill the connection.