Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- ReadMultipleItems Method
ReadMultipleItems Method
The Vtq.Value is generally an 'object', i.e. it can be of any type. The actual type depends on the OPC Server and the particular OPC item (and, on the RequestedDataType that you can specify when reading or subscribing). More information to this is e.g. in the Concepts document, "9.13 Data Types":
OPC Data Access specification is based on COM, and uses Windows VARIANT type (from COM Automation) for representing data values.
Note: Some OPC servers even use certain VARIANT types that are not officially supported by Microsoft.
Microsoft .NET Framework has a different concept, and all data is represented using an Object type. Conversions between the two are available, but not always fully possible.
In addition, not everything that can be stored in an Object can later be processed by all .NET tools and languages. Microsoft has created so-called Common Language Specification (CLS), which has certain rules and restrictions that, if followed, guarantee cross-language compatibility. Public QuickOPC.NET components (assemblies) are fully CLS compliant, and that includes the way the data types are converted to and from OPC types.
QuickOPC.NET converts data from COM to .NET according to following table:
COM type (VARIANT)
.NET type (Object)
VT_EMPTY
System.Object (null reference)
VT_NULL
System.DBNull (singleton class)
VT_I2
System.Int16
VT_I4
System.Int32
VT_R4
System.Single
VT_R8
System.Double
VT_CY
System.Decimal
VT_DATE
System.DateTime
VT_BSTR
System.String
VT_DISPATCH
System.Object (not tested)
VT_ERROR
System.Int32
VT_BOOL
System.Boolean
VT_VARIANT
converted type of the target VARIANT
VT_DECIMAL
System.Decimal
VT_I1
System.Int16
VT_UI1
System.Byte
VT_UI2
System.Int32
VT_UI4
System.Int64
VT_I8
System.Int64
VT_UI8
System.Decimal
VT_INT
System.Int32
VT_UINT
System.Int64
VT_ARRAY | vtElement
System.Array of the converted vtElement type
Types that are highlighted do not convert from COM to their “natural” .NET counterparts, because the corresponding .NET type is not CLS compliant. Instead, a “wider” type that is CLS compliant is chosen.
Types not listed in the above table at all are not supported.
Strings are internally represented in Unicode wherever possible.
BTW, it looks like that the Live Binding feature (available in version 5.20) could be a good fit for you. With Live Binding, you can set up Windows Forms controls to be "bound" to OPC data, simply by configuring it in VS Designer.
Please Log in or Create an account to join the conversation.
- alissonhaubert
- Topic Author
- Offline
- New Member
- Thank you received: 0
Label1.Text = leitura[6].Exception == null ? leitura[6].Vtq.ValueToString() : "***";
another question, what format is the return value of Vtq.Value? Double, Decimal, Float?
I thank you for understanding.
Att Alisson R. S. Haubert.
Please Log in or Create an account to join the conversation.
I am a bit puzzled by the question, because the answer seems obvious to me: If you want "something" be displayed in the text box in case the actual value is null, use an 'if'-then-else' statement, test the value for null, and if it is null, store the required "something" into the text box instead of converting the value to string.
If I misunderstood the question, let me know.
Kind regards,
Zbynek Zahradnik
Please Log in or Create an account to join the conversation.
- alissonhaubert
- Topic Author
- Offline
- New Member
- Thank you received: 0
Below is how I'm trying to do:
DAVtqResult[] leitura = EasyDAClient.DefaultInstance.ReadMultipleItems("CoDeSys.OPC.02", new DAItemDescriptor[]
{ "PLC1:.xI_TBN_ValvBorbFechada",
"PLC1:.xI_TBN_ValvBorbAberta",
"PLC1:.xI_TBN_ValvBorbAberta",
});
for (int i = 0; i < leitura.Length; i++)
{
if (leitura.Exception != null)
{
leitura.Vtq.Value = 000;
}
}
//and I pass the textbox value vtq.value
TextBox1.Text = leitura[1].Vtq.Value.ToString();
Please Log in or Create an account to join the conversation.
Each of the result objects in the result array has an Exception property. This property contains a null reference if there was no error, or it contains a non-null Exception-derived object with the error details, if there has been an error related to that position in the input (output) array. You can test the Exception property for being null (or not null), which is quite efficient (compared to throwing/catching).
If Exception is null (no error), then Vtq is non-null, so there is no need to test the Vtq then. But beware - Vtq.Value can STILL be null, if if Vtq.Quality is Bad or Uncertain.
Best regards
Please Log in or Create an account to join the conversation.
- alissonhaubert
- Topic Author
- Offline
- New Member
- Thank you received: 0
opc if you can not find a variable I want to pass a value to it, because when he does not find a variable it crashes my application and that's not good for me, I wish that when a variable was not set to be read one default value for that position in the array
I'm trying to do it this way, but is not working, I thought he would return a null value for that position in the array, but apparently it does not.
Below is how I'm trying to do this:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using OpcLabs;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
namespace Supervisorio_V1_06_12.Paginas.M1
{
public partial class Comando : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DAVtqResult[] leitura = EasyDAClient.DefaultInstance.ReadMultipleItems("CoDeSys.OPC.02", new DAItemDescriptor[]
{
"PLC1:.xI_TBN_ValvBorbFechada",
"PLC1:.xI_TBN_ValvBorbAberta",
"PLC1:.xI_TBN_ValvBorbAberta",
"PLC1:.reM_RDV_ReferenciaPotencia",
});
for (int i = 0; i < leitura.Length; i++)
{
if (leitura.Vtq == null)
{
leitura.Vtq.Value == 000;
}
}
TextBox1.Text = leitura[1].Vtq.Value.ToString();
}
}
}
You know me know a more efficient way of handling errors in readmultipleitems? tried using try catch block for this, have not found a more efficient way.
I thank you for your understanding, hugs.
Alisson R. S. Haubert
Please Log in or Create an account to join the conversation.
you can increase the time the connection is held by setting a property in HoldPeriod, e.g. for 10 minutes:
easyDAClient.HoldPeriods.TopicRead = 10*60*1000;
Best regards,
Zbynek Zahradnik
Please Log in or Create an account to join the conversation.
- alissonhaubert
- Topic Author
- Offline
- New Member
- Thank you received: 0
I'm using the ReadMultipleItems method, and runs every 5 minutes, but I noticed that the OPC is running for 2 minutes, how can I make amends and let the OPC running until the next execution method ReadMultipleItems. Thank you for your attention.
Alisson Houbert
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- ReadMultipleItems Method