none
操作EXCEL时抛出RPC_E_SERVERCALL_RETRYLATER错误 RRS feed

  • 问题

  • 你好,我现在正在开发一款通过Excel输出报表的程序,用户要求每次用程序生成的Excel文件都要直接以打印预览的形式打开。为了减少任务管理器中Excel进程的数量并减少画面僵死的时间,我通过一个专门的全局进程以异步方式来打开并预览Excel文件,预览代码模拟如下:

    MsExcel.Workbook msExcelWorkbook = GetMsExcelApp().Workbooks.Open(previewExcelName, Type.Missing,.....);

    msExcelWorkbook.PrintPreview(false);

    但是碰到一个问题,如果连续输出并预览多个Excel,导致代码抛出异常:(HRESULT : 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))。

    经过分析发现是Excel的Application在预览状态下会被阻塞,此时继续对其操作就会出现上述错误,请问如何能够判断当前Excel的Application对象是否正处于打印预览等阻塞状态。

    2010年11月30日 11:29

答案

  • 你好

    我想你的烦恼应该是这样的,在某个EXCEL文件打印预览时没有关掉,然后又选了这个文件来打印预览,由于这个文件正在调用,因此报错。

    但我想每打开一个EXCEL文件,就会有一个MsExcel实例(就是说这个实例可能不是全局实例),这样不好判断当前Excel的Application对象是否正处于打开状态(例如打印预览等阻塞状态),除非每个EXCEL文件Application对象都是全局的(或者当前只打开一个实例,但那样就没有这种烦恼了)。

    那么换种思路如何,例如在执行打印预览前用一个方法来判断这个文件是否被打开?

            private bool FileIsReady(string excelFile)   
            {
                FileInfo fi = new FileInfo(excelFile);
                FileStream fs = null;
                try
                {
                    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                    return true;
                }
                catch (IOException)
                {
                    return false;
                }
                finally
                {
                    if (fs != null) { fs.Close(); fs.Dispose(); }
                }
            }

     


    jianwu0929
    2010年12月2日 10:55

全部回复

  • 你好

    我想你的烦恼应该是这样的,在某个EXCEL文件打印预览时没有关掉,然后又选了这个文件来打印预览,由于这个文件正在调用,因此报错。

    但我想每打开一个EXCEL文件,就会有一个MsExcel实例(就是说这个实例可能不是全局实例),这样不好判断当前Excel的Application对象是否正处于打开状态(例如打印预览等阻塞状态),除非每个EXCEL文件Application对象都是全局的(或者当前只打开一个实例,但那样就没有这种烦恼了)。

    那么换种思路如何,例如在执行打印预览前用一个方法来判断这个文件是否被打开?

            private bool FileIsReady(string excelFile)   
            {
                FileInfo fi = new FileInfo(excelFile);
                FileStream fs = null;
                try
                {
                    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                    return true;
                }
                catch (IOException)
                {
                    return false;
                }
                finally
                {
                    if (fs != null) { fs.Close(); fs.Dispose(); }
                }
            }

     


    jianwu0929
    2010年12月2日 10:55
  • 谢谢你的解答,参考你的异常捕获思路,我通过捕获异常来处理后续预览的Excel文件,如果当前预览队列中存在正处于预览状态的Excel文件,那么我就新建立一个Application对象来进行预览,并将每一个Application对象放入集合中存放,退出系统的时刻对这些所有的Application对象进行关闭和回收。
    2010年12月3日 1:32