VBA执行流程意外中断

时间:2018-07-02 14:51:52

标签: vba execution scada

问题的背景

我正在使用 Factory Talk View Studio 7.00.00(CPR 9 SR 6) VBA 6.5 为HMI开发新功能。
我有两个显示器: ma1_header ma2_header ,而且众所周知,在Factory Talk View Studio中(为简便起见,我将其称为FTV) )的每个显示都有专用的 DisplayCode 。 显示代码可以看作是Excel文件后面的VBA代码,只要它的Excel文件保持打开状态即可。从这个角度来看,绑定到FTV中的显示器的VBA代码与excel中的VBA项目具有相同的行为,因此当图形显示由用户或从代码中关闭时,它会关闭。

enter image description here

要理解该问题的另一个重要方面是,当在FTV中以替换模式打开名为A的通用显示器时,至少一个像素与另一个显示器B重叠时,显示器B处于关闭状态带有其VBA代码。请记住,始终在“替换”模式下打开ma1_header和ma2_header。

问题描述

也就是说,现在我将描述发现的问题。
绑定到ma1_header和ma2_header的VBA代码基本相同(在以下架构中指出了差异),并且在显示开始时执行了一些初始化操作,然后执行了名为 ScheduleCheck 的过程。此过程将更新一些UI组件,并评估一些条件,以确定是否是时候显示ma2_header(如果ma1_header是在ma2_header之后执行的代码,则该时间),然后重新调用它。

enter image description here

打开显示的命令不是直接从VBA执行的,它是在VBA外部异步执行的。实际上,VBA可以执行某些操作,例如:“显示显示”,“设置标签值”等,从而可以使用一个库来告知FTV服务(也可以与命令行工具一起使用)来执行这些动作的列表(一次传送1个或更多命令)。
当用户启动FTV客户端时,首先显示ma1_header以及构成用户界面的其他一些显示。
在ma1_header中,当满足ma2_header的打开条件并将其打开时,就会出现问题。现在,让我们逐步说明VBA状态,以便尽可能清楚地了解问题所在:

  1. 在ma1_header中满足打开条件,并且执行显示ma2_header的异步命令。请注意,目前ma1_header vba仍处于打开状态。
  2. 当ma2_header开始打开代码时,直到执行等待过程都没有问题。等待过程如下:

    Public Declare Function GetTickCount Lib "kernel32" () As Long
    
    Public Sub wait(lMillSec As Long)
        Dim lT2 As Long
        Dim lT1 As Long
    
    On Error GoTo errHandle
        Const strMethod = "wait"
        MsgBox "wait - 1"
        lT1 = GetTickCount
        lT2 = lT1
        While lT2 - lT1 < lMillSec
            lT2 = GetTickCount
            DoEvents
        Wend
    errHandle:
        If Err.Number Then
            LogDiagnosticsMessage "VBA: Display " & Me.Name & " in Method " & strMethod
            Err.Clear
        End If
    End Sub
    
  3. 等待过程的执行一直没有问题,直到第18行的 DoEvents 命令为止。在执行DoEvents后,ma1_header有时间确定地关闭自身(甚至是其vba代码),然后ma2_header中的vba流似乎在此处停止,没有任何错误。因此,ScheduleCheck无法回忆起自己。

丑陋的解决方案1 ​​

目前,我发现了所谓的丑陋解决方案,可以使代码正常工作。

当ma1_header打开时,ma2_header的打开将强制ma1_header的关闭(如我之前所述),仅在执行DoEvents时才完成。 当需要显示ma2_header时,我尝试将这个新的命令列表传输给FTW工具:

##New##
Abort MA2_HEADER;
Pause 1;
Display MA1_HEADER /TRRU;

##Old##
Display MA1_HEADER /TRRU;

使用新方法,我关闭了ma2_header,然后使用命令“暂停1;”(在FTV工具中,而不是在VBA中)等待1秒。然后在合理确定ma1_heder已关闭的情况下(由于使用了stop命令),我打开了ma1_header。 这样ma2_heder会定期执行ScheduleCheck过程,而不会引起奇怪的执行中断。

我不知道为什么这可以解决我的问题,所以我想了解它为什么起作用,并且是导致此问题的原因,以便找到更好的解决方案。

丑陋的解决方案2

我找到了另一个丑陋的解决方案,但是像以前一样,我不满意,因为我想知道我当前的代码有这个问题(对我来说,解决一个问题而不知道是什么原因导致了程序员的失败)。

  1. 我已经在FTV的代码服务器上创建了以下新代码

enter image description here

  1. 我在FTV上创建了以下新事件

enter image description here

  1. 我在ma1_header和ma2_header中添加了一个包含新标签Tick的字符串显示

    1. 现在,在VBA中,每次此字符串显示发生更改时,我都可以使用此字符串显示的 Change 事件来执行ScheduleCheck中包含的相同代码(显然,无需等待DoEvents循环) (每秒)。

对于这个问题的任何澄清或更好的解决方案,我们将不胜感激。

0 个答案:

没有答案