简体   繁体   English

C#Excel自动化仅在Excel可见时才起作用

[英]C# Excel automation works only when Excel is visible

I have developed a small C# utility that opens several workbooks and copy worksheets and specific cell ranges into a merged workbook. 我开发了一个小型C#实用程序,它可以打开多个工作簿,并将工作表和特定单元格范围复制到合并的工作簿中。 The app works flawlessly until I set Excel.Aplication.Visible = false. 该应用程序完美无缺,直到我设置Excel.Aplication.Visible = false。 Then, it throws a COM error 800A03EC on opening a workbook. 然后,它在打开工作簿时抛出COM错误800A03EC。 This is the same location, same workbook that is opened when Visible = true. 这是相同的位置,当Visible = true时打开的相同工作簿。

The Excel processing occurs on a BackgroundWorker thread. Excel处理在BackgroundWorker线程上进行。

To begin, I start Excel and open several "global" workbooks that will be used as sources for all of the merged workbooks. 首先,我启动Excel并打开几个“全局”工作簿,这些工作簿将用作所有合并工作簿的源。

//Start Excel and get Application object.
XL = new Excel.Application();
XL.Visible = true;

//Open workbooks that are used for all providers
sourceTemplate = (Excel._Workbook)(XL.Workbooks.Open(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Provider Summary Template.xlsx")));
currentTemplateSheet = sourceTemplate.Worksheets["Summary"];
sourceAuditPlan = (Excel._Workbook)(XL.Workbooks.Open(Path.Combine(DataSetFolder.Text, "Audit Plan.xlsx")));
currentAuditPlanSheet = sourceAuditPlan.Worksheets["Audit Plan"];
sourceRiskSummary = (Excel._Workbook)(XL.Workbooks.Open(Path.Combine(DataSetFolder.Text, "Provider Risk Summary.xlsx")));
currentRiskSummarySheet = sourceRiskSummary.Worksheets["Visible Risk"];

Then I loop through a list of workbooks, opening one at a time, and opening additional workbooks based on data found in that workbook (so opening workbook for Dr. One, a Chiropractor, I then open utilization workbooks for the Chiropractor specialty, etc.). 然后我循环浏览一个工作簿列表,一次打开一个工作簿,并根据该工作簿中的数据打开其他工作簿(因此,为Dr. One打开工作簿,按摩师,然后打开脊椎治疗师专业的使用工作簿等。 )。 It is on that first utilization workbook that the error is thrown. 它是第一个使用工作簿上的错误抛出。

foreach (string workbook in workbooksList)
{
    try
    {
        //Determine provider ID - in target filename as Dr_[Provider ID]_RVU.xlsx
        string providerId = workbook.Substring(workbook.IndexOf("_") + 1, workbook.LastIndexOf("_") - (workbook.IndexOf("_") + 1));

        //Open target workbook (Dr_xx_RVU.xlsx)
        targetWorkbook = (Excel._Workbook)(XL.Workbooks.Open(workbook));
        Excel.Sheets targetWorksheets = targetWorkbook.Worksheets;
        currentTargetSheet = (Excel._Worksheet)targetWorksheets.get_Item(1);

        //Determine specialty - in cell A1 of first worksheet as [Data Set Name]: [Provider Name], [Specialty]
        Excel.Range providerRange = currentTargetSheet.get_Range("A1");
        string providerInfo = providerRange.Cells.Value;
        string specialty = providerInfo.Substring(providerInfo.LastIndexOf(",") + 2);
        string providerName = providerInfo.Substring(providerInfo.LastIndexOf(":") + 2, providerInfo.LastIndexOf(",") - (providerInfo.LastIndexOf(":") + 2));

        //Open appropriate Modifier Util workbook, select and copy this provider's worksheet
        string sourceWorkbookName = Path.Combine(DataSetFolder.Text, "Modifier Utilization - " + specialty + ".xlsx");
        Debug.WriteLine(sourceWorkbookName);
        sourceWorkbook = (Excel._Workbook)(XL.Workbooks.Open(sourceWorkbookName));
        if (sourceWorkbook == null)
        {
            Debug.WriteLine("Unable to open worksheet " + sourceWorkbookName);
        }
        Excel.Sheets sourceWorksheets = sourceWorkbook.Worksheets;
        currentSourceSheet = (Excel._Worksheet)sourceWorksheets[providerId];
        if (currentSourceSheet == null)
        {
            Debug.WriteLine("Unable to find " + providerId + " worksheet in " + sourceWorkbookName);
        }

        currentSourceSheet.Copy(Before: currentTargetSheet);                //insert as first worksheet
        currentTargetSheet = (Excel._Worksheet)targetWorksheets.get_Item(1);
        currentTargetSheet.Name = "Modifier Util";

I omitted the rest of the loop - I simply open two other workbooks in the same fashion, copy worksheets into the target workbook, save the target and close this set of workbooks for the next iteration. 我省略了循环的其余部分 - 我只是以相同的方式打开另外两个工作簿,将工作表复制到目标工作簿中,保存目标并关闭这组工作簿以进行下一次迭代。

The error occurs on 发生错误

sourceWorkbook = (Excel._Workbook)(XL.Workbooks.Open(sourceWorkbookName));

So I see the DebugWriteLine of the sourceWorkbookName, but no further. 所以我看到了sourceWorkbookName的DebugWriteLine,但没有进一步。 Excel opens a dialog displaying the error number800A03EC (which I have researched). Excel将打开一个对话框,显示错误号800A03EC(我已研究过)。 If I allow the app to continue processing, on the next iteration it opens a dialog announcing that the workbook is already open, and do I want to re-open and lose changes or continue. 如果我允许应用程序继续处理,则在下一次迭代时会打开一个对话框,通知工作簿已经打开,我是否要重新打开并丢失更改或继续。 Makes no sense to me, based on the first error and the fact that no worksheets are copied from that workbook. 基于第一个错误以及没有从该工作簿复制工作表这一事实对我没有任何意义。

Again, all is well when Excel.visible = true. 同样,当Excel.visible = true时,一切都很好。

I appreciate all suggestions, Scott 斯科特,我感谢所有的建议

Have u tried setting sourceWorkbookName to a basic filename without space's, in a directory without any permission issues? 您是否尝试在没有任何权限问题的目录中将sourceWorkbookName设置为没有空格的基本文件名? I know its a long shot, but for me it would be the place to start, i have encountered some strange behavior with excel 2007 on that one. 我知道这是一个很长的镜头,但对我来说这将是一个开始的地方,我在excel 2007上遇到了一些奇怪的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM