OPC Studio User's Guide and Reference
BrowseNodes Method (_EasyDAClient)
Example 



OpcLabs.EasyOpcClassic Assembly > OpcLabs.EasyOpc.DataAccess.ComTypes Namespace > _EasyDAClient Interface : BrowseNodes Method
The OPC server involved in the operation.

Because the OpcLabs.EasyOpc.ServerDescriptor has an implicit conversion from System.Guid, System.String and OpcLabs.EasyOpc.ServerElement, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a GUID (representing the CLSID of the server), a string (representing the so-called OPC server descriptor string, such as a ProgID or the URL of the server), or a OpcLabs.EasyOpc.ServerElement object (result from OPC browsing), in place of this parameter, and the corresponding OPC server descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the OpcLabs.EasyOpc.ServerDescriptor.FromGuid, OpcLabs.EasyOpc.ServerDescriptor.FromString or OpcLabs.EasyOpc.ServerDescriptor.FromServerElement static method instead.

The value of this parameter cannot be null (Nothing in Visual Basic).

Descriptor for the parent branch to be browsed (can be the root).

Because the OpcLabs.EasyOpc.DataAccess.DANodeDescriptor has an implicit conversion from System.String and OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a string (representing the qualified name of the node), or a OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement object (result from OPC browsing), in place of this parameter, and the corresponding OPC DA node descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the OpcLabs.EasyOpc.DataAccess.DANodeDescriptor.FromString or OpcLabs.EasyOpc.DataAccess.DANodeDescriptor.FromDANodeElement static method instead.

The value of this parameter cannot be null (Nothing in Visual Basic).

Contains filtering conditions.

The value of this parameter cannot be null (Nothing in Visual Basic).

Browses the specified branch (or root) in OPC server's address space, and returns information about child nodes (both branches and leaves) found. Specify server descriptor, parent item ID, and node filter.
Syntax
'Declaration
 
<NotNullAttribute()>
Function BrowseNodes( _
   ByVal serverDescriptor As Object, _
   ByVal parentNodeDescriptor As Object, _
   ByVal browseParameters As Object _
) As DANodeElementCollection
'Usage
 
Dim instance As _EasyDAClient
Dim serverDescriptor As Object
Dim parentNodeDescriptor As Object
Dim browseParameters As Object
Dim value As DANodeElementCollection
 
value = instance.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)

Parameters

serverDescriptor
The OPC server involved in the operation.

Because the OpcLabs.EasyOpc.ServerDescriptor has an implicit conversion from System.Guid, System.String and OpcLabs.EasyOpc.ServerElement, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a GUID (representing the CLSID of the server), a string (representing the so-called OPC server descriptor string, such as a ProgID or the URL of the server), or a OpcLabs.EasyOpc.ServerElement object (result from OPC browsing), in place of this parameter, and the corresponding OPC server descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the OpcLabs.EasyOpc.ServerDescriptor.FromGuid, OpcLabs.EasyOpc.ServerDescriptor.FromString or OpcLabs.EasyOpc.ServerDescriptor.FromServerElement static method instead.

The value of this parameter cannot be null (Nothing in Visual Basic).

parentNodeDescriptor
Descriptor for the parent branch to be browsed (can be the root).

Because the OpcLabs.EasyOpc.DataAccess.DANodeDescriptor has an implicit conversion from System.String and OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a string (representing the qualified name of the node), or a OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement object (result from OPC browsing), in place of this parameter, and the corresponding OPC DA node descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the OpcLabs.EasyOpc.DataAccess.DANodeDescriptor.FromString or OpcLabs.EasyOpc.DataAccess.DANodeDescriptor.FromDANodeElement static method instead.

The value of this parameter cannot be null (Nothing in Visual Basic).

browseParameters
Contains filtering conditions.

The value of this parameter cannot be null (Nothing in Visual Basic).

Return Value

The method returns a keyed collection of OpcLabs.EasyOpc.DataAccess.AddressSpace.DANodeElement values, each containing information about a particular node found. The keys of the keyed collection are the names of the nodes.

This method never returns null (Nothing in Visual Basic).

The individual elements of the returned value are never null (Nothing in Visual Basic).

Exceptions
ExceptionDescription

A null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.

This is a usage error, i.e. it will never occur (the exception will not be thrown) in a correctly written program. Your code should not catch this exception.

The OPC "Classic" (or OPC XML-DA) operation has failed. This operation exception in uniformly used to allow common handling of various kinds of errors. The System.Exception.InnerException always contains information about the actual error cause.

This is an operation error that depends on factors external to your program, and thus cannot be always avoided. Your code must handle it appropriately.

Remarks

This member or type is for use from COM. It is not meant to be used from .NET or Python. Refer to the corresponding .NET member or type instead, if you are developing in .NET or Python.

The server(s) can be local or can be remotely accessed via DCOM.

Example

COM

COM

// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

class procedure BrowseNodes.Main;
var
  BrowseParameters: _DABrowseParameters;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  Count: Cardinal;
  Element: OleVariant;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
  NodeElement: _DANodeElement;
  NodeElementEnumerator: IEnumVariant;
  NodeElements: _DANodeElementCollection;
begin
  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := 'Simulation';

  BrowseParameters := CoDABrowseParameters.Create;

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  try
    NodeElements := Client.BrowseNodes(
      ServerDescriptor,
      NodeDescriptor,
      BrowseParameters);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  NodeElementEnumerator := NodeElements.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
//    WriteLn(NodeElement.Name, ': ', NodeElement.ItemId);
    WriteLn('BrowseElements("', NodeElement.Name, '"):');
    WriteLn('    .IsBranch: ', NodeElement.IsBranch);
    WriteLn('    .IsLeaf: ', NodeElement.IsLeaf);
  end;
end;
// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->ServerClass = "OPCLabs.KitServer.2";

$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "Simulation";

$BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters");

$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");

try
{
    $NodeElements = $Client->BrowseNodes($ServerDescriptor, $NodeDescriptor, $BrowseParameters);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

foreach ($NodeElements as $NodeElement)
{
    printf("NodeElements(\"%s\"):\n", $NodeElement->Name);
    printf("    .IsBranch: %s\n", $NodeElement->IsBranch ? 'true' : 'false');
    printf("    .IsLeaf: %s\n", $NodeElement->IsLeaf ? 'true' : 'false');
}
# This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
# whether the node is a branch or a leaf.
#
# The Python for Windows (pywin32) extensions package is needed. Install it using "pip install pypiwin32".
# CAUTION: We now recommend using Python.NET package instead. Full set of examples with Python.NET is available!
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
import win32com.client
from pywintypes import com_error

serverDescriptor = win32com.client.Dispatch('OpcLabs.EasyOpc.ServerDescriptor')
serverDescriptor.ServerClass = 'OPCLabs.KitServer.2'

nodeDescriptor = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.DANodeDescriptor')
nodeDescriptor.ItemID = 'Simulation'

browseParameters = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.DABrowseParameters')

# Instantiate the client object
client = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.EasyDAClient') 

# Perform the operation
try:
    nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
except com_error as e:
    print('*** Failure: ' + e.args[2][1] + ': ' + e.args[2][2])
    exit()

# Display results
for nodeElement in nodeElements:
    print('NodeElements("' + nodeElement.Name + '"):')
    print('    .IsBranch:', nodeElement.IsBranch)
    print('    .IsLeaf:', nodeElement.IsLeaf)


# Example output:
#
#NodeElements("Register_ArrayOfI1"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI2"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI4"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Staircase 0:2 (10 s)"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Constant_VARIANT"):
#    .IsBranch: False
#    .IsLeaf: True
#...
// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")

// Prepare the arguments

OLEObject serverDescriptor
serverDescriptor = CREATE OLEObject
serverDescriptor.ConnectToNewObject("OpcLabs.EasyOpc.ServerDescriptor")
serverDescriptor.ServerClass = "OPCLabs.KitServer.2"

OLEObject nodeDescriptor
nodeDescriptor = CREATE OLEObject
nodeDescriptor.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
nodeDescriptor.ItemID = "Simulation"

OLEObject browseParameters
browseParameters = CREATE OLEObject
browseParameters.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")

// Perform the operation
OLEObject nodeElements
TRY
    nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
CATCH (OLERuntimeError oleRuntimeError)
    mle_outputtext.Text = mle_outputtext.Text + "*** Failure: " + oleRuntimeError.Description + "~r~n"
    RETURN
END TRY

OLEObject nodeElementList
nodeElementList = nodeElements.ToList()

// Display results
Int i
FOR i = 0 TO nodeElementList.Count - 1
    OLEObject nodeElement
    nodeElement = nodeElementList.Item[i]
    mle_outputtext.Text = mle_outputtext.Text + 'NodeElements("' + nodeElement.Name + '"):' + "~r~n" 
    mle_outputtext.Text = mle_outputtext.Text + "    nodeElement.IsBranch: " + String(nodeElement.IsBranch) + "~r~n"
    mle_outputtext.Text = mle_outputtext.Text + "    nodeElement.IsLeaf: " + String(nodeElement.IsLeaf) + "~r~n"
NEXT

mle_outputtext.Text = mle_outputtext.Text + "~r~n" 
mle_outputtext.Text = mle_outputtext.Text + "Finished." + "~r~n" 
REM This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
REM whether the node is a branch or a leaf.
REM
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.

Private Sub BrowseNodes_Main_Command_Click()
    OutputText = ""
    
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    
    Dim nodeDescriptor As New DANodeDescriptor
    nodeDescriptor.itemId = "Simulation"
    
    Dim browseParameters As New DABrowseParameters
    
    ' Instantiate the client object
    Dim client As New EasyDAClient

    On Error Resume Next
    Dim nodeElements As DANodeElementCollection
    Set nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    Dim nodeElement: For Each nodeElement In nodeElements
        OutputText = OutputText & "BrowseElements(""" & nodeElement.Name & """): " & nodeElement.itemId & vbCrLf
        OutputText = OutputText & "    .IsBranch: " & nodeElement.IsBranch & vbCrLf
        OutputText = OutputText & "    .IsLeaf: " & nodeElement.IsLeaf & vbCrLf
    Next
    
End Sub
Rem This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
Rem whether the node is a branch or a leaf.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"

Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = "Simulation"

Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")

Dim Client: Set Client= CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
Dim NodeElements: Set NodeElements = Client.BrowseNodes(ServerDescriptor, NodeDescriptor, BrowseParameters)
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim NodeElement: For Each NodeElement In NodeElements
    WScript.Echo "NodeElements(""" & NodeElement.Name & """):"
    With NodeElement
        WScript.Echo Space(4) & ".IsBranch: " & .IsBranch
        WScript.Echo Space(4) & ".IsLeaf: " & .IsLeaf
    End With
Next
// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

type
  TBrowseNodes = class
    BranchCount: Integer;
    LeafCount: Integer;
    procedure BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor:  _DANodeDescriptor);
  end;

procedure TBrowseNodes.BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor: _DANodeDescriptor);
var
  BrowseParameters: _DABrowseParameters;
  Count: Cardinal;
  Element: OleVariant;
  NodeElement: _DANodeElement;
  NodeElementEnumerator: IEnumVariant;
  NodeElements: _DANodeElementCollection;
begin
  // Obtain all node elements under ParentNodeDescriptor
  BrowseParameters := CoDABrowseParameters.Create;  // no filtering whatsover
  NodeElements := Client.BrowseNodes(
    ServerDescriptor,
    ParentNodeDescriptor,
    BrowseParameters);
  // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
  // it, here omitted for brevity.

  NodeElementEnumerator := NodeElements.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
    WriteLn(NodeElement.ToString);

    // If the node is a branch, browse recursively into it.
    if NodeElement.IsBranch then
    begin
      BranchCount := BranchCount + 1;
      BrowseFromNode(Client, ServerDescriptor, NodeElement.ToDANodeDescriptor);
    end
    else
      LeafCount := LeafCount + 1;
  end;
end;

class procedure BrowseNodes.RecursiveXml;
var
  BeginTime: Cardinal;
  BrowseNodes: TBrowseNodes;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  EndTime: Cardinal;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
begin
  BrowseNodes := TBrowseNodes.Create;
  BrowseNodes.BranchCount := 0;
  BrowseNodes.LeafCount := 0;

  BeginTime := Ticks;

  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.UrlString := 'http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := '';

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  try
    BrowseNodes.BrowseFromNode(
      Client,
      ServerDescriptor,
      NodeDescriptor);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  EndTime := Ticks;

  WriteLn;
  WriteLn('Browsing has taken (milliseconds): ', (endTime - beginTime) * 1000);
  WriteLn('Branch count: ', BrowseNodes.BranchCount);
  WriteLn('Leaf count: ', BrowseNodes.LeafCount);
end;
// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

$beginTime = microtime(true);
$branchCount = 0;
$leafCount = 0;

$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "";

// Instantiate the client object.
$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");

try
{
    BrowseFromNode($Client, $ServerDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

$endTime = microtime(true);

printf("\n");
printf("Browsing has taken (milliseconds): : %f\n", ($endTime - $beginTime) * 1000);
printf("Branch count: %d\n", $branchCount);
printf("Leaf count: %d\n", $leafCount);


function BrowseFromNode($Client, $ServerDescriptor, $ParentNodeDescriptor) : void
{
    global $branchCount, $leafCount;

    // Obtain all node elements under ParentNodeDescriptor
    $BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters"); // no filtering whatsoever
    $NodeElementCollection = $Client->BrowseNodes($ServerDescriptor, $ParentNodeDescriptor,$BrowseParameters);
    // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
    //it, here omitted for brevity.

    foreach ($NodeElementCollection as $NodeElement)
    {
        printf("%s\n", $NodeElement);

        // If the node is a branch, browse recursively into it.
        if ($NodeElement->IsBranch)
        {
            $branchCount = $branchCount + 1;
            BrowseFromNode($Client, $ServerDescriptor, $NodeElement->ToDANodeDescriptor());
        }
        else
        {
            $leafCount = $leafCount + 1;
        }
    }
}
Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.

'Public branchCount As Integer
'Public leafCount As Integer

Private Sub BrowseNodes_RecursiveXml_Command_Click()
    OutputText = ""
    branchCount = 0
    leafCount = 0
    Dim beginTime: beginTime = Timer
        
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"
    
    Dim NodeDescriptor As New DANodeDescriptor
    NodeDescriptor.ItemId = ""
    
    ' Instantiate the client object
    Dim client As New EasyDAClient

    On Error Resume Next
        BrowseFromNode client, serverDescriptor, NodeDescriptor
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    Dim endTime: endTime = Timer
    
    OutputText = OutputText & vbCrLf
    OutputText = OutputText & "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000 & vbCrLf
    OutputText = OutputText & "Branch count: " & branchCount & vbCrLf
    OutputText = OutputText & "Leaf count: " & leafCount & vbCrLf
End Sub

Public Sub BrowseFromNode(client, serverDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters As New DABrowseParameters
    Dim NodeElementCollection As DANodeElementCollection
    Set NodeElementCollection = client.BrowseNodes(serverDescriptor, ParentNodeDescriptor, BrowseParameters)
    ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for
    ' it, here omitted for brevity.

    Dim NodeElement: For Each NodeElement In NodeElementCollection
        OutputText = OutputText & NodeElement & vbCrLf
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode client, serverDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next
End Sub
Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim beginTime: beginTime = Timer
Dim branchCount: branchCount = 0
Dim leafCount: leafCount = 0

Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = ""

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
BrowseFromNode Client, ServerDescriptor, NodeDescriptor
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim endTime: endTime = Timer

WScript.Echo ""
WScript.Echo "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000
WScript.Echo "Branch count: " & branchCount
WScript.Echo "Leaf count: " & leafCount


Sub BrowseFromNode(Client, ServerDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")
    Dim NodeElementCollection: Set NodeElementCollection = Client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
    ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
    ' it, here omitted for brevity.

    Dim NodeElement: For Each NodeElement In NodeElementCollection
        WScript.Echo NodeElement
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode Client, ServerDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next

End Sub
Requirements

Target Platforms: .NET Framework: Windows 10 (selected versions), Windows 11 (selected versions), Windows Server 2016, Windows Server 2022; .NET: Linux, macOS, Microsoft Windows

See Also