<< 点击显示目录 >> 主页 PVI通信 > PVI帮助信息 > PVI Services > Communication classes > Variable class > Value class |
每个变量对象都包含Value属性,它将最后读取的过程变量值表示为一个值对象。当一个变量对象被连接时,值和数据类型信息都被存储在值对象中。
Property |
Type |
说明 |
DataType |
Data type enumerator |
该变量的.NET数据类型 |
TypeLength |
Int32 |
数据类型的范围 |
ArrayLength |
Int32 |
变量对象的数组长度 |
Item [ .. ] |
String / Int32 |
对结构或数组元素的访问 |
由于该类是从IConvertible和IFormattable派生出来的,PVI服务的数据类型可以与.NET数据类型归为同一类别。这使得任何值对象都可以使用单独的转换例程(如ToString()或ToInt32())转换为任何.NET数据类型。此外,IFormatProvider对象使其有可能进行特定文化的格式化。如果没有使用格式化对象,那么在调用过程中就需要转移空值。
System.Double d = tmpVar.Value.ToDouble(null);
因此,变量对象的值可以使用此属性进行设置或读取。如果变量被注册,且活动属性为真,那么值会被轮询并持续更新。另一方面,如果变量对象没有被激活,那么在连接时只有初始化值被读取并存储在Value属性中。因此,通过Value属性的读取访问 并不意味着 控制器上的过程变量的值被读取,而只是意味着Value属性的最后保存值被返回。
"正常 "值访问
一个值可以通过三种不同的方式分配给变量对象的Value属性。
Variable variable = new Variable(this.cpu,"var_01");
// 方案1:分配简单的值
variable.Value = 22;
// 注意:目前 只有在C#中可以进行操作符分配。
// 这个功能在Visual Basic .NET中也支持这个功能,从Visual Studio .NET 8.0开始。
// 选项 2: 指定一个值对象
Value myVal = new Value(22); // Assigning in Visual Basic .NET 7.0
variable.Value = myVal;
// 选项3:使用Value.Assign进行分配
variable.Value.Assign(22);
variable.WriteValue();
变量对象的值分配给一个.NET数据类型。
Int32 myInt32 = variable.Value; // 自动转换为Int32
Int16 myInt16 = variable.Value; // 自动转换为Int16
结构变量的值访问
从结构中读取和写入元素的值是通过一个 String类型的索引来处理的 。该索引返回一个代表结构元素值的值对象。然而,只有当变量至少被 正确连接过一次 或者 变量对象的 DataValid 属性的值为 "True " 时,才能保证用括号进行访问 。 这是因为 结构 类型的变量对象的完整结构 只有在收到 "连接 "事件后才会建立。
// 访问elem_1元素的变量对象
variable.Value["elem_1"] = 22;
// 访问elem_2.sub_elem的变量对象
variable.Value["elem_2.sub_elem"] = 22;
// 访问elem_3[4].sub_elem的变量对象
variable.Value["elem_3[4].sub_elem"] = 22;
如果结构变量本身是一个数组,那么在访问结构元素时,变量的名称和所需的数组索引将被设置在元素名称之前的括号内。
Variable variable = new Variable(this.cpu,"varSt");
// 访问varSt[4].elem的变量对象
variable.Value["varSt[4].elem"] = 22;
数组变量的值访问
对简单数组变量的访问也是使用索引进行的。然而,这次使用的是一个Int32类型的索引。
Variable variable = new Variable(this.cpu,"varArray");
// 访问第154个元素的变量对象变量
variable.Value[154] = 22;
Example of structures and arrays
下面的例子解释了如何访问结构类型的单个变量对象的值。此外,使用树状视图来帮助显示结构变量的内容,应该说明如何管理该变量以及变量的结构(Members 属性)。
// 全球通信对象的定义
Service service;
Cpu cpu;
Variable variable;
/// <summary>
/// Establish connection to PLC
/// </summary>
private void btConnectPLC_Click(object sender, System.EventArgs e)
{
if ( service == null )
{
service = new Service("Service");
service.Connected+=new PviEventHandler(service_Connected);
}
service.Connect();
}
/// <summary>
/// Connect CPU object if service object connection successful
/// </summary>
private void service_Connected(object sender, PviEventArgs e)
{
if ( cpu == null )
{
// 创建CPU对象并添加事件处理程序
cpu = new Cpu(this.service,"Cpu");
cpu.Connected += new PviEventHandler(cpu_Connected);
cpu.Variables.Uploaded += new PviEventHandler(Variables_Uploaded);
// 为一个串行连接设置连接属性
cpu.Connection.DeviceType = DeviceType.Serial;
cpu.Connection.Serial.BaudRate = 57600;
cpu.Connection.Serial.Channel = 1;
}
// Connect CPU
cpu.Connect();
}
/// <summary>
/// CPU对象连接成功
/// </summary>
private void cpu_Connected(object sender, PviEventArgs e)
{
this.btUploadVariables.Enabled = true;
}
/// <summary>
/// 读取全局变量
/// </summary>
private void btUploadVariables_Click(object sender, System.EventArgs e)
{
cpu.Variables.Upload();
}
/// <summary>
/// 成功读取全局变量信息
/// </summary>
private void Variables_Uploaded(object sender, PviEventArgs e)
{
this.btConnect.Enabled = true;
this.cbVariables.Items.Clear();
// 将变量对象应用到组合框中
foreach ( Variable var in cpu.Variables.Values )
{
this.cbVariables.Items.Add(var.Name);
}
this.cbVariables.SelectedIndex = 0;
}
/// <summary>
/// 连接变量对象
/// </summary>
private void btConnect_Click(object sender, System.EventArgs e)
{
// 断开以前连接的变量对象的连接
if ( variable != null )
{
variable.Disconnect();
this.cbMember.Items.Clear();
this.tvVariable.Nodes.Clear();
}
// 使用字符串索引指定变量对象
variable = this.cpu.Variables[this.cbVariables.Text];
// 连接变量对象
variable.Active = true;
variable.Connect();
// 添加事件处理程序
variable.ValueChanged += new VariableEventHandler(Variable_ValueChanged);
variable.Connected += new PviEventHandler(Variable_Connected);
}
/// <summary>
/// 变量对象连接成功 树状视图的结构 有了结构变量,它的各个元素就可以通过 "成员 "属性添加到树状视图中。
/// </summary>
private void Variable_Connected(object sender, PviEventArgs e)
{
// 暂时存储变量对象
Variable tmpVar = (Variable)sender;
tmpVar.Connected-=new PviEventHandler(Variable_Connected);
// 用于树状视图的.NET TreeNode对象
TreeNode tn2;
TreeNode tn;
this.btSetValue.Enabled = true;
tn = new TreeNode(tmpVar.Name);
this.tvVariable.Nodes.Add(tn);
if ( (tmpVar.Value.DataType == DataType.Structure) || (tmpVar.Value.ArrayLength > 1))
{
// 结构阵列变量处理
if ( tmpVar.Value.ArrayLength > 1 )
{
for (int i=0;i<tmpVar.Value.ArrayLength;i++)
{
tn2 = new TreeNode(tmpVar.Name+"["+i.ToString()+"]");
tn.Nodes.Add(tn2);
foreach ( Variable member in tmpVar.Members.Values )
{
InsertNode(member,tn2);
}
}
}
// 结构变量处理
else
{
// 通过结构变量的元素运行
foreach ( Variable member in tmpVar.Members.Values )
{
// 应添加结构变量下的当前元素.
InsertNode(member,tn);
}
}
}
}
/// <summary>
/// 创建树状视图的帮助功能
/// </summary>
private void InsertNode(Variable var, TreeNode node)
{
TreeNode tmpNode2=null;
TreeNode tmpNode=null;
if ( var.Value.ArrayLength > 1 )
{
tmpNode2 = new TreeNode(var.Name);
node.Nodes.Add(tmpNode2);
}
for (int i=0;i<var.Value.ArrayLength;i++)
{
if ( var.Value.ArrayLength == 1 )
{
tmpNode = new TreeNode(var.Name);
node.Nodes.Add(tmpNode);
}
else
{
if ( tmpNode2 != null)
{
tmpNode = new TreeNode(var.Name+"["+i.ToString()+"]");
tmpNode2.Nodes.Add(tmpNode);
}
}
foreach ( Variable member in var.Members.Values )
{
InsertNode(member,tmpNode);
}
}
}
/// 当数值发生变化时评估数据
/// </summary>
private void Variable_ValueChanged(object sender, VariableEventArgs e)
{
// 暂时保存变量对象
Variable tmpVar = (Variable)sender;
String output;
tbState.Text = "";
// 结构变量处理
if ( tmpVar.Value.DataType == DataType.Structure )
{
// 运行 "ChangedMembers "字符串列表
// 这包含了所有作为字符串对象的修改过的结构成员
foreach ( String element in e.ChangedMembers )
{
if ( element != null )
{
// 输出带有当前值的结构元素
// 使用一个字符串索引器进行访问
output = String.Format(n style="color:teal">"{0}: {1}", element, tmpVar.Value[element].ToString());
tbState.Text += output + "\r\n";
}
}
}
// Array variable handling
else if ( tmpVar.Value.ArrayLength > 1 )
{
foreach ( String element in e.ChangedMembers )
{
if ( element != null )
{
// 输出数组索引及其当前值
output = String.Format("{0}: {1}", element, tmpVar.Value[System.Convert.ToInt32(element)].ToString());
tbState.Text += output + "\r\n";
}
}
}
// "正常 "的变量处理
else
{
output = String.Format("{0}: {1}",tmpVar.Name,tmpVar.Value.ToString());
tbState.Text += output + "\r\n";
}
// 在组合框中添加结构或数组元素
if ( this.cbMember.Items.Count == 0 )
{
if ( (tmpVar.Value.DataType == DataType.Structure) ||
(tmpVar.Value.ArrayLength > 1) )
{
foreach ( String element in e.ChangedMembers )
{
if ( element != null )
cbMember.Items.Add(element);
}
}
else
{
cbMember.Items.Add(tmpVar.Name);
}
if ( this.cbMember.Items.Count > 0 )
cbMember.SelectedIndex = 0;
}
}
/// <summary>
/// 在元素组合框中选择它之后,设置一个元素值(结构体或数组元素)。
/// </summary>
private void btSetValue_Click(object sender, System.EventArgs e)
{
Variable tmpVar = cpu.Variables[this.cbVariables.Text];
// 使用字符串索引为结构变量设置值
if ( tmpVar.Value.DataType == DataType.Structure )
tmpVar.Value[this.cbMember.Text] = System.Convert.ToSingle(this.tbValue.Text);
// 使用字符串索引为数组变量设置值
else if ( tmpVar.Value.ArrayLength > 1 )
tmpVar.Value[System.Convert.ToInt32(this.cbMember.Text)] = System.Convert.ToSingle(this.tbValue.Text);
// 为正常变量设定值
else
tmpVar.Value = System.Convert.ToSingle(this.tbValue.Text);
}