【问题标题】:Windows Script Host - JScript and VBScript with COM ObjectWindows 脚本宿主 - 带有 COM 对象的 JScript 和 VBScript
【发布时间】:2017-06-28 14:22:18
【问题描述】:

在这里挣扎……

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 对象。当我尝试调用方法时

var objGroup = objGroups.Add();

它说“对象不支持此属性或方法”。就好像它只是创建了一个通用/空白对象;没有一个键入为 OPCGroups 对象。

所以。我可以解决任一这些问题吗?

【问题讨论】:

  • 在 vbscript 版本中,您是否尝试使用 cstr 函数将数组的每一项强制转换为字符串?
  • 确实做到了; Do Until objTextFile.AtEndOfStream Redim Preserve arrFileLines(i) arrFileLines(i) = CStr(objTextFile.Readline) i = i + 1 Loop

标签: vbscript jscript wsh


【解决方案1】:

(免责声明:这是一种自我宣传)

借助 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 或 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)"

【讨论】:

    【解决方案2】:

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

    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

    【讨论】:

    • 不是 Matrikon 本身;但他们的 OPCDAAuto.dll。是的,我已经在 Excel 中的 VBA 中运行它,我希望只将它放在脚本文件中 - 无需编译。 Powershell是一种选择,但我对Powershell一无所知。 OPC 也有 DLL 的 .NET 实现,但我对 .NET 一无所知,他们只向企业成员发布规范。
    【解决方案3】:

    只是清理一下。

    我使用 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 问题,但我希望有人觉得它有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      相关资源
      最近更新 更多