通过打开Excel窗口将C#中的数据写入Excel中断

当我的C#程序将数据连续写入Excel电子表格时,如果最终用户单击右上angular的菜单并打开“Excel选项”窗口,则会导致System.Runtime.InteropServices.COMException与HRESULT:0x800AC472中断数据写入到电子表格。

理想情况下,应允许用户在不引起exception的情况下执行此操作。

我发现这个错误代码的唯一解决scheme是循环,并等待,直到exception消失: 从HRESULTexception:0x800AC472有效挂起的应用程序,数据不写入Excel,用户在黑暗中留下的问题。

我想写关于Excel的主菜单,但没有find一个参考如何做到这一点。

我的应用程序支持Excel 2000至2013年。

这里是如何重现这个问题:

使用Visual Studio Express 2013 for Windows桌面,使用Excel 2007在Windows 7 64位上使用.NET 4.5.1。

创build一个新的Visual C#控制台应用程序项目。

添加对“Microsoft Excel 12.0对象库”(对于Excel)和对“System.Windows.Forms”(对于消息框)的引用。

这里是完整的代码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading.Tasks; using System.Threading; // for sleep using System.IO; using System.Runtime.InteropServices; using System.Reflection; using Microsoft.Win32; using Excel = Microsoft.Office.Interop.Excel; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int i = 3; // there is a split pane at row two Excel.Application xlApp; Excel.Workbook xlWorkBook; Excel.Worksheet xlWorkSheet; try { object misValue = System.Reflection.Missing.Value; xlApp = new Excel.Application(); xlApp.Visible = false; xlWorkBook = xlApp.Workbooks.Add(misValue); xlApp.Visible = true; xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); // next 2 lines for split pane in Excel: xlWorkSheet.Application.ActiveWindow.SplitRow = 2; xlWorkSheet.Application.ActiveWindow.FreezePanes = true; xlWorkSheet.Cells[1, 1] = "Now open the"; xlWorkSheet.Cells[2, 1] = "Excel Options window"; } catch (System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show("Microsoft Excel does not seem to be installed on this computer any longer (although there are still registry entries for it). Please save to a .tem file. (1)"); return; } catch (Exception) { System.Windows.Forms.MessageBox.Show("Microsoft Excel does not seem to be installed on this computer any longer (although there are still registry entries for it). Please save to a .tem file. (2)"); return; } while(i < 65000) { i++; try { xlWorkSheet.Cells[i, 1] = i.ToString(); Thread.Sleep(1000); } catch (System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show("All right, what do I do here?"); } catch (Exception) { System.Windows.Forms.MessageBox.Show("Something else happened."); } } Console.ReadLine(); //Pause } } } 

Lanch的应用程序,Excel出现,并写入数据。 从菜单打开Excel选项对话框窗口popup错误:

mscorlib.dll中发生types为“System.Runtime.InteropServices.COMException”的exception,并未在托pipe/本机边界之前处理

附加信息:来自HRESULT的exception:0x800AC472

点击继续,我的信息框“好的,我在这里做什么?” 出现。

请指教?

最好的问候,伯特兰

我们终于一路走到微软支持这个问题。 他们的最终答复是:

我能够重现这个问题。 我进一步研究了这一点,发现这种行为是预料之中的,也是devise的。 这个exception0x800AC472 – VBA_E_IGNORE被抛出,因为Excel繁忙,不会服务任何对象模型调用。 这是谈论这个的讨论之一。 http://social.msdn.microsoft.com/Forums/vstudio/en-US/9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/hresult-800ac472-from-set-operations-in-excel?forum=vsto解决方法我看到的是明确地捕捉到这个exception,并在某个时候之后重试,直到你的意图行动完成&#x3002;

由于我们无法读取可能决定打开一个窗口或者logging而没有意识到软件已经停止logging的用户的头脑(如果你掩盖了错误),我们决定解决使用:

  xlWorkSheet.EnableSelection = Microsoft.Office.Interop.Excel.XlEnableSelection.xlNoSelection; 

lockingExcel窗口UI。 我们提供了一个明显的“解锁”button,但是当用户点击它时,他会在一个消息框中被严格警告,并伴随着一个“你想继续吗?

 xlApp = new Excel.Application(); xlApp.Interactive = false; 

我所做的成功是在打开代码之前制作一个目标excel文件的临时副本。

这样,我可以独立于打开或不打开源文档来操作它。

使Excel交互是一个完美的解决scheme。 唯一的问题是如果用户在Excel上同时做某些事情,如select范围或编辑单元格。 例如,您的代码正在从不同的线程返回,并尝试在Excel上写入计算结果。 所以为了避免这个问题,我的build议是:

 private void x(string str) { while (this.Application.Interactive == true) { // If Excel is currently busy, try until go thru SetAppInactive(); } // now writing the data is protected from any user interaption try { for (int i = 1; i < 2000; i++) { sh.Cells[i, 1].Value2 = str; } } finally { // don't forget to turn it on again this.Application.Interactive = true; } } private void SetAppInactive() { try { this.Application.Interactive = false; } catch { } } 

自动化Excel的一个可能的替代方法是,使用OpenXmlWriter编写器(DocumentFormat.OpenXml.OpenXmlWriter)将文件写出来。

这是一个有点棘手,但没有打破汗水处理床单> 100万行。

在MSDN上的OpenXml文档