ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

搬家第四天-89.Wincc V7.3 用户归档深入8-用户归档结合数据库控件使用vbs脚本模拟从ERP任务表到控制系统配方

2021-02-01 13:32:03  阅读:172  来源: 互联网

标签:控件 Task ERP 用户 ors Set User 归档 TextMatrix


一 任务背景描述

        假设有这样一个车间,每天生产任务来自ERP系统任务表,现场控制计算机从系统中查询到任务表,然后根据设备实际情况选择任务表,并把这个配方任务每隔10秒逐条下载给控制系统,控制系统根据上级的指令完成生产任务。wincc查询、选择数据表的方法,前面的博客有较为介绍,本文不作重点介绍。

1. 假设ERP任务表存放在ERP数据库中,表名叫做Task。表的各字段如下图所示,各字段类型、长度、表结构是否最优不在本文讨论范围。CurDate表示生产任务的日期,Product表示配方名称,Pressure表示压力设定值,Tempreture表示温度设定值,finished记录任务是否完成(我们假定下载到控制系统的任务都能完成,只要下载了就把这个显示为“是”)。

2. 假定Task表格已经有下面一些记录了。

我们需要在画面上能够按照日期查询这些配方任务,可以筛选符合现场设备工艺状况的配方任务,然后每隔10秒把选中的配方任务下载到控制系统中,选中的记录在finished字段标注“是”,未选中的任务在finished字段标注“否”。我们选定好任务后,在人物下载到控制系统的过程中,还必须确保无论是在哪一个工艺画面,下载过程都能够顺利完成,不会因为画面切换而造成中断(实际生产中也会有这类需求)。

 3. 在数据库ERP中新建一个用户任务表User_Task,用于记录用户选定的配方任务。

二 基本设置

1. 下位机硬件设置

   这是一个模拟项目,没有实际的硬件,在simatic manager 插入一个s7 300 站点,配置好电源、CPU和简单的IO。



2. 插入一个DB1,里面定义Product、Pressure、Tempreture三个变量,设置这三个变量和DB块允许操作员监控,DB块S7_m_c属性为true.

3. simatic manager插入PC Station,配置硬件。

4. simatic manager的PC Station下OS右键编译,把标签上载到Wincc。

5. 在Wincc定义内部变量Index,32位浮点数,记录user_task的行号;Download 二进制变量;@MyUA_ID、@MyUA_JOB、@MyUA_Field、@MyUA_Value分别对应用户归档MyUA的四个属性。

6. 新建用户归档MyUA,下面三个归档变量Product,Pressure、Tempreture,分别对应上载上来的三个PLC变量。(详细设置参考其他博客)

二 画面设置和编程

1. 新建两个画面Task和UA,分别用于查询设置和查看用户归档
2. Task画面插入日期时间空间,名字修改为DTPicker;两个MSHFGrid控件,名字分别为ERP_Task和User_Task;一个查询按钮、一个上移按钮、一个下移按钮、一个下达任务按钮、一个跳转到用户贵党页面按钮。

3.查询按钮vbs脚本

Sub OnClick(ByVal Item)                
Dim conn
Dim ssql
Dim ors
Dim ocom
Dim scon
Dim ERP_Task,User_Task,rowcount,i
Dim ADODC
Dim PCName,colscount
Dim sYear,sMonth,sDay,sDate,DTP
'以下代码规范查询日期的字符串格式
Set DTP=ScreenItems("DTPicker")
sYear=Year(DTP.value)
sMonth=Month(DTP.value)
sDay=Day(DTP.Value)
If sMonth<10 Then
   sMonth="0" & CStr(sMonth)
End If
If sDay<10 Then
   sDay="0" & CStr(sDay)
End If
sDate=CStr(sYear) & "-" & CStr(sMonth) & "-" & CStr(sDay)

'开始按照日期条件查询
PCName=HMIRuntime.Tags("@LocalMachineName").Read
scon="Provider = SQLOLEDB.1;Integrated Security=SSPI;Persist SecurityInfo=False;Initial Catalog =ERP;Data Source = " &PCName & "\WINCC"
ssql="select Curdate as '日期',product as N'配方代号',pressure as '压力设定',tempreture as '温度设定',finished as N'是否完成' from Task where Curdate='" & sDate & "'"
Set conn=CreateObject("ADODB.Connection")
conn.ConnectionString=scon
conn.Cursorlocation=3
conn.open
Set ors=CreateObject("ADODB.RecordSet")
Set ocom=CreateObject("ADODB.Command")
ocom.commandtype=1
Set ocom.ActiveConnection=conn
ocom.CommandText=ssql
Set ors=ocom.Execute
Set ERP_task=ScreenItems("ERP_Task")
Set ERP_task.DataSource=ors
ERP_task.Refresh
Set ors=Nothing
conn.close
Set conn=Nothing
' 增加一列用于勾选,一列记录临时表行号
colscount=ERP_task.Cols
ERP_task.Cols = colscount + 2
ERP_task.TextMatrix(0,colscount)="点击选择"
ERP_task.TextMatrix(0,colscount+1)="临时表行号"
ERP_task.colwidth(1)=1200


'如果已经设定过一次再次点击读取数据,则清空临时表

Set User_Task=ScreenItems("User_Task")
rowcount=User_Task.Rows
User_Task.Row=1
For i=1 To User_Task.Rows-2
   User_Task.RemoveItem User_Task.Row
   User_Task.Row=1
Next
End Sub

有中文显示的字段,前面加N避免显示成?

4. ERP_Task控件鼠标点击事件vbs脚本

Sub Click(ByVal Item)              
Dim ERP_Task,User_Task
Dim hid,vid
Dim colcount
Dim i,UserTask_currow
Dim delrow
Set ERP_Task=ScreenItems("ERP_Task")
Set User_Task=ScreenItems("User_Task")
User_Task.colwidth(1)=1200
colcount=ERP_Task.cols-2
User_Task.Cols=colcount+1 '增加一列记录在原表中的行号
hid=ERP_Task.Row
vid=ERP_Task.col
'初始化临时表
For i=1 To colcount-1 '列标题
 User_Task.TextMatrix(0,i)=ERP_Task.TextMatrix(0,i)
Next
User_Task.TextMatrix(0,User_Task.cols-1)="原始表行号"
If (hid>=1 And hid<=ERP_Task.rows-1) And vid=colcount Then
   If ERP_Task.TextMatrix(hid,vid)="" Then
      ERP_Task.TextMatrix(hid,vid)="x"
      ERP_Task.ColAlignment(vid)=3  '居中
      User_Task.AddItem ""    
      UserTask_currow=User_Task.Rows-2
      For i=1 To colcount-1
         User_Task.TextMatrix(UserTask_currow,i)=ERP_Task.TextMatrix(hid,i)
      Next
      User_Task.TextMatrix(UserTask_currow,0)="第" & CStr(UserTask_currow) & "步骤"
      ERP_Task.TextMatrix(hid,colcount+1)=CStr(User_Task.Rows-2)
      User_Task.TextMatrix(UserTask_currow,User_Task.Cols-1)=CStr(hid) '记录是原表哪一行
   Else      
      delrow=ERP_Task.TextMatrix(hid,ERP_Task.Cols-1)
      User_Task.RemoveItem delrow
      ERP_Task.TextMatrix(hid,ERP_Task.Cols-1)=""
      ERP_Task.TextMatrix(hid,ERP_Task.Cols-2)=""
      '删除临时表相应行之后,原始表中相应列数字需要修改
      For i=delrow To User_Task.Rows-2
         ERP_Task.TextMatrix(User_Task.textmatrix(i,User_Task.cols-1),vid+1)=i
      Next
   End If
End If

End Sub

5. 上移按钮脚本

Sub OnClick(ByVal Item)
Dim currow,Erp_Task,User_Task
Dim colvalue
Dim selrow,selcol
Dim rowno1,rowno2 '这两个变量存放临时表中“原表行号”
Dim rowno3,rowno4 '这两个变量存放原表行号
Dim i,btn
Set Erp_Task=ScreenItems("Erp_Task")
Set User_Task=ScreenItems("User_Task")
Set btn=ScreenItems("btn_up")
selrow=User_Task.Row
selcol=User_Task.Col
For i=1 To User_Task.cols-1
  colvalue=User_Task.TextMatrix(selrow,i)
  User_Task.TextMatrix(selrow,i)=User_Task.TextMatrix(selrow-1,i)
  User_Task.TextMatrix(selrow-1,i)=colvalue
Next
'改变原表中"临时表行号"字段
User_Task.Row=User_Task.Row-1
rowno1=User_Task.TextMatrix(User_Task.Row,User_Task.cols-1)
rowno2=User_Task.TextMatrix(User_Task.Row+1,User_Task.cols-1)
ERP_Task.TextMatrix(User_Task.TextMatrix(User_Task.Row,User_Task.Cols-1),ERP_Task.cols-1)=User_Task.Row
ERP_Task.TextMatrix(User_Task.TextMatrix(User_Task.Row+1,User_Task.Cols-1),ERP_Task.cols-1)=User_Task.Row+1

'如果移动到第一行,按钮失效
If User_Task.Row=1 Then
   btn.Enabled=False
Else
   btn.Enabled=True
End If
End Sub

6.下移按钮vbs脚本

Sub OnClick(ByVal Item)   
Dim currow,Erp_Task,User_Task
Dim colvalue
Dim selrow,selcol
Dim i,btn
Set User_Task=ScreenItems("User_Task")
Set Erp_Task=screenitems("Erp_Task")
Set btn=ScreenItems("btn_Down")
selrow=User_Task.Row
selcol=User_Task.Col
For i=1 To User_Task.cols-1
  colvalue=User_Task.TextMatrix(selrow,i)
  User_Task.TextMatrix(selrow,i)=User_Task.TextMatrix(selrow+1,i)
  User_Task.TextMatrix(selrow+1,i)=colvalue
Next
User_Task.Row=User_Task.Row+1
'改变原表中"临时表行号"字段
rowno1=User_Task.TextMatrix(selrow,User_Task.cols-1) '用户选中的那一行在Erp_Task表中的行号
rowno2=User_Task.TextMatrix(selrow+1,User_Task.cols-1) '用户选中的行紧邻下一行在Erp_Task表中的行号
Erp_Task.TextMatrix(rowno1,Erp_Task.cols-1)=selrow
Erp_Task.TextMatrix(rowno2,Erp_Task.cols-1)=selrow+1
If User_Task.Row>=User_Task.Row-2 Then
   btn.Enabled=False
Else
   btn.Enabled=True
End If
End Sub

7. 下达任务按钮vbs脚本

Sub OnClick(ByVal Item)                                                  
Dim Product(),Pressure(),Tempreture(),CurDate()'定义动态数组,事先不知道配方任务有多少条
Dim conn,con,ssql
Dim PCName
Dim UserTask,UATaskCount
Dim i,Download
PCName=HMIRuntime.Tags("@LocalMachineName").Read '数据库所在计算机名字
Set Download=HMIRuntime.Tags("Download")
Set UserTask=ScreenItems("User_Task")
UATaskCount=UserTask.rows-2
Redim CurDate(UATaskCount),Product(UATaskCount),Pressure(UATaskCount),Tempreture(UATaskCount)
For i=1 To UATaskCount
  CurDate(i)=UserTask.TextMatrix(i,1)
  Product(i)=UserTask.TextMatrix(i,2)
  Pressure(i)=UserTask.TextMatrix(i,3)
 Tempreture(i)=UserTask.TextMatrix(i,4) 
Next
'先删除表格内容
con="Provider = SQLOLEDB.1;password = sa;user id = sa;Initial Catalog =ERP;Data Source = " & PCName & "\WINCC"
Set conn=CreateObject("ADODB.Connection")
conn.ConnectionString=con
conn.open
ssql="delete from usertask"
conn.Execute ssql
'逐行把usertask表格内容添加到sql数据表UserTask中
For i= 1 To UATaskcount
  ssql="insert into UserTask(CurDate,Product,Pressure,Tempreture) values('" & CurDate(i) & "','" & Product(i) & "','" & CStr(Pressure(i)) & "','" & CStr(Tempreture(i)) & "')"
  conn.Execute ssql 
Next
conn.close
Set conn=Nothing
Download.Write 1
End Sub

8.新建全局vbs脚本,循环触发器10s触发一次

Option Explicit
Function action
Dim con,conn,ssql,ors,Rscount,PCName
Dim con1,conn1,ssql1,ors1
Dim Product,Pressure,Tempreture,Download
Dim id,job
Dim CurDate(),CP(),YL(),WD()
Dim i,Index
PCName=HMIRuntime.Tags("@LocalMachineName").Read '数据库所在计算机名字
Set Product=HMIRuntime.Tags("S7$程序(1)/DB1.Product")
Set Pressure=HMIRuntime.Tags("S7$程序(1)/DB1.Pressure")
Set Tempreture=HMIRuntime.Tags("S7$程序(1)/DB1.Tempreture")
Set Download=HMIRuntime.Tags("Download")
Set id=HMIRuntime.Tags("@MyUA_ID")
Set job=HMIRuntime.Tags("@MyUA_Job")
Set Index=HMIRuntime.Tags("Index")
If download.Read =1 Then
con="Provider = SQLOLEDB.1;password = sa;user id = sa;Initial Catalog =ERP;Data Source = " & PCName & "\WINCC"
Set conn=CreateObject("ADODB.Connection")
conn.ConnectionString=con
conn.open
ssql="select * from usertask"
conn.Execute ssql
Set ors=CreateObject("ADODB.RecordSet")
ors.open ssql, conn, 1,3
rscount=ors.recordcount
Redim Curdate(rscount),CP(rscount),YL(rscount),WD(rscount)
ors.movefirst
Curdate(1)=ors.fields("Curdate").value
CP(1)=ors.fields("Product").value
YL(1)=ors.fields("Pressure").value
WD(1)=ors.fields("Tempreture").value
For i=1 To rscount-1
  ors.movenext
  Curdate(i+1)=ors.fields("Curdate").value
  CP(i+1)=ors.fieldS("Product").value
  YL(i+1)=ors.fields("Pressure").value
  WD(i+1)=ors.fields("Tempreture").value
Next
Set ors=Nothing
conn.close
Index.Write Index.Read + 1
'Msgbox Index.Read
If Index.read <=rscount Then 
  Product.Write CP(Index.read)
  Pressure.Write YL(Index.read)
  Tempreture.Write WD(Index.read)
 ' Msgbox Index.read
  '写入用户归档
  id.Write -1
  job.Write 6
  'Msgbox j
  '把ERP_Task表格finished字段修改成‘已完成’
  con1="Provider = SQLOLEDB.1;password = sa;user id = sa;Initial Catalog =ERP;Data Source = " & PCName & "\WINCC"
  Set conn1=CreateObject("ADODB.Connection")
  conn1.ConnectionString=con1
  conn1.open
  ssql1="update task set finished=N'是' where CurDate='" & CurDate(Index.read) & "' and Product='" & CP(Index.read) & "' and Pressure=" & CStr(YL(Index.read)) & " and Tempreture=" & CStr(WD(Index.read))
  conn1.Execute ssql1 
End If
If Index.read>=rscount Then
   Index.Write 0
   Download.Write 0
End If
End If
End Function

当“下达任务”按钮点击后,二进制内部变量download变成1,全局脚本有效,然后查询sql表ueser_task

,逐条读取记录,将值传给PLC变量,同时用户归档做记录。如果读完最后一条user_task表格记录,download恢复0,行序号index恢复0,如果切换到用户归档页面,就可以看到记录。

这样完成后,整个需求的基本功能就完全实现了。但是这种思路有不完善的地方:

1. 定时逐条给下位机传送配方参数,如果遇上上下位机通讯问题,配方不能及时下达,那么生产就会中断,实际使用可以考虑一次性把所有配方下载到PLC。

2. 我们在选择配方任务时,如果遇到标注已完成的,就没必要再次选择下达任务,这个在ERP_Task控件点击的脚本中可以再完善一下。

 

标签:控件,Task,ERP,用户,ors,Set,User,归档,TextMatrix
来源: https://www.cnblogs.com/fishingsriver/p/14356133.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有