在工业自动化项目中,HMI画面的图层控制是常见需求。当面对几十个甚至上百个需要控制图层显示/隐藏的按钮时,传统逐个编写脚本的方式不仅效率低下,维护起来更是噩梦。本文将带你突破基础操作,用VBScript的循环结构和数组特性重构冗余代码,实现工程级的脚本优化。
打开一个典型的WinCC图层控制项目,你会发现每个按钮的脚本都像这样重复:
vbs复制Dim Sobj
Dim VisibleOn
Set Sobj = hmiruntime.Screens("Layer01")
Set VisibleOn = HMIRuntime.Tags("VisibleOn")
VisibleOn.Write 1
If VisibleOn.Value = 1 Then
Sobj.Layers(1).visible = True
Sobj.Layers(2).visible = False
'...重复5次类似操作
Else
Sobj.Layers(1).visible = False
End If
这种写法存在三个明显问题:
优化方向很明确:
我们先实现最基础的循环控制方案。在全局脚本中创建函数:
vbs复制Function SetLayerVisibility(screenName, layerArray)
Dim screenObj, i
Set screenObj = HMIRuntime.Screens(screenName)
For i = LBound(layerArray) To UBound(layerArray)
screenObj.Layers(i).visible = layerArray(i)
Next
End Function
使用时只需传入画面名称和布尔数组:
vbs复制' 只显示第1层
Dim visibleLayers(6)
visibleLayers(1) = True
For i = 2 To 6
visibleLayers(i) = False
Next
SetLayerVisibility "Layer01", visibleLayers
对比原始方案,代码量减少了70%。但我们可以更进一步。
设计一个更智能的图层管理系统:
vbs复制' 定义图层配置预设
Dim layerPresets
Set layerPresets = CreateObject("Scripting.Dictionary")
' 添加预设配置
layerPresets.Add "ShowRedOnly", Array(True, False, False, False, False, False)
layerPresets.Add "ShowRGB", Array(True, False, True, True, False, False)
' ...其他预设配置
' 智能切换函数
Function ApplyLayerPreset(screenName, presetName)
If layerPresets.Exists(presetName) Then
SetLayerVisibility screenName, layerPresets(presetName)
Else
HMIRuntime.Trace "预设配置不存在:" & presetName
End If
End Function
按钮脚本简化为:
vbs复制ApplyLayerPreset "Layer01", "ShowRGB"
对于多画面项目,我们需要建立中央控制机制:
vbs复制' 画面配置表
Dim screenConfig
Set screenConfig = CreateObject("Scripting.Dictionary")
' 注册画面及其图层数
Sub RegisterScreen(screenName, layerCount)
screenConfig.Add screenName, layerCount
End Sub
' 初始化所有画面图层
Sub InitAllLayers(visible)
Dim screenName, layers(), i
For Each screenName In screenConfig.Keys
ReDim layers(screenConfig(screenName))
For i = 1 To UBound(layers)
layers(i) = visible
Next
SetLayerVisibility screenName, layers
Next
End Sub
使用示例:
vbs复制' 项目初始化时
RegisterScreen "MainScreen", 8
RegisterScreen "SubScreen1", 6
InitAllLayers False ' 隐藏所有图层
结合WinCC变量实现条件触发:
vbs复制' 动态响应变量变化
Sub OnTagChanged(tagName)
Dim presetMap
Set presetMap = CreateObject("Scripting.Dictionary")
presetMap.Add "TagValue1", "Preset1"
presetMap.Add "TagValue2", "Preset2"
If presetMap.Exists(tagName) Then
ApplyLayerPreset "MainScreen", presetMap(tagName)
End If
End Sub
在全局脚本的变量变化事件中调用:
vbs复制Sub SmartTags_OnChanged(item)
OnTagChanged item.Name
End Sub
这种架构下,新增控制逻辑只需修改配置表,无需改动核心代码。我在一个包含32个画面的项目中应用此方案,将脚本总量从原来的2400行缩减到300行,维护效率提升近10倍。