Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Excel.Interop正确有效地隐藏Excel,还是我遗漏了什么?_C#_Excel_Excel Interop - Fatal编程技术网

C# 如何使用Excel.Interop正确有效地隐藏Excel,还是我遗漏了什么?

C# 如何使用Excel.Interop正确有效地隐藏Excel,还是我遗漏了什么?,c#,excel,excel-interop,C#,Excel,Excel Interop,这是我在这个网站上的第一个问题,或者我应该说是第一个帮助查询,所以我会尽可能的清晰和广泛,不要睡着!) 我们正在重塑我们的旧“应用程序”,它是一个Excel模板,充满了自动化、打印、菜单替换和数据库记录,以及所有其他东西,使它成为一个巨大的模板(8MB),或者至少是一个巨大的模板,以这种方式保存每个客户流程的记录(我们每天有+200个新文件,存储空间越来越难以控制) 因此,我开发了一个WPF/C应用程序,仅将模板作为空壳用于计算,这样我就可以存储每个模板版本的副本,而不是每个客户的完整文件,并将

这是我在这个网站上的第一个问题,或者我应该说是第一个帮助查询,所以我会尽可能的清晰和广泛,不要睡着!)

我们正在重塑我们的旧“应用程序”,它是一个Excel模板,充满了自动化、打印、菜单替换和数据库记录,以及所有其他东西,使它成为一个巨大的模板(8MB),或者至少是一个巨大的模板,以这种方式保存每个客户流程的记录(我们每天有+200个新文件,存储空间越来越难以控制)

因此,我开发了一个WPF/C应用程序,仅将模板作为空壳用于计算,这样我就可以存储每个模板版本的副本,而不是每个客户的完整文件,并将数据直接存储到SQL中。我使用Excel.Interop与该模板交互,当需要计算时,我打开该模板,向其提供数据,调用VBA宏运行计算,然后获取一些包含结果数据的范围,以便在我的应用程序中检索。所有这些都需要对用户隐藏(因为CEO这么说!!),因此我使用“Application.Visible=False”

实际的问题是,无论我做什么,无论我在Excel上使用什么版本(至少2010年和2016年),我都会得到我所谓的“错误行为”。当我启动应用程序的多个实例时,每个实例都有自己的Excel实例隐藏在后台运行,每个隐藏工作簿的计算都可以完美地独立工作但是如果我先启动我的应用程序,然后从资源管理器中打开另一个excel文件,excel“窃取”我的隐藏实例以打开这个新文件,然后我的工作簿变为可见。。。起初,我认为使用Excel 2016和正确的注册表项可以解决这个问题(HKCU\Software\Microsoft\Office\16.0\Excel\Options\DisableMergeInstance=1),但它并没有像我预期的那样工作(在新窗口中打开文件之前,它仍然会偷取我的实例的一部分来显示它,如果我隐藏应用程序,它会将其全部隐藏)

我的问题(在这里)是,是否有一种“最佳实践”能够与隐藏工作簿交互,并让我的应用程序实例“独占”使用excel进程?或者是注册表操作的解决方案。。。我的想法快用完了

提前感谢你花时间预读,祝福能让我摆脱困境的人

致以最良好的祝愿

PS:若计算可以被转移到服务器上,那个将有很大帮助,但据我所知,ExcelService不接受运行VBA,所以我坚持使用互操作

[开始编辑1-2018/05/02] 后台启动Excel的代码示例:

private void launchExcel()
    {
        if (xlsApp != null) return;

        isReady = false;

        try
        {
            xlsApp = new Excel.Application();

            //Identification process Excel associé
            GetWindowThreadProcessId(xlsApp.Hwnd, out excelProcessId);

            ("OSEP Excel process ID = " + excelProcessId).writeToConsole();

            //Prevent Excel dialog
            xlsApp.DisplayAlerts = false;

            xlsApp.Visible = myApp.Configuration.mode_excel_visible;

            //Attaches event on Application.Exit, Application.DispatcherUnhandledException, and CurrentDomain.UnhandledException
            //On one of these event : dispose COM objects, and Kill Excel process
            this.CloseWithApplication();

            SheetSelectionChange((s, e) =>
            {
                WriteToConsole("SheetSelectionChange : " + e.Address);
            });

            AfterCalculate(() =>
            {
                WriteToConsole("AfterCalculate");
            });
        }
        catch(Exception ex)
        {
            ex.writeToConsole();
        }
        finally
        {
            isReady = true;
        }           
    }

[结束编辑1-2018/05/02]

您能将计算导入C#并完全绕过Excel互操作吗?即使计算依赖于Excel工作表函数,也可以使用Interop来利用这些函数,同时完全用C#处理数据。这会将模板简化为一个渲染引擎,仅在您想要输出特定客户机的信息时使用。是否有某些特殊原因导致必须使用VBA进行这些计算?也许我没有抓住要点,但当您的应用程序打开此
Excel模板
时,您能否在计算完成后立即关闭它?这样,即使您打开另一个excel实例,您的工作簿也不会被删除visible@ZevSpitz:不幸的是,我不能,流程引擎(在模板中编码)不是由我创建的,而是由一位excel财务专家创建的,我几乎无法自己重新编码,而且,他不愿意成为一名全职开发人员,并适应C#。我们还得出结论,在不断变化的标准下,最好让它们彼此演化出一个零件。@Zac:启动此模板需要10秒,这对我们来说是不可接受的,因为在用户对其模拟进行多次修改/调整后,可以多次运行计算(有时用户必须在客户端打电话时运行它…),这就是我在启动应用程序的背景下启动excel及其模板对应项的原因。如果将隐藏实例的
UserControl
属性设置为
False
,这是否重要?可能不会,因为如果以编程方式打开隐藏实例,它将已经设置为
False
>.