打开Excel窗口会中断将数据从C#写入Excel
当我的C#程序将数据连续写入Excel电子表格时,如果最终用户单击右上菜单并打开 Excel选项窗口,这会导致以下异常: System.Runtime.InteropServices.ComeException与HRESULT:0x800AC472 这会中断数据写入电子表格 理想情况下,应该允许用户这样做,而不会导致异常 我找到的唯一解决此错误代码的方法是循环并等待异常消失: 这实际上会挂起应用程序,数据不会写入Excel,用户对此问题一无所知 我想在写入Excel时禁用其主菜单,但找不到有关如何执行此操作的参考 我的应用程序支持Excel 2000到2013 以下是如何重现该问题:打开Excel窗口会中断将数据从C#写入Excel,c#,.net,excel,excel-interop,C#,.net,Excel,Excel Interop,当我的C#程序将数据连续写入Excel电子表格时,如果最终用户单击右上菜单并打开 Excel选项窗口,这会导致以下异常: System.Runtime.InteropServices.ComeException与HRESULT:0x800AC472 这会中断数据写入电子表格 理想情况下,应该允许用户这样做,而不会导致异常 我找到的唯一解决此错误代码的方法是循环并等待异常消失: 这实际上会挂起应用程序,数据不会写入Excel,用户对此问题一无所知 我想在写入Excel时禁用其主菜单,但找不到有关如
- 使用Windows桌面的Visual Studio Express 2013,在64位Windows 7上使用Excel 2007创建新的Visual C#Console应用程序项目
- 添加对“Microsoft ExceL 12.0对象库”(用于ExceL)和“System.Windows.Forms”(用于messagebox)的引用
以下是完整的代码:
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 } } }
使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用System.Threading.Tasks; 使用System.Threading.Tasks; 使用System.Threading;//睡觉 使用System.IO; 使用System.Runtime.InteropServices; 运用系统反思; 使用Microsoft.Win32; 使用Excel=Microsoft.Office.Interop.Excel; 命名空间控制台应用程序1 { 班级计划 { 静态void Main(字符串[]参数) { int i=3;//第二行有一个拆分窗格 Excel.applicationxlapp; Excel.工作簿; Excel工作表; 尝试 { 对象错误值=System.Reflection.Missing.Value; xlApp=new Excel.Application(); xlApp.Visible=false; xlWorkBook=xlApp.Workbooks.Add(错误值); xlApp.Visible=true; xlWorkSheet=(Excel.Worksheet)xlWorkBook.Worksheets.get_项(1); //Excel中拆分窗格的下两行: xlWorkSheet.Application.ActiveWindow.SplitRow=2; xlWorkSheet.Application.ActiveWindow.FreezePanes=true; xlWorkSheet.Cells[1,1]=“现在打开工作表”; xlWorkSheet.Cells[2,1]=“Excel选项窗口”; } 捕获(System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show(“此计算机上似乎不再安装Microsoft Excel(尽管仍有它的注册表项)。请保存到.tem文件。(1)”; 返回; } 捕获(例外) { System.Windows.Forms.MessageBox.Show(“此计算机上似乎不再安装Microsoft Excel(尽管仍有它的注册表项)。请保存到.tem文件。(2)”; 返回; } 而(i<65000) { i++; 尝试 { xlWorkSheet.Cells[i,1]=i.ToString(); 睡眠(1000); } 捕获(System.Runtime.InteropServices.COMException) { System.Windows.Forms.MessageBox.Show(“好吧,我在这里做什么?”); } 捕获(例外) { System.Windows.Forms.MessageBox.Show(“发生了其他事情”); } } Console.ReadLine();//暂停 } } }
- 打开应用程序,Excel出现,数据写入其中。从菜单中打开Excel选项对话框窗口,弹出错误:
mscorlib.dll中发生“System.Runtime.InteropServices.COMException”类型的异常,在托管/本机边界之前未处理该异常
其他信息:来自HRESULT的异常:0x800AC472 - 单击“继续”,我的消息框“好的,我在这里做什么?”出现
Bertrand自动化Excel并与它的“perculiarities”搏斗的一个可能的替代方法是使用OpenXmlWriter编写器(DocumentFormat.OpenXml.OpenXmlWriter)写出文件 这有点棘手,但在处理超过100万行的床单时不会出一身冷汗
我们终于在这个问题上找到了Microsoft支持部门。他们的最后答复是: 我能够重现这个问题。我对此做了进一步的研究 发现这种行为是预期的,也是设计的。这 由于Excel正忙,引发异常0x800AC472–VBA_E_IGNORE 并且不会为任何对象模型调用提供服务。这是其中一个例子 关于这一点的讨论。 我看到的解决方法是显式捕获此异常并重试 一段时间后,直到你的预期行动完成 由于我们无法理解用户的想法,用户可能决定打开一个窗口或记笔记,而没有意识到软件已停止记录(如果您掩盖错误),因此我们决定使用以下方法解决此问题:
xlWorkSheet.EnableSelection = Microsoft.Office.Interop.Excel.XlEnableSelection.xlNoSelection;
锁定Excel窗口UI。我们提供了一个明显的“解锁”按钮,但当用户单击它时,消息框中会严厉警告他“您想继续吗?”我成功地做了一个目标excel文件的临时副本,然后用代码打开它 那样我
xlWorkSheet.EnableSelection = Microsoft.Office.Interop.Excel.XlEnableSelection.xlNoSelection;
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
{
}
}
bool failed = false;
do
{
try
{
// Call goes here
failed = false;
}
catch (System.Runtime.InteropServices.COMException e)
{
failed = true;
}
System.Threading.Thread.Sleep(10);
} while (failed);