Windows 脚本宿主 - 带有 COM 对象的 JScript 和 VBScript

Windows Script Host - JScript and VBScript with COM Object

在这里挣扎...

VBScript

我加载了一个 DLL,可以创建一个对象;

Set objServer = CreateObject("Matrikon.OPC.Automation.1")

然后我可以基于 objServer 的 属性 创建一个新对象(我想我说的对吗?)

Set objGroups = objServer.OPCGroups
Set objGroup = objGroups.Add("Group001")

手册显示 OPCGroupsPropertyOPCServer。一旦我调用了这个 属性,我就得到了一个 OPCGroups 类型的新对象,然后我可以调用它的属性和方法。

Syntax  OPCGroups As OPCGroups

这很好用。然后我继续,调用这个函数时卡住了;

Syntax  AddItems (Count As Long, ItemIDs() As String, ClientHandles() As Long, ByRef  ServerHandles() As Long, ByRef Errors() As Long, Optional RequestedDataTypes As Variant, Optional AccessPaths As Variant)

它需要一个字符串数组。然而,在 VBScript 中,我总是以变体数组 (VarType = 8204) 结束。当我尝试传递数组时,出现类型不匹配错误。我找不到将其强类型化为字符串数组的方法;我什至不确定这是否可能。

转向 JScript

JScript

我执行与上面相同的第一步,但是当我创建 OPCGroups 对象时;

var objGroups = objServer.OPCGroups;

有些东西没有用。它实际上并没有创建一个 OPCGroups 对象及其所有关联的 Properties/Methods。当我尝试调用方法时

var objGroup = objGroups.Add();

它说“对象不支持此 属性 或方法”。就好像它刚刚创建了一个 generic/blank 对象;没有一个类型为 OPCGroups 对象。

所以。我可以解决 其中一个 这些问题吗?

有一段时间没在这个问答部分见到一位自动化专家了。和 Matrikon 一起工作吧?我个人更喜欢 autosol 或 kepware。无论如何,到你的代码。您引用的手册是为 VBA 而不是 vbscript 编写的,并提供了 "As xxxx" 描述符,而 VBScript 不需要这些描述符。在将其放入 .vbs 文件之前,您应该打开 excel,在 excel 引用中附加 COM 对象,阅读下面的 article/code 并测试它。

Dim TestServer As OPCServer
Dim TestGroupCollection As OPCGroups
Dim WithEvents Group1 As OPCGroup
Dim ItemCollection1 As OPCItems

Dim OPCItemIDs() As String
Dim ClientHandles() As Long
Dim ReadWriteHandles() As Long

Dim ItemServerHandles() As Long
Dim ItemServerErrors() As Long
Dim RequestedDataTypes As Variant
Dim AccessPaths As Variant
Dim MaxItems As Integer

' Start monitoring the value
Private Sub StartBtn_Click()
  Dim ItemTag As String
  ItemTag = "D57PT201.AI_MEAS"

  Dim ItemValues() As Variant
  Dim ItemQualities As Variant
  Dim ItemTimeStamps As Variant
  Dim idx As Integer

  MaxItems = 1
  ReDim OPCItemIDs(MaxItems)
  ReDim ClientHandles(MaxItems)
  ReDim ReadWriteHandles(MaxItems)

  ' Create connection to the OPC server
  Set TestServer = CreateObject("Matrikon.OPC.Automation.1")

  TestServer.Connect "Matrikon.OPC.Simulation.1"

  ' Create a group to contain the tag
  Set TestGroupCollection = TestServer.OPCGroups
  Set Group1 = TestGroupCollection.Add("group1")
  Group1.ClientHandle = 100
  Group1.UpdateRate = 1000

  Set ItemCollection1 = Group1.OPCItems
  ItemCollection1.DefaultAccessPath = ""

  ' Add the tag
  For idx = 1 To MaxItems
    ClientHandles(idx) = idx
    OPCItemIDs(idx) = ItemTag
  Next idx

  ItemCollection1.AddItems MaxItems, OPCItemIDs, ClientHandles, ItemServerHandles, ItemServerErrors, RequestedDataTypes, AccessPaths
  MsgBox "Success"
End Sub

以下是使用 Matrikon OPC 引擎正确初始化轮询会话的示例:

AutomationException: 0x80070057 - One or more arguments are invalid

只是清理一下。

我使用过 PowerShell - 令人惊讶的是 3 年前我对 PowerShell 一无所知。使用较新的 .NET OPC API,它更简单;

加载 DLL

$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
# Namespaces Opc, Opc.Ae, Opc.Da, Opc.Hda
Add-Type -Path ($PSScriptRoot + "\OpcNetApi.dll")
# Namespaces OpcCom, OpcCom.Ae, OpcCom.Da, OpcCom.Hda, OpcCom.Da20 and OpcCom.Da.Wrapper - the same namespace as the original Interop.OPCAutomation.dll
Add-Type -Path ($PSScriptRoot + "\OpcNetApi.Com.dll")

将标签做成字符串数组,然后转换为Opc.Da.Items[]

# Convert array of strings into an Array of Opc.Da.Items[]
$masterItemsList = $tagList | ForEach {New-Object "Opc.DA.Item" ([String]$_)}

连接到 OPC 服务器

$opcFactory = New-Object "OpcCom.Factory"
# Constructor is Opc.Da.Server(OPC.Factory factory, Opc.URL url). Leave URL $null - apply it in the connect method
$opcServer = New-Object "Opc.DA.Server" ($opcFactory, $null)

$opcURL = New-Object "Opc.URL" ("opcda://" + $serverName + "/" + $progID)
# Method is void Connect(Opc.URL url, new Opc.ConnectData(new System.Net.NetworkCredential())). connectData can supply Windows Credentials
$opcServer.Connect($opcURL, $null)

无需创建OPC组;它是自动完成的。

$opcResults = $opcServer.Read([Opc.Da.ItemValueResult[]]$masterItemsList)

这并没有真正解决 VBS/JScript 问题,但我希望有人觉得它有用。

(免责声明:这是自我推销)

借助 QuickOPC 库,您可以使用 VBScript (http://opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%27s%20Guide%20and%20Reference-QuickOPC/webframe.html#Examples%20-%20OPC%20Data%20Access%20-%20Read%20a%20single%20item.html ), JScript or PowerShell (https://www.opclabs.com/products/quickopc/languages-and-tools/powershell)。

用于读取项目的 VBScript 代码:

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
Dim Vtq: Set Vtq = Client.ReadItem("", "OPCLabs.KitServer.2", "Simulation.Random")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0
WScript.Echo "Vtq: " & Vtq

PowerShell 代码:

using namespace OpcLabs.EasyOpc.DataAccess
using namespace OpcLabs.EasyOpc.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Assemblies/net47/OpcLabs.EasyOpcClassic.dll"

# Instantiate the client object.
$client = New-Object EasyDAClient

try {
    $vtq = [IEasyDAClientExtension]::ReadItem($client, "", "OPCLabs.KitServer.2", "Simulation.Random")
}
catch [OpcException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

Write-Host "Vtq: $($vtq)"