OPC Studio User's Guide and Reference
Elements Property (_SequenceData)
Example 



View with Navigation Tools
OpcLabs.BaseLib Assembly > OpcLabs.BaseLib.DataTypeModel.ComTypes Namespace > _SequenceData Interface : Elements Property
The elements of the sequence data.
Syntax
'Declaration
 
<NotNullAttribute()>
Property Elements As GenericDataCollection
 
'Usage
 
Dim instance As _SequenceData
Dim value As GenericDataCollection
 
instance.Elements = value
 
value = instance.Elements

Property Value

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

The individual elements of the property value can be 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.

Remarks

Relation of OpcLabs.BaseLib.DataTypeModel.SequenceData and its constituents is shown on the following picture:

.

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.

Example
// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// 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.

using System;
using OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.ComplexData;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.ComplexData._EasyUAClient
{
    class WriteValue
    {
        public static void Main1()
        {
            // Define which server and node we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"
            UANodeDescriptor nodeDescriptor =
                "nsu=http://test.org/UA/Data/ ;i=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Read a node which returns complex data. 
            // We know that this node returns complex data, so we can type cast to UAGenericObject.
            Console.WriteLine("Reading...");
            UAGenericObject genericObject;
            try
            {
                genericObject = (UAGenericObject)client.ReadValue(endpointDescriptor, nodeDescriptor);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }


            // Modify the data read.
            // This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
            // data types are sub-types of one common type which the data type of the node. We therefore use the data type 
            // ID in the returned UAGenericObject to detect which data type has been returned.

            // For processing the internals of the data, refer to examples for GenericData and DataType classes.
            // We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
            // also possible to discover the structure of the data type in the program, and write generic clients that can 
            // cope with any kind of complex data.
            //
            // Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
            Console.WriteLine("Modifying...");
            Console.WriteLine(genericObject.DataTypeId);
            if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9440"))  // ScalarValueDataType
            {
                // Negate the byte in the "ByteValue" field.
                var structuredData = (StructuredData)genericObject.GenericData;
                var byteValue = (PrimitiveData)structuredData.FieldData["ByteValue"];
                byteValue.Value = (Byte)~((Byte)byteValue.Value);
                Console.WriteLine(byteValue.Value);
            }
            else if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9669")) // ArrayValueDataType
            {
                // Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
                var structuredData = (StructuredData)genericObject.GenericData;
                var byteValue = (SequenceData)structuredData.FieldData["ByteValue"];
                var element0 = (PrimitiveData)byteValue.Elements[0];
                var element1 = (PrimitiveData)byteValue.Elements[1];
                element0.Value = (Byte)~((Byte)element0.Value);
                element1.Value = (Byte)~((Byte)element1.Value);
                Console.WriteLine(element0.Value);
                Console.WriteLine(element1.Value);
            }


            // Write the modified complex data back to the node.
            // The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
            // knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
            // as the node has (not a subtype).
            Console.WriteLine("Writing...");
            try
            {
                client.WriteValue(endpointDescriptor, nodeDescriptor, genericObject);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
            }
        }
    }
}
// Shows how to process generic data type, displaying some of its properties, recursively.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// 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.

using System;
using System.Collections.Generic;
using OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.ComplexData;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.ComplexData._GenericData
{
    class DataTypeKind1
    {
        public static void Main1()
        {
            // Define which server and node we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"
            UANodeDescriptor nodeDescriptor =
                "nsu=http://test.org/UA/Data/ ;i=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Read a node. We know that this node returns complex data, so we can type cast to UAGenericObject.
            UAGenericObject genericObject;
            try
            {
                genericObject = (UAGenericObject)client.ReadValue(endpointDescriptor, nodeDescriptor);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Process the generic data type. We will inspect some of its properties, and dump them.
            ProcessGenericData(genericObject.GenericData, maximumDepth: 3);
        }
        

        // Process the generic data type. Its structure can sometimes be quite deep, therefore we are limiting the depth
        // of the recursion using maximumDepth.
        public static void ProcessGenericData(GenericData genericData, int maximumDepth)
        {
            if (maximumDepth == 0)
                return;

            Console.WriteLine();
            Console.WriteLine("genericData.DataType: {0}", genericData.DataType);

            switch (genericData.DataTypeKind)
            {
                case DataTypeKind.Enumeration:
                    Console.WriteLine("The generic data is an enumeration.");
                    var enumerationData = (EnumerationData) genericData;
                    Console.WriteLine("Its value is {0}.", enumerationData.Value);
                    // There is also a ValueName that you can inspect (if known).
                    break;

                case DataTypeKind.Opaque:
                    Console.WriteLine("The generic data is opaque.");
                    var opaqueData = (OpaqueData) genericData;
                    Console.WriteLine("Its size is {0} bits.", opaqueData.SizeInBits);
                    Console.WriteLine("The data bytes are {0}.", BitConverter.ToString(opaqueData.ByteArray));
                    // Use the Value property (a BitArray) if you need to access the value bit by bit.
                    break;

                case DataTypeKind.Primitive:
                    Console.WriteLine("The generic data is primitive.");
                    var primitiveData = (PrimitiveData) genericData;
                    Console.WriteLine("Its value is \"{0}\".", primitiveData.Value);
                    break;

                case DataTypeKind.Sequence:
                    Console.WriteLine("The generic data is a sequence.");
                    var sequenceData = (SequenceData) genericData;
                    Console.WriteLine("It has {0} elements.", sequenceData.Elements.Count);
                    Console.WriteLine("A dump of the elements follows.");
                    foreach (GenericData element in sequenceData.Elements)
                        ProcessGenericData(element, maximumDepth - 1);
                    break;

                case DataTypeKind.Structured:
                    Console.WriteLine("The generic data is structured.");
                    var structuredData = (StructuredData) genericData;
                    Console.WriteLine("It has {0} field data members.", structuredData.FieldData.Count);
                    Console.WriteLine("The names of the fields are: {0}.",
                        String.Join(", ", structuredData.FieldData.Keys));

                    Console.WriteLine("A dump of each of the fields follows.");
                    foreach (KeyValuePair<string, GenericData> pair in structuredData.FieldData)
                    {
                        Console.WriteLine();
                        Console.WriteLine("Field name: {0}", pair.Key);
                        ProcessGenericData(pair.Value, maximumDepth - 1);
                    }
                    break;

                case DataTypeKind.Union:
                    Console.WriteLine("The generic data is a union.");
                    var unionData = (UnionData)genericData;
                    Console.WriteLine("The name of current field is: {0}", unionData.FieldName);
                    Console.WriteLine("Current field value is: {0}", unionData.FieldValue);
                    break;
            }
        }
    }
}
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