:《再问如何把一个变量的采样值保存到一个数组中呢》
本论题共有134人阅读,有4人回复。
  我设计了一个循环,每隔一定时间把变量值赋给一个中间变量,但是发现这个数组的每个元素都是一样的值,不知是怎么回事?该如何解决呢?
    tmp为间接变量
    WHILE(t<=15) DO
   
    t=t+1;
    tmp[t]=uc.PV;
   
    Delay(100);
    ENDWHILE
yz
以下是对《再问如何把一个变量的采样值保存到一个数组中呢》的回复:
111
2004-7-29 10:02:00
  数组一定要赋初值
sunwaywell
2004-7-29 11:40:00
  to yz:
  按照您的设计,tmp数组中的每个元素确实都是一样的。
  因为间接变量实际上是对数据库变量和中间变量的引用,也就是说
  tmp[t]=uc.PV;
  将是tmp[t]指向uc.PV的内存地址,不论uc.PV的值怎么变,他的地址确实不会改变的,故而这个循环赋值下来,tmp[]数组中的所有元素都指向同一片内存地址,值当然也一样。
 
  如果按照高级语言中同样的模式在力控中实现数组操作确实比较麻烦,不过也不是没有办法,关键在于地址的分配,为间接变量数组中的每一个元素都分配独立的地址就行了。而地址的分配在力控中是通过定义变量来实现的。
 
  下面我们来看一下您需要的功能怎么实现:
  第一步:在实时数据库里定义一组变量,15(建好t1后,按个复制键,然后按住ctrl+v不动,力控会自动为你创建下面的点,即使建100个点,整个过程10秒钟也搞定了)
 
  第二步:现在你可以把t当作一个数组来用了;如果想在循环中遍历这个数组,为数组赋值,可以采用下面的方法:
  FOR i = 1 TO 15 STEP 1
  VarRedir(DbVar,"t" + IntToStr(i, 10) + ".pv");
  DbVar = i;
  NEXT
 
  这个循环结束后,可以看到t1 - t15都赋值完成了。
 
  关于循环中用到的函数VarRedir,说明如下(详见力控联机帮助):
  VarRedir
  数据库变量重定向。
  语法
   VarRedir(var, NewTagPar)
  说明
  用于将数据库变量或间接变量重定向,对于数据库变量改变变量的数据库参数名称,
  使其指向其他数据库参数;而对于间接变量则改变其变量指向,使其指向名字为
  NewTagPar的变量,该变量在DRAW中一定要存在。
 
  通常可用于历史报表,趋势中变量动态替换。
  参数
  var: 重定向变量,该变量必须为数据库变量或间接变量。
  NewTagPar:字符串类型,新数据库参数或变量名称名称。
 
  示例
  VarRedir(dbvar1, "a1.pv");//dbvar1将指向数据库参数a1.pv
  VarRedir(dbvar1, "a2.pv");//dbvar1将指向数据库参数a2.pv
  dbvar1为已定义的数据库变量。
  VarRedir(var, "var1");
  var为间接变量,var1为要转向的变量名称。
sunwaywell
2004-7-29 12:13:00
  如果按照111所说的方法,也可以实现。但需要注意的是,这里所说的赋初值是指分配内存,而不是赋值,按yz的例子,实现如下:
  第一步:同上贴
  第二步:赋初值,代码如下:
  tmp[1] = t1.pv;
  tmp[2] = t2.pv;
  .
  .
  .
  tmp[15] = t15.pv;
 
  第三步:就是yz的代码部分了
  WHILE(t<=15) DO
    t=t+1;
    tmp[t]=uc.PV;
     
  ENDWHILE
cowboy:《力控能否在内存中实现数组指针功能》
本论题共有195人阅读,有8人回复。
  我想对一个变量X进行如下处理,在历史数据库中能实现对该变量60秒存储一次(可以的),但是对这个变量达到报警值后往前的每一秒的实时数据(累计60秒)的数据进行存储,但不是依靠历史数据库的每秒的定时保存,而类似C语言里的数组功能,在内存中建立一个堆栈(先进先出),完成报警前数据的取舍,不知道能否实现?
cowboy
以下是对《力控能否在内存中实现数组指针功能》的回复:
怎么给数组赋值
cowboy
2005-2-28 13:47:00
  我本想用以下程序建立一个堆栈,但发现陷入了死循环,
  Z为逻辑变量,可控
  while(z=1) do
  for i=1 to 60 step 1
  delay(1000)
  varredir(x.pv, "p"+intostr(i,10)+".pv");
  next;
  endwhile
  我原设想设备在z=1为正常情况,使得p1.pv到p60.pv能始终保持x.pv在一分钟内的变化情况,当设备故障则z=0循环停止,将p1.pv到p60.pv的数据存储,但实现不了,请高手指点
cowboy
2005-2-28 14:05:00
  应该是while(z==1) ,打错了
confige
2005-2-28 17:19:00
  你这个做的太复杂了,采用数据改变动作。
 
  变量:$Second
  脚本:varredir(x.pv, "p"+intostr($Second,10)+".pv");
114
2005-2-28 17:38:00
  我用数组做了一个计录10个值的演示,脚本如下。如果有看不明白的请留下邮箱。我把工程给你发过去。
  进入程序里:
  a[1] = &b1;a[2] = &b2;a[3] = &b3;a[4] = &b4;a[5] = &b5;
  a[6] = &b6;a[7] = &b7;a[8] = &b8;a[9] = &b9;a[10] = &b10;
  程序运行周期执行(周期为1秒)
  b=b+1; //模拟数据
  if s==1 then //记录开关
  c=c+1; //记数器
  SWITCH (c)
  CASE 1:b1=b;//记录第一个值
  CASE 2:b2=b;//......二....
  CASE 3:b3=b;//......三....
  CASE 4:b4=b;//......四....
  CASE 5:b5=b;//......五....
  CASE 6:b6=b;//......六....
  CASE 7:b7=b;//......七....
  CASE 8:b8=b;//......八....
  CASE 9:b9=b;//......九....
  CASE 10:b10=b;//......十....
  ENDSWITCH
cowboy
2005-2-28 22:29:00
  以上周期执行,会不会出现死循环呢?麻烦发个工程给我:fdn1978@xinhuanet,谢谢
114
2005-3-1 8:55:00
  邮件已经给你发过去了上面少了一个endif
窦哥
2005-3-7 11:09:00
  114,上面的代码如果改为:
  b=b+1;
  if s==1 then
  for i=1 to 10 step 1
  a[i]=b;
  next
  endif
 
  效果是否也一样呢?请指教!
窦哥
2005-3-8 13:31:00
  噢,我以为既然前面已经定义了
  a[1] = &b1;a[2] = &b2;a[3] = &b3;a[4] = &b4;a[5] = &b5;
    a[6] = &b6;a[7] = &b7;a[8] = &b8;a[9] = &b9;a[10] = &b10;
 
  后面用一个循环也可以呢,原来也不行呀!看来我以后若遇到类似的问题,不能想什么捷径了!
OK1
2005-3-8 17:07:00
  按照窦哥下面的做法是可以的,可以走捷径:
    b=b+1;
    if s==1 then
    for i=1 to 10 step 1
    a[i]=b;
    next
    endif

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。