Excel C#无法更新:数据库只读

时间:2017-10-11 22:26:32

标签: c# excel windows

我有2台电脑:

  • 主要M = Win 7,32位,Office 2007
  • 虚拟V = Win 7,32位,Visual Studio 2013

我创建了3个带有M数据的Excel文件,并通过网络发送了我正在构建程序的V机器,事情是程序工作正常并更新V机器上的Excel工作表,这对我的M不起作用机!

我试过了:

  • 设置权限
  • 设置" OleDb-Readonly = false;"
  • 在另一台机器win7 32bit和64bit
  • 上尝试了它
  • 在win10 64bit计算机上试用了
  • 在该计算机上创建新的Excel文件并将数据复制到新计算机上 片
  • 在上面的每个步骤中以管理员身份启动程序,没有
  • 在0到1之间查询IMEX

所有这些都没有工作除了V机器......为什么?

请注意,V机器没有安装办公室,我试图抓住没有安装办公室的机器(或者我可以从中卸载它)来测试它,但不确定这是否会导致问题

另请注意,我在程序中也使用Access 2007连接,并且工作正常。

这是C#更新代码:

 public static bool PreProcess(string dbpath)
{
    //string file = System.IO.Path.Combine("./", dbpath);
    string connStr = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;\";", dbpath);

    using (var conn = new OleDbConnection(connStr))
    {
        conn.Open();
        var sql = "SELECT * FROM [Sheet1$]";
        var cmd = new OleDbCommand(sql, conn);
        var reader = cmd.ExecuteReader();

        List<string> list = new List<string>();
        bool notExists;
        while (reader.Read())
        {
            notExists = true;
            if (reader[0].ToString().Equals(""))continue;

            for (int cn = 0; cn < list.Count; cn++)
            {
                if (reader[0].ToString().Equals(list[cn]) || reader[0].ToString().Equals(""))
                {
                    new OleDbCommand("UPDATE [Sheet1$] SET [name] = '' WHERE [name]= '" + reader[0].ToString() + "' AND [par1]="+reader[1].ToString()+"", conn).ExecuteNonQuery();
                    notExists = false;
                    break;
                }
            }

            if (notExists)
            {
                list.Add(reader[0].ToString());
                for (int i = 1; i < reader.FieldCount; i++)
                {
                    try
                    {
                        double d = Double.Parse(reader[i].ToString());
                    }catch(Exception e)
                    {
                        //new OleDbCommand("UPDATE [Sheet1$] SET par"+i+" = '0' WHERE id = '"+reader[0].ToString()+"'");
                        new OleDbCommand("UPDATE [Sheet1$] SET [par"+i+"] = 0 WHERE [name]= '" + reader[0].ToString() + "'", conn).ExecuteNonQuery();
                    }

                    //MessageBox.Show("Data: "+reader[i].ToString() + " - i="+i);
                }
            }
        }
        return true;
    }
    return false;
}

错误:

Cannot update. Database or object is read only.

详细说明:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.Data.OleDb.OleDbException (0x80004005): Cannot update. Database or object is read-only.
   at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
   at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionInternal.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.OleDb.OleDbConnection.Open()
   at KMean.ExcelCon.PreProcess(String dbpath)
   at KMean.Form1.PrePBtn_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
KMean
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/Abubakar/Desktop/KMean/KMean/bin/Release/KMean.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Data
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Transactions
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
System.EnterpriseServices
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.EnterpriseServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Numerics
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.17929 built by: FX45RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

修改

我设法让V机给我同样的问题。除了连接字符串失败然后将其返回到原始状态之外,我什么都没改变。现在它消失了......同样的错误:&#34;无法更新...&#34;

1 个答案:

答案 0 :(得分:1)

我看了一眼,打开连接在这里工作得很好。

我需要安装2016版ACE引擎。我看到M机正在运行Office 2007.引擎的差异不太可能在连接打开时产生只读问题;但你永远不知道。当发生这些类型的错误时,值得探索机器配置的差异。

这是我使用的代码。这很好。

using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExcelReadOnly
{
    class Program
    {
        static void Main(string[] args)
        {
            PreProcess("Sample File.xlsx");
            Console.In.ReadLine();
        }

        public static bool PreProcess(string dbpath)
        {
            string connStr = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={dbpath};Extended Properties=\"Excel 12.0 Xml;HDR=YES;\";";

            using (var conn = new OleDbConnection(connStr))
            {
                conn.Open();

                var cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", conn);
                var reader = cmd.ExecuteReader();
                while (reader?.Read() == true)
                    Console.Out.WriteLine($"Name: {reader[0]}, Par1: {reader[1]}");
                reader?.Close();

                new OleDbCommand("INSERT INTO [Sheet1$] ([Name], [Par1]) VALUES ('Name 0', '0')", conn)
                    .ExecuteNonQuery();
                new OleDbCommand("INSERT INTO [Sheet1$] ([Name], [Par1]) VALUES ('Name 1', '1')", conn)
                    .ExecuteNonQuery();
                new OleDbCommand("INSERT INTO [Sheet1$] ([Name], [Par1]) VALUES ('Name 2', '2')", conn)
                    .ExecuteNonQuery();

                reader = cmd.ExecuteReader();
                while (reader?.Read() == true)
                    Console.Out.WriteLine($"Name: {reader[0]}, Par1: {reader[1]}");
                reader?.Close();
            }

            return false;
        }
    }
}