我正在使用 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项目具有相同的行为,因此当图形显示由用户或从代码中关闭时,它会关闭。
要理解该问题的另一个重要方面是,当在FTV中以替换模式打开名为A的通用显示器时,至少一个像素与另一个显示器B重叠时,显示器B处于关闭状态带有其VBA代码。请记住,始终在“替换”模式下打开ma1_header和ma2_header。
也就是说,现在我将描述发现的问题。
绑定到ma1_header和ma2_header的VBA代码基本相同(在以下架构中指出了差异),并且在显示开始时执行了一些初始化操作,然后执行了名为 ScheduleCheck 的过程。此过程将更新一些UI组件,并评估一些条件,以确定是否是时候显示ma2_header(如果ma1_header是在ma2_header之后执行的代码,则该时间),然后重新调用它。
打开显示的命令不是直接从VBA执行的,它是在VBA外部异步执行的。实际上,VBA可以执行某些操作,例如:“显示显示”,“设置标签值”等,从而可以使用一个库来告知FTV服务(也可以与命令行工具一起使用)来执行这些动作的列表(一次传送1个或更多命令)。
当用户启动FTV客户端时,首先显示ma1_header以及构成用户界面的其他一些显示。
在ma1_header中,当满足ma2_header的打开条件并将其打开时,就会出现问题。现在,让我们逐步说明VBA状态,以便尽可能清楚地了解问题所在:
当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
等待过程的执行一直没有问题,直到第18行的 DoEvents 命令为止。在执行DoEvents后,ma1_header有时间确定地关闭自身(甚至是其vba代码),然后ma2_header中的vba流似乎在此处停止,没有任何错误。因此,ScheduleCheck无法回忆起自己。
目前,我发现了所谓的丑陋解决方案,可以使代码正常工作。
当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过程,而不会引起奇怪的执行中断。
我不知道为什么这可以解决我的问题,所以我想了解它为什么起作用,并且是导致此问题的原因,以便找到更好的解决方案。
我找到了另一个丑陋的解决方案,但是像以前一样,我不满意,因为我想知道我当前的代码有这个问题(对我来说,解决一个问题而不知道是什么原因导致了程序员的失败)。
我在ma1_header和ma2_header中添加了一个包含新标签Tick的字符串显示
对于这个问题的任何澄清或更好的解决方案,我们将不胜感激。