简体   繁体   English

确定弹出窗口是否在Excel的前景中

[英]Determine if Popup is in foreground of Excel

I'm writing a VSTO add-in for Excel and I have noticed that if I lock the sheet and password protect it (so only my add-in can write to it but the user can view it), if the user tries to edit the sheet they get the "This sheet is locked" popup. 我正在为Excel编写VSTO加载项,并且我注意到,如果用户尝试编辑该表并对其进行密码保护(因此只有我的加载项可以写入,但用户可以查看),他们收到“此工作表已锁定”的工作表弹出窗口。 If while that prompt is still pending user input, the add-in tries to write to the sheet, Excel crashes. 如果在该提示仍在等待用户输入时,该加载项尝试写入工作表,则Excel崩溃。 The act of writing to the sheet involves unprotecting it, writing the data, then locking it again. 写入工作表的操作包括取消保护工作表,写入数据,然后再次锁定它。 The Add-in captures data from an external source via the serial port so data could be written at any time. 外接程序通过串行端口从外部源捕获数据,因此可以随时写入数据。

To recreate: 1. Lock sheet with add-in. 要重新创建:1.锁定带有加载项的工作表。 2. User attempts to edit sheet contents 3. User is prompted that they cannot edit the contents of the sheet because it is locked. 2.用户尝试编辑工作表内容。3.提示用户无法编辑工作表内容,因为它已被锁定。 4. Data comes in the serial port and the add-in attempts to unlock, write data, and lock the sheet before the user has a chance to ack the prompt that was thrown. 4.数据进入串行端口,并且在用户有机会确认所引发的提示之前,加载项会尝试解锁,写入数据和锁定工作表。 5. Excel bytes the dust. 5. Excel清除灰尘。

Any suggestions? 有什么建议么? I was toying with the idea of maintaining a hidden "master" sheet and the visible sheet and just using an excel formula or named range to reference the hidden sheet. 我一直在想维护一个隐藏的“主”表和可见表,而只是使用一个excel公式或命名范围来引用该隐藏表。 However this would then be open to editing and potential data corruption by a user. 但是,这将对用户进行编辑和潜在的数据破坏开放。 The data must be as un-editable as possible. 数据必须尽可能不可编辑。

Update: I would be satisfied with catching the COMException so it doesn't kill excel, however the general "catch (Exception ex)" doesn't seem to help. 更新:我对捕获COMException非常满意,因此它不会杀死excel,但是常规的“ catch(ex ex ex)”似乎没有帮助。

In VBA you can protect the sheet with UserInterFaceOnly:=True. 在VBA中,您可以使用UserInterFaceOnly:= True保护工作表。 This means the code can still write to the sheet. 这意味着代码仍然可以写入工作表。 From this link it looks like this is true with a VSTO addin as well. 从该链接看来,VSTO插件也是如此。

You may put check to ensure sheet is in interactive mode or active cell is not null, if check fails exit function that perform write operation 如果检查失败退出执行写操作的退出功能,则可以进行检查以确保工作表处于交互模式或活动单元不为空

 private bool IsExcelInteractive()
    {
        try
        {
            Globals.ThisAddIn.Application.Interactive = Globals.ThisAddIn.Application.Interactive;
            return true;
        }
        catch
        {
            return false;
        }
    }

The issue was apparently 问题显然是

catch(Exception)

does not function as a general catch all when it comes to a COMException. 当涉及到COMException时,它不能作为通用功能。 Adding the line 添加线

using System.Runtime.InteropServices;

and then adding 然后添加

catch(COMException)

to my try...catch blocks allows me to handle the errors better. 我的尝试... catch块使我可以更好地处理错误。 Mix that with some code to retry the failed action a few times after using 使用后,将其与一些代码混合以重试失败的操作几次

SendKeys.SendWait("{ESC}");

seems to make things better. 似乎使事情变得更好。 However, blindly sending the escape key to the forefront program can cause some issues however I cannot sit in an endless loop waiting for a user who may or may not be paying attention to clear up the issue on the screen. 但是,盲目地将转义键发送到最前端的程序可能会导致一些问题,但是我不能无休止地等待用户,他们可能会或可能不会注意在屏幕上清除问题。 It seems to cause the serial port to stop buffering data and just dropping it if it's not handled fast enough. 似乎导致串行端口停止缓冲数据,如果处理速度不够快,则将其丢弃。

您可以在功能区中添加一个按钮,然后单击它来执行此任务,而不是在单击单元格时执行此操作,这样就可以摆脱弹出窗口

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

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