Search Results for

    Show / Hide Table of Contents

    UserDefined data

    Overview

    RECORD structures are common in RAPID code. To handle these unique data types, a UserDefined class is available. This class has properties and methods to handle individual components of a RECORD.

    In some cases implementing your own structure can improve application design and code maintenance.

    Creating UserDefined object

    The UserDefined constructor takes a RapidDataType object as argument. To retrieve a RapidDataType object you need to provide a RapidSymbol or the path to the declaration of the RAPID data type.

    The following example creates a UserDefined object representing the RAPID RECORD processdata:

    RapidDataType rdt;
    rdt = this.aController.Rapid.GetRapidDataType("T_ROB1", "user",  "processdata");
    UserDefined processdata = new UserDefined(rdt);
    

    Reading UserDefined data

    UserDefined can be used to read any kind of RECORD variable from the controller. The individual components of the RECORD are accessible using the Components property and an index. Each Component can be read as a string.

    UserDefined processdata = new UserDefined(rdt);
    processdata = (UserDefined)rd.Value;
    string no1 = processdata.Components[0].ToString();
    string no2 = processdata.Components[1].ToString();
    

    Each individual string can then be used in a FillFromString method to convert the component into a specific data type, for example RobTarget or ToolData. For more information, see IRapidData.FillFromString method.

    Writing to UserDefined data

    If you want to modify UserDefined data and write it to the controller, you must first read the UserDefined object and the apply new values using the FillFromString method. Then you need to perform a write operation using the RapidData.Value property.

    processdata.Components[0].FillFromString("[0,0,0]");
    processdata.Components[1].FillFromString("10");
    rd.Value = processdata;
    

    For more information and code samples, see IRapidData.FillFromString method and Writing to RAPID data.

    Recursively reading the structure of any RECORD data type

    If you need to know the structure of a RECORD data type (built-in or user-defined) you must first retrieve the record components of the record. Then you need to iterate the record components and check if any of them are also records. This procedure must be repeated until all record components are atomic types.The following code example shows how to get information about the robtarget data type. The robtarget URL is “RAPID/robtarget” or just “robtarget”.

    private void SearchRobtarget()
    {
        RapidSymbolSearchProperties sProp = RapidSymbolSearchProperties.CreateDefault();
        sProp.Recursive = true;
        sProp.Types = SymbolTypes.Constant | SymbolTypes.Persistent;
        sProp.SearchMethod = SymbolSearchMethod.Block;
        RapidSymbol[] rsCol = tRob1.SearchRapidSymbol(sProp, "RAPID/robtarget", "p10");
        RapidDataType theDataType;
        if (rsCol.Length > 0)
        {
            Console.WriteLine("RapidSymbol name = " + rsCol[0].Name);
            theDataType = RapidDataType.GetDataType(rsCol[0]);
            Console.WriteLine("DataType = " + theDataType.Name);
            if (theDataType.IsRecord)
            {
                RapidSymbol[] syms =
                theDataType.GetComponents(); SearchSymbolStructure(syms);
            }
        }
    }
    
    private void SearchSymbolStructure(RapidSymbol[] rsCol)
    {
        RapidDataType theDataType;foreach (RapidSymbol rs in rsCol)
        {
            Console.WriteLine("RapidSymbol name = " + rs.Name);
            theDataType = RapidDataType.GetDataType(rs);
            Console.WriteLine("DataType = " + theDataType.Name);
            if (theDataType.IsRecord) 
            {
                RapidSymbol[] syms = theDataType.GetComponents();
                SearchSymbolStructure(syms);
            }
        }
    }
    

    The code example above produces the following printout:

    RapidSymbol name = p10
    
    DataType = robtarget
    
    RapidSymbol name = trans
    
    DataType = pos
    
    RapidSymbol name = x
    
    DataType = num
    
    RapidSymbol name = y
    
    DataType = num
    
    RapidSymbol name = z
    
    DataType = num
    
    RapidSymbol name = rot
    
    DataType = orient
    
    RapidSymbol name = q1
    
    DataType = num
    
    RapidSymbol name = q2
    
    DataType = num
    
    RapidSymbol name = q3
    
    DataType = num
    
    RapidSymbol name = q4
    
    DataType = num
    
    RapidSymbol name = robconf
    
    DataType = confdata
    
    RapidSymbol name = cf1
    
    DataType = num
    
    RapidSymbol name = cf4
    
    DataType = num
    
    RapidSymbol name = cf6
    
    DataType = num
    
    RapidSymbol name = cfx
    
    DataType = num
    
    RapidSymbol name = extax
    
    DataType = extjoint
    
    RapidSymbol name = eax_a
    
    DataType = num
    
    RapidSymbol name = eax_b
    
    DataType = num
    
    RapidSymbol name = eax_c
    
    DataType = num
    
    RapidSymbol name = eax_d
    
    DataType = num
    
    RapidSymbol name = eax_e
    
    DataType = num
    
    RapidSymbol name = eax_f
    
    DataType = num
    

    Implement your own struct representing a RECORD

    The following example shows how you can create your own .NET data type representing a RECORD in the controller instead of using the UserDefined type.

    RapidDataType rdt = ctr.Rapid.GetRapidDataType("T_ROB1", "MyModule", "processdata");
    ProcessData pc = new ProcessData(rdt);
    pc.FillFromString(rd.Value.ToString());
    

    Implementing ProcessData struct

    The following example shows how the new data type ProcessData may be implemented. This is done by using a .NET struct and letting ProcessData wrap the UserDefined object.

    The struct implementation should include a FillFromString and ToString method, that is, inherit the IRapidData interface. Any properties and methods may also be implemented.

    public struct ProcessData : IRapidData
    {
        private UserDefined data;
        
        public ProcessData(RapidDataType rdt)
        {
            data = new UserDefined(rdt);
        }
        
        private UserDefined IntData
        {
            get { return data; }
            set { data = value; }
        }
        
        public int StepOne
        {
            get
            {
                int res = Convert.ToInt32(IntData.Components[0].ToString());
                return res;
            }
            set
            {
                IntData.Components[0] = new Num(value);
            }
        }
    }
    

    Implementing IRapidData methods

    This piece of code shows how the two IRapidData methods ToString and FillFromString can be implemented.

    public void FillFromString(string newValue)
    {
        IntData.FillFromString(newValue);
    }
    
    public override string ToString()
    {
        return IntData.ToString();
    }
    

    The ToString method has to use the Overrides keyword in Visual Basic and the override keyword in C#.

    Property implementation

    Each item in the RECORD structure should have a corresponding property in the extended .NET data type. The get and set methods have to implement the conversion from/to controller data type to .NET data type.

    Note

    If FillFromNum() does not work, use FillFromString for records ud.FillFromString("[\"10\",50,60,\"apa\"]"); does not work.

    public int Step
    {
        get
        {
            int res = Convert.ToInt32(IntData.Components[0].ToString());
            return res;
        }
        set
        {
            Num tmp = new Num();
            tmp.FillFromNum(value);
            IntData.Components[0] = tmp;
        }
    }
    
    In This Article
    Back to top Copyright © 2025 ABB