C#Excel强制ReadOnly没有Edit Priveledges

时间:2017-01-10 21:53:12

标签: c# excel readonly

我有一个Excel工作簿(“test.xlsx”),其中有一个名为“gv_epxsize”的单元格。我的目标是打开excel工作簿并在单元格中记下字符串“101”,名称为“gv_epxsize”。

问题是我的代码一直使文件只读,因此它不会将字符串“101”写入指定的单元格。我一直收到一个Windows提示,我已经打开了Windows权限的文件,并询问我是否要打开只读副本。问题是我没有打开文件,并且在启动代码之前没有运行EXCEL.EXE进程。

我已经做过的事情:

  • 我在不同的文件夹中将文件另存为另一个名称 - 仍然没有运气。
  • 该文件未保存在共享文件夹中。
  • 我确保在运行代码之前,我的TaskManager已将所有EXCEL.EXE进程终止。

有人可以告诉我这里我做错了吗?

这是C#的片段

  string filePath = "C:\\Users\\ussatdafa\\Desktop\\Work\\Projects\\test.xlsx";

  Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

        if (xlApp == null)
        {
            MessageBox.Show("Excel has not been properly installed");
        }
        else
        {
            //string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
            Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
            Workbooks wbs = excelApp.Workbooks;
            Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);


            Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
            wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
        }

2 个答案:

答案 0 :(得分:4)

我老实说不确定发生了什么,但我有两点意见:

  1. 您正在打开Excel两次 - 这似乎是肯定的。一个实例是xlApp,另一个是excelApp。如果您在excelApp的实例化时打开任务管理器,我很确定您会发现两个Excel实例正在运行。我不知道这是否有助于你的问题
  2. 我总是发现在调试时有助于使Excel可见。您可以在部署之前始终对该行进行注释,但在调试期间,这很好,因为在调试期间暴露COM对象不如本机.NET对象有用 - 这样您就可以以原生形式查看它
  3. 我使用这些更改运行了您的代码版本,并且在更改命名范围“gv_epxsize”的单元格值时没有任何问题。

    string filePath = "C:\\Users\\ussatdafa\\Desktop\\Work\\Projects\\test.xlsx";
    Microsoft.Office.Interop.Excel.Application excelApp =
        new Microsoft.Office.Interop.Excel.Application();
    
    if (excelApp == null)
    {
        MessageBox.Show("Excel has not been properly installed");
    }
    else
    {
        excelApp.Visible = true;
        Workbook wb = excelApp.Workbooks.Open(filePath, 0, false, 5, "", "", false,
            XlPlatform.xlWindows, "", true, false, 0, true, false, false);
        Worksheet ws = wb.Sheets[1];
    
        wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
    }
    

    这对我来说完美无缺。这是证据:

    enter image description here

    因此,这引出了几种可能性:

    (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
    

    不是你的想法。或许,它与我使用的不一样,那就是:

    Worksheet ws = wb.Sheets[1];
    

    将返回第一个工作表(新工作簿上的“Sheet1”)。

    当然,有两个Excel打开可能会导致问题。

答案 1 :(得分:1)

我很确定您的问题是您的代码中保存文件的WHERE。从您发布的代码中,有一件事情无法真正起作用,可以解释您的问题。请看下面的代码:

else {
  //string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
  Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
  Workbooks wbs = excelApp.Workbooks;
  Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);

  Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
  wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}

这是else声明的if (xlApp == null)部分。首先在此else部分中创建一个名为excelApp的新Excel应用程序,其中包含:

Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();

为什么你这样做是未知的,因为你已经创建了一个名为xlApp的早期版本。但这还是可以的;您可以打开多个Excel应用程序。

然后打开文件并进行更改:

Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";

使用filePath打开工作簿并调用woorkbook wb。然后抓取wb中的第一张工作表,并将其分配给工作表变量ws。请记住,您在此else子句中打开了工作簿。对工作簿进行更改,然后退出else子句。一切似乎都没问题除了......因为我们退出了else条款...... excelAppwbswbws变量不再存在。即使您尝试保存或关闭此else子句之外的文件,您也无法引用它,因为您在else子句中创建了这些变量。

由于您无法创建名为wb的新变量(如果它已经存在)...然后很明显工作簿wb永远不会被保存或关闭。

我将以下行放在您的else子句中,即使您的程序正在运行,也可以正确打开文件。很明显,您可能稍后在代码中保存并关闭文件,但这不是您在此else子句中打开的文件。

else {
  Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
  Workbooks wbs = excelApp.Workbooks;
  Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);

  Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
  wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
  wb.Save();
  wb.Close();
  excelApp.Quit();
  System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
  System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
}

希望这是有道理的。