Solved

C# Variant Type

Posted on 2012-03-19
15
1,281 Views
Last Modified: 2012-03-19
Hi All,

I have a interface with a Siemens PBL.
The methods that is exposed to me to read from the PBL takes 7 parameters.
And I am not sure how to declare the parameters and types for the parameters.

Please have a look at the attached screenshot and help me with this.
I am fairly new to C#.


Kind regards :)
OpX.jpg
0
Comment
Question by:Marius0188
  • 10
  • 4
15 Comments
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37736884
Two Things to note here:-
1. Methods That Accept Ref and Out Parameters, method arguments have to be of the same type as type of the parameter.
2. List cannot be passed to a method that accepts array, you have to convert your list to Array by calling its ToArray() method

Here is a code for you:-
                Array arrHandles = new List<int>().ToArray();
                Array arrValues = new List<string>().ToArray();
                Array arrErrors = new List<Exception>().ToArray();
                object quality = "Quality";
                object ts = DateTime.Now;

                IOPCGroup.SyncRead(1, 1, ref arrHandles, out arrValues, out arrErrors, out quality, out ts);

Open in new window

0
 

Author Comment

by:Marius0188
ID: 37737028
Thank you for the quick reply.
How would I return the values from the Array then?

Kind regards :)
0
 

Author Comment

by:Marius0188
ID: 37737037
If trying to read the first index of the arrValues[] array like this:
            MessageBox.Show("Value: " + arrValues[0]);


I get the following compiler error:
Error      2      Cannot apply indexing with [] to an expression of type 'System.Array'      C:\OperationX\OperationX\frmMain.cs      161      41      OperationX
0
 
LVL 9

Expert Comment

by:sachinpatil10d
ID: 37737075
Try this

MessageBox.Show("Value: " + arrValues.GetValue(0));
0
 

Author Comment

by:Marius0188
ID: 37737092
Okay thanks got that one.
Here is the example for VBscript that does work. I have tested the XLS doc and it was able to read the value from PBL.

Can you probably see where I am going wrong with my C# version of the working VB:

VB Code (working)
Option Explicit  ' every variable has to be declared
Option Base 1    ' every Array starts on Index 1

Private MyOPCServer As OPCServer
Private WithEvents MyOPCGroup As OPCGroup
Private MyOPCItems() As OPCItem

Private Sub cmdConnect_Click()
    Dim i As Integer

    Set MyOPCServer = New OPCServer
    
    'connect the OPC Server
    Call MyOPCServer.Connect(Cells(4, 2))
    
    'add one OPC Group
    Set MyOPCGroup = MyOPCServer.OPCGroups.Add("Gruppe1")
    
    'apply for DataChange
    MyOPCGroup.IsSubscribed = True
    MyOPCGroup.UpdateRate = 500
    
    'add Items
    ReDim MyOPCItems(4)
    
    For i = 1 To 4
        Set MyOPCItems(i) = MyOPCGroup.OPCItems.AddItem(Cells(8 + i, 2), 8 + i)
    Next i
    
    'set buttons
    cmdDisconnect.Enabled = True
    cmdRead.Enabled = True
    cmdWrite.Enabled = True
    cmdConnect.Enabled = False
        
    
End Sub
Private Sub cmdRead_Click()
    
    Dim SHandles(2) As Long 'parameter value
    Dim Values() As Variant 'return value
    Dim Errors() As Long    'return value
    Dim Qual As Variant     'return value
    Dim TS As Variant       'return value
    Dim i As Integer
    
    'save ServerHandles
    SHandles(1) = MyOPCItems(1).ServerHandle
    SHandles(2) = MyOPCItems(2).ServerHandle
        
    Call MyOPCGroup.SyncRead(OPCCache, 2, SHandles, Values, Errors, Qual, TS)
   
   'fill the cells with the read values
   
   For i = 1 To 2
    Cells(8 + i, 5) = Values(i)   'column "read"
    Cells(8 + i, 8) = Qual(i)     'column "quality"
    Cells(8 + i, 9) = TS(i)       'column "timestamp"
   Next i
    
    
    
End Sub

Open in new window


And this is my C# version based on VB version.
        private const string PROG_ID = "OPC.SimaticNet.1";
        private OPCSiemensDAAutomation.OPCServer opcServer;
        private OPCSiemensDAAutomation.OPCGroup opcGroup;
        private OPCSiemensDAAutomation.OPCItem[] opcItems = new OPCSiemensDAAutomation.OPCItem[1];

        private void connectOPCServer() 
        {
            try
            {
                opcServer = new OPCSiemensDAAutomation.OPCServer();
                opcServer.Connect(PROG_ID);

                opcGroup = opcServer.OPCGroups.Add("Gruppe1");
                opcGroup.IsSubscribed = true;
                opcGroup.UpdateRate = 500;

                opcItems[0] = opcGroup.OPCItems.AddItem("S7:[S7 connection_1]DB700, STRING8.50", 1);
            }
            catch(Exception ex)
            {
                MessageBox.Show("Exception: " + ex.Message);
            }
        }
            Array arrHandles = new List<int>().ToArray();
            Array arrValues = new List<string>().ToArray();
            Array arrErrors = new List<Exception>().ToArray();
            Object Quality = "Quality";
            Object Ts = DateTime.Now;


            arrHandles.SetValue(opcItems[1].ServerHandle, 0);

            opcGroup.SyncRead(1, 1, ref arrHandles, out arrValues, out arrErrors, out Quality, out Ts);

            MessageBox.Show("Value: " + arrValues.GetValue(0));

Open in new window


I know I am doing something wrong with the passing arrHandles parameter.
As in the VB example it get assigned by the opcITems.

Not sure how to rectify it though.

Please help :)
0
 

Author Comment

by:Marius0188
ID: 37737098
Sorry  I keep on referring to PBL but meant PLC...
:)

My mind is on something else....
0
 

Author Comment

by:Marius0188
ID: 37737101
Just a note about the VBScript example.
They are reading 4 dummy values and therefor you will see the loop 1 to 4.
I am only reading ONE value do know the name etc...
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:Marius0188
ID: 37737205
Okay I am getting exception index out of bounds on my arrays.

Why is this code failing?

                Array arrHandles = new List<int>().ToArray();
                Array arrValues = new List<string>(1).ToArray();
                Array arrErrors = new List<Exception>().ToArray();
                Object Quality = "Quality";
                Object Ts = DateTime.Now;

                arrValues.SetValue("Joe", 0);
                MessageBox.Show(arrValues.GetValue(0).ToString());

Open in new window

0
 

Author Comment

by:Marius0188
ID: 37737214
I tried both options:

Array arrValues = new List<string>().ToArray();

AND

Array arrValues = new List<string>(1).ToArray();
0
 
LVL 20

Accepted Solution

by:
BuggyCoder earned 500 total points
ID: 37737250
do this if you want to achieve this:-
var lstValues = new List<string> {"Joe"};
Array arrValues = lstValues.ToArray();
var val = (string) arrValues.GetValue(0);

Open in new window

0
 

Author Comment

by:Marius0188
ID: 37737321
Okay thanks - one step further now :)

But there seem to be a type mismatch now.
The VBScript method that works is like this:

Private Sub cmdWrite_Click()

    Dim SHandles(2) As Long  'parameter value
    Dim Values(2) As Variant 'parameter value
    Dim Errors() As Long     'return value
    Dim i As Integer

        
    'save ServerHandles
    SHandles(1) = MyOPCItems(3).ServerHandle
    SHandles(2) = MyOPCItems(4).ServerHandle
    
    'find out the values which are written into the following cells (line 11+12, column F)
    'this values should be writen into PLC
    
    For i = 1 To 2
          Values(i) = Cells(10 + i, 6)
          If Values(i) = "" Then Values(i) = 0
    Next i
    
    Call MyOPCGroup.SyncWrite(2, SHandles, Values, Errors)
    
End Sub

Open in new window


And my C# version is this:

        private void btnWrite_Click(object sender, EventArgs e)
        {
                var lstHandles = new List<int>();
                lstHandles.Add(opcItems[0].ServerHandle);
                Array arrHandles = lstHandles.ToArray();

                var lstValues = new List<string>();
                lstValues.Add("Test Value");
                Array arrValues = lstValues.ToArray();

                Array arrErrors = new List<int>().ToArray();

                Object Quality = "Quality";
                Object Ts = DateTime.Now;

                opcGroup.SyncWrite(1, ref arrHandles, ref arrValues, out arrErrors);
        }

Open in new window



And I am receiving the following error when executing the C# Code:
please see attached screen shot....
opc.jpg
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37737325
Let me know what syncwrite method looks like.
0
 

Author Comment

by:Marius0188
ID: 37737377
Sorry about that:

void SyncWrite(int NumItems, ref Array ServerHandles, ref Array Values, out Array Errors);
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37737396
Each array that you are supplying in method have to be of some predefined type. My example included arrays of some arbitrary types that it took as an example...
 
Read the documentation and define the arrays by specifying the correct types.

As of now, it seems that it is unhappy with the type of array being passed to one of the ref/out marked parameters.

Also suggest you close this question and open a new question as your question was regarding how to pass parameters to SyncRead method, the solution to which has already been supplied to you.

you can always open new question for a new problem...
0
 

Author Comment

by:Marius0188
ID: 37737415
Thank Buggy :) I agree.
Will close this one and start new one...


Keep well :)
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now