0

Stuggling here...

VBScript

I have a DLL loaded, and can create an Object;

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

I can then create a new Object, based on a Property of the objServer (I think I am saying that right?)

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

The manual shows OPCGroups is a Property of OPCServer. Once I have called this Property, I am left with a new Object of type OPCGroups, that I can then call its Properties and Methods.

Syntax  OPCGroups As OPCGroups

This works fine. I then continue, and get stuck when calling this function;

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)

It wants an Array of Strings. However, in VBScript, I always end up with an Array of Variants (VarType = 8204). When I try and pass my array, I get a Type Mismatch error. I can't find a way of strongly typing it to an Array of Strings; I'm not even sure it's possible.

Over to JScript

JScript

I perform the same first steps as above, but when I create the OPCGroups object;

var objGroups = objServer.OPCGroups;

Something hasn't worked. It hasn't actually created an OPCGroups object with all its associated Properties/Methods. When I try and call a Method

var objGroup = objGroups.Add();

It says the 'Object doesn't support this property or method'. It's as though it just created a generic/blank Object; not one typed as an OPCGroups object.

So. Can I workaround either of these issues?

3
  • With the vbscript version did you try coercing each item of the array to a string with the cstr function? Commented Feb 10, 2017 at 13:30
  • sure did; Do Until objTextFile.AtEndOfStream Redim Preserve arrFileLines(i) arrFileLines(i) = CStr(objTextFile.Readline) i = i + 1 Loop Commented Feb 10, 2017 at 14:58
  • some info here: support.microsoft.com/en-us/help/244012/… Commented Feb 10, 2017 at 15:11

3 Answers 3

1

(Disclaimer: This is a self-promotion)

With QuickOPC library, you can use 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 code for reading an item:

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 code:

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)"
Sign up to request clarification or add additional context in comments.

Comments

0

Been a while since I seen a fellow automation specialist in this Q&A section. Working with Matrikon huh? I prefer autosol or kepware personally. Anyway, onto your code. The manual you are referencing is written for VBA rather than vbscript and provides the "As xxxx" descriptors, where as VBScript doesn't need those. Before tossing this into a .vbs file, you should open up excel, attach the COM object in the excel references, read the article/code below and test it out.

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

Here is an example of a properly initialized polling session with the Matrikon OPC Engine:

AutomationException: 0x80070057 - One or more arguments are invalid

1 Comment

Not Matrikon per se; but their OPCDAAuto.dll. Yeah I've had it running in VBA in Excel, I was hoping to just have it in a script file - without the need for compilation. Powershell is an option, but I know nothing of Powershell. OPC also have a .NET implementation of the DLL, but I know nothing of .NET, and they only release the specifications to Corporate Members.
0

Just cleaning this up.

I used PowerShell - amazing how 3 years ago I knew nothing about PowerShell. Using newer .NET OPC APIs, it was much simpler;

Load DLLs

$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")

Make an array of tags as strings, and then convert to Opc.Da.Items[]

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

Connect to OPC Server

$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)

No need to create an OPC Group; it is done automatically.

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

This doesn't really solve the VBS/JScript issue, but I hope someone finds it helpful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.