简体   繁体   English

使用 C# 互操作打开 Excel 文件时忽略失败的宏

[英]Ignore Failing Macro when Opening Excel File with C# Interop

I have been asked to write a script to crawl through a load of folder locations and list out all the Excel spreadsheets that have connections to a set of SQL and other data sources that are due to be upgraded to a new server.我被要求编写一个脚本来爬取大量文件夹位置并列出所有 Excel 电子表格,这些电子表格与一组 SQL 和其他将升级到新服务器的数据源有连接。

In order to do this, I need to open each file, then check the connections and return those that match the criterion set.为此,我需要打开每个文件,然后检查连接并返回与标准集匹配的连接。 All this happens fine until I hit any file where the end user has made a macro to run on open that refers to a non-existent file - As the C# script opens the file, the file presents the following message:所有这一切都发生得很好,直到我点击了最终用户在打开时运行宏的任何文件,该文件引用了一个不存在的文件 - 当 C# 脚本打开文件时,文件显示以下消息:

错误弹出窗口

If I manually click "End", the script moves on to the next file and all is ok, but I would much rather avoid any user input and record the fact that there was a problem with the macro... How would I go about doing that?如果我手动单击“结束”,脚本将转到下一个文件,一切正常,但我更愿意避免任何用户输入并记录宏存在问题的事实......我将如何 go 关于这样做?

I have set the Excel property "Disable all macros without notification" to true on the computer that will be running the script, using the same username as will run it, which I thought would prevent this kind of thing happening.我已经在将运行脚本的计算机上将 Excel 属性“禁用所有宏而不通知”设置为 true,使用与运行脚本相同的用户名,我认为这可以防止这种事情发生。 I also open Excel with DisplayAlerts=false , so that isn't the problem...我还用DisplayAlerts=false打开 Excel ,所以这不是问题......

I don't need to run the macro at all and would rather not..!我根本不需要运行宏,也不想......!

for context, the code snippet that opens each file looks like this:对于上下文,打开每个文件的代码片段如下所示:

var app = new Application
{
    Visible = false,
    DisplayAlerts = false,
    ScreenUpdating = false
};
Workbook thisFile = null;
try
{
    //send a false password to stop Excel asking for one - when it is wrong, the error will be caught.
    thisFile = app.Workbooks.Open(file.FullName, ReadOnly: true, Password: "FakePassword");

    foreach (WorkbookConnection connection in thisFile.Connections)
    {

EDIT: It occurs to me that maybe I could do something with a timeout..?编辑:我突然想到,也许我可以做一些超时..? If there were some way to close the popup box from the script, that would do the job - I could just record that the timer expired in the output, which would be enough.如果有某种方法可以从脚本中关闭弹出框,那就可以了——我可以在 output 中记录计时器已过期,这就足够了。 So... alternatively is there a way to just close the box after it has popped up?所以......或者有没有办法在它弹出后关闭盒子?

I have been able to disable startup macros when I open the workbook by holding down shift when opening the file.通过在打开文件时按住 shift 打开工作簿时,我已经能够禁用启动宏。

I believe the interop way to handle this is to use the application AutomationSecurity property:我相信处理此问题的互操作方法是使用应用程序AutomationSecurity属性:

Excel.Application app = new Excel.Application();
app.Visible = true;
app.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable;

I tested this on a simple workbook that popped up a message box and put the current time in A1, and it seemed to work properly.我在一个弹出消息框并将当前时间放在 A1 中的简单工作簿上对此进行了测试,它似乎工作正常。

Excel.Workbook wb = app.Workbooks.Open("c:/cdh/foot.xlsm");

Default, the message box popped up and A1 had a value, and when I set it to disable neither happened.默认情况下,弹出消息框并且 A1 有一个值,当我将其设置为禁用时,都没有发生。

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

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