我写了一个C#应用程序,它查询数据库并将结果放在excel文件中。该程序本身工作正常。但是,如果我在应用程序运行时打开第二个完全不相关的excel文件,则会发生异常并且该过程将停止。
现在,在程序本身中,我将可见性设置为false,在打开第二个不相关的Excel文件后,生成的文件突然打开并可见,然后我得到异常。
任何人都知道导致问题的原因或解决方法吗?
代码的相关部分如下,异常发生在工作单行.get_Range(currCol.GetString()+ excelRow,Missing.Value).Formula = item.ToString();
异常本身是:“来自HRESULT的异常:0x800AC472”
Application exc = new Application();
//Makes the Excel file not visible
exc.Visible = false;
exc.UserControl = false;
exc.DisplayAlerts = false;
Workbooks workbooks = exc.Workbooks;
Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Sheets sheets = workbook.Worksheets;
Worksheet worksheet = (Worksheet)sheets.get_Item(1);
int excelRow = 1;
ExcelChar currCol = new ExcelChar('A');
System.Data.DataTable testTable = dbConnection.searchQuery("Select * from testTable").Copy();
if (worksheet == null)
{
Console.WriteLine("ERROR: worksheet == null");
}
foreach (System.Data.DataRow row in testTable.Rows)
{
foreach (var item in row.ItemArray)
{
worksheet.get_Range(currCol.GetString() + excelRow, Missing.Value).Formula = item.ToString();
currCol.Add(1);
}
excelRow++;
currCol = new ExcelChar('A');
}
答案 0 :(得分:1)
看看this thread。
看起来你的错误是VBA_E_IGNORE,在这种情况下你需要注册an IMessageFilter implementation,这样你才能实现重试逻辑。
过去我曾经看过这个问题,当使用相同的Excel实例和互操作时 - 例如在使用以下方法实例化Excel Application对象时:
Marshal.GetActiveObject("Excel.Application")
在您的情况下,您使用以下方法创建新的Excel实例:
exc = new Application();
您应该尝试做的是确保尽快关闭此实例。由于this KB article中描述的问题,这并不总是容易的。否则,您可能会考虑使用COM Interop之外的其他内容来写入Excel(例如OLEDB或第三方库,如Aspose或EPPlus)。
当Excel忙时 - 例如有一个模式对话框显示,或正忙于加载工作簿,它不会响应传入的COM消息,因此它返回一个错误,该错误被转换为此异常。 IMessageFilter
实现(具体为:RetryRejectedCall
)通常会重试几次,然后失败或提示用户重试(“服务器忙”)。
答案 1 :(得分:0)
使用Office InterOp服务时,必须以相反的顺序关闭已创建的对象。
private static void Excel_FromDataTable(DataTable dt)
{
// Global missing variable.
object missing = System.Reflection.Missing.Value;
// Creates an excel object,
Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
// Then a workbooks object,
Excel.Workbooks workbooks = excel.Workbooks;
// Then adds a workbook object,
Excel.Workbook workbook = workbooks.Add(true);
// Then adds a worksheet object,
Excel.Worksheet activeSheet = workbook.ActiveSheet;
// Then names the worksheet to what we need.
activeSheet.Name = "scbyext";
// Add column headings,
int iCol = 0;
// for each row of data,
int iRow = 0;
foreach (DataRow r in dt.Rows)
{
iRow++;
// Then add each row's cell data.
iCol = 0;
foreach (DataColumn c in dt.Columns)
{
iCol++;
excel.Cells[iRow, iCol] = r[c.ColumnName];
}
}
// Disable Excel prompts.
excel.DisplayAlerts = false;
// Save the workbook to the correct folder.
workbook.SaveAs("C:\\Escaped\\Path",
Excel.XlFileFormat.xlExcel8, missing, missing,
false, false, Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
// Release the objects we made, in reverse order, to allow Excel to quit correctly.
ReleaseObj(activeSheet);
ReleaseObj(workbook);
ReleaseObj(workbooks);
excel.Quit();
ReleaseObj(excel);
}
如果不这样做,该过程将保持打开状态。我不确定当它停滞不前时它正在做什么,但到了当天结束时它使用的CPU时间会变得非常高。
答案 2 :(得分:0)
我有类似的问题。我正在使用C#创建一个excel文件,其中有很多图表需要很长时间才能创建。如果用户在我的C#文件仍在写入时打开了现有的excel文件,则会导致抛出异常,我的应用程序将崩溃。
我用以下内容修复了它:
xlApp = new Application();
xlApp.IgnoreRemoteRequests = true;