搬家第三天-55.Wincc v7.3 MSHFGrid 操作数据库模拟ERP任务

前面写过一篇博客,介绍Wincc上使用MSHFGrid来读取ERP数据表,本文再次介绍这种任务,加入了写ERP数据表的一些功能。

一 任务简介

   假设有这么一张数据表(如上图),是ERP给生产单元下单的任务单,上面有日期、任务编号、槽罐编号、重量、分配状态五个信息。其中任务编号上有日期和槽罐编号信息,同一个槽罐同一天可能有多批次任务,所以任务编号后面从000开始编排。分配状态表示了这个任务编号是否被生产单元采纳,生产单元可以根据设备、人员、原材料等实际情况自行决定是否接受这些任务。重量是ERP下达的一个生产指标,同样的生产单元在接收任务的同时可以自行决定是否需要修改这个指标,如果修改值小于任务值,那么修改ERP数据表相应重量值为修改值,并且增加一条记录且标识为未分配;如果修改值大于任务值,那么修改ERP数据表相应重量为修改值,不增加记录。生产单元选择完任务后,可以将这些任务的前后执行顺序进行修改。

     通过上述描述可以看出,要完成这些任务,实际上就是在Wincc中使用控件和SQL语句查询读写SQL数据表,个人认为Wincc中读写数据表也就MSHFGrid和OWC好用一点,本文使用MSHFGrid来完成。

 二 Wincc页面设计

   为了达到上述效果,我们在Wincc页面中放入以下控件:

1. Microsoft Date and Time Picker Control V6.0(SP4)

这是日期选择控件,我们将其名字修改为DTPicker,其他属性使用默认值。

2. Microsoft Hierarchical FlexGrid Control V6.0Sp4(OLEDB)

这是一个数据控件用于显示sql数据表的,我们共需要两个这样的控件,名字分别修改为BaseTable和TempTable。其中BaseTable用于显示从ERP表查询到的某个日期的任务表,TempTable用于显示用户筛选和修改用户任务表,给现场设备下达的生产指令,也是基于这张表。

3. 按钮

我们需要在画面上放置四个按钮进行用户操作,其中上移任务按钮名字修改为upbtn,下移任务按钮名字修改为downbtn,其他按钮名字不变。

放置完所有控件后的HMI页面如下:

三 脚本

1.  查询当日未分配生产任务按钮脚本

这个查询主要是连接数据表把日期等于选择日期,分配状态为“未分配”的记录显示出来,要注意DTPicker中日期格式是YYYY/M/D,数据表里面是YYYY-MM-DD,需要统一格式。

Sub OnClick(Byval Item)              
Dim conn
Dim ssql
Dim ors
Dim ocom
Dim scon
Dim BaseTable,temptable,DTPicker,rowcount,i
Dim ADODC
Dim PCName,colscount
Dim SelYear,SelMonth,SelDay,SelDate
Set DTPicker=ScreenItems("DTPicker")
SelYear=CStr(Year(DTPicker.value))
SelMonth=Month(DTPicker.Value)
SelDay=Day(DTPicker.Value)
If selmonth<10 Then
   selmonth="0" & CStr(selmonth)
Else
   selmonth=CStr(selmonth)
End If
If selday<10 Then
   selday="0" & CStr(selday)
Else
   selday=CStr(selday)
End If
SelDate=selyear & "-" & selmonth & "-" & selday
PCName=HMIRuntime.Tags("@LocalMachineName").Read
scon="Provider = SQLOLEDB.1;Integrated Security=SSPI;Persist SecurityInfo=False;Initial Catalog =MyDB;Data Source = " &PCName & "\WINCC"
ssql="select * from PF where 日期='" & seldate & "' and 分配状态=N'未分配'"
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
If ors.recordcount=0 Then
   Msgbox "当天没有生产任务"
Else
 Set BaseTable=ScreenItems("BaseTable")
 Set BaseTable.DataSource=ors
 BaseTable.Refresh
 'BaseTable.colwidth(1)=1000
 'BaseTable.colwidth(2)=1500
 Set ors=Nothing
 conn.close
 Set conn=Nothing
 ' 增加一列用于勾选,一列记录临时表行号
 colscount=BaseTable.Cols
 BaseTable.Cols = colscount + 2
 BaseTable.TextMatrix(0,colscount)="点击选择"
 BaseTable.TextMatrix(0,colscount+1)="临时表行号"
 BaseTable.colwidth(1)=1200
 BaseTable.colwidth(2)=1500
End If

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

Set temptable=ScreenItems("TempTable")
rowcount=temptable.Rows
temptable.Row=1
For i=1 To temptable.Rows-2
   temptable.RemoveItem temptable.Row
   temptable.Row=1
Next

End Sub

 

2. BaseTable选择生产任务填充至TempTable脚本

生产任务basetable是ERP系统下达的指令,生产现场的情况可能无法完全执行这些任务,就需要进行筛选。为了避免误选,我们可以对已经选择的任务取消,因此临时增加了两列数据,一列记录是否选择了此任务,一列记录此任务在TempTable上处于第几行。当筛选再取消一个任务后,不仅影响当前任务,原有选择的任务在TempTable表格中行号也会发生改变,这点需要注意。在BaseTable表的点击事件加入以下脚本:

Sub Click(ByVal Item)            
Dim BaseTable,TempTable
Dim hid,vid,DefaultValue,ModifyValue
Dim colcount
Dim i,TempTable_currow
Dim delrow

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

 

3. TempTable表格修改任务指标

选择好生产任务后,我们还可以修改生产任务指标(重量),Microsoft Hierarchical FlexGrid Control V6.0Sp4(OLEDB)控件修改数据不像text控件那么直接方便,在这里我们使用inputbox来解决。修改的数据最终还要影响ERP原始表,生产任务还可以根据需要上下移动顺序,相关脚本我们在后面按钮脚本中介绍。

在TempTable表的点击事件中加入以下脚本:

Sub Click(Byval Item)             
Dim hid,vid,DefaultValue,ModifyValue,LeftValue,TopValue
Dim TempTable,btn1,btn2
Set TempTable=ScreenItems("TempTable")
Set btn1=ScreenItems("upbtn")
Set btn2=ScreenItems("downbtn")

hid=TempTable.Row
vid=TempTable.col
If hid
  btn2.Enabled =True
End If
If hid<=temptable.Rows-2  Then
  btn1.Enabled =True
End If
ModifyValue=""
If (hid>=1 And hid<=TempTable.rows-1) And vid=TempTable.cols-3 Then
  DefaultValue=CSng(TempTable.TextMatrix(hid,vid))
   '规范修改的数据类型和范围
   Do While (Not IsNumeric(ModifyValue))
     ModifyValue=Inputbox("输入想修改的数值,并确保小于原有数值","修改数值",DefaultValue,300,300)
   Loop
   If ModifyValue<>"" Then  '只有用户输入数值并且没有按下ESC,数字才会被修改
     TempTable.TextMatrix(hid,vid)=ModifyValue
   End If
 End If
End Sub

 

4. 上移任务按钮脚本

我们要对生产任务进行上下移动调整顺序,先判断当前任务是不是已经处于第一位了,如果处于第一位就没必要移动,上移任务调整了任务在TempTable表格中的顺序,相应的在BaseTable中标识的行号也要进行修改。在上移按钮的点击事件中加入以下脚本:

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

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

 

5. 下移任务按钮脚本

我们要对生产任务进行上下移动调整顺序,先判断当前任务是不是已经处于倒数第一位了,如果处于倒数第一位就没必要移动,下移任务调整了任务在TempTable表格中的顺序,相应的在BaseTable中标识的行号也要进行修改。在下移按钮的点击事件中加入以下脚本:

Sub OnClick(ByVal Item)           
Dim currow,BaseTable,TempTable
Dim colvalue
Dim selrow,selcol,rowno1,rowno2
Dim i,btn
Set TempTable=ScreenItems("TempTable")
Set BaseTable=ScreenItems("BaseTable")
Set btn=ScreenItems("downbtn")
selrow=TempTable.Row
selcol=TempTable.Col

For i=1 To TempTable.cols-1
  colvalue=temptable.TextMatrix(selrow,i)
  TempTable.TextMatrix(selrow,i)=temptable.TextMatrix(selrow+1,i)
  TempTable.TextMatrix(selrow+1,i)=colvalue
Next
TempTable.Row=selrow+1

'改变原表中"临时表行号"字段

rowno1=TempTable.TextMatrix(selrow,TempTable.cols-1)
rowno2=TempTable.TextMatrix(selrow+1,TempTable.cols-1)

BaseTable.TextMatrix(rowno1,BaseTable.cols-1)=selrow
BaseTable.TextMatrix(rowno2,BaseTable.cols-1)=selrow+1

If Temptable.Row>=Temptable.Row-2 Then
   btn.Enabled=False
Else
   btn.Enabled=True
End If
End Sub

 

6. 确认任务脚本

生产任务筛选修改后,要下达给生产设备,也需要返回信息给ERP系统,确认任务按钮会把选择上的任务的分配状态表示为“已分配”,如果修改了生产指标(重量),改大了就直接修改原指标值,改小了就增加一行记录,写上差值。按钮点击事件的脚本如下:

Sub OnClick(ByVal Item)                              
Dim conn,ssql,ors,ocom,scon
Dim BaseTable,DTPicker,rowcount,i,intiWeight,Taskid
Dim PCName,colscount
Dim SelYear,SelMonth,SelDay,SelDate
Dim TempTable
Set TempTable=ScreenItems("TempTable")
PCName=HMIRuntime.Tags("@LocalMachineName").Read
scon="Provider = SQLOLEDB.1;Integrated Security=SSPI;Persist SecurityInfo=False;Initial Catalog =MyDB;Data Source = " &PCName & "\WINCC"
'将选择的任务标记"已分配"
For i=1 To TempTable.Rows-2
 ssql="update PF Set 分配状态 = N'已分配' where 任务编号 = '" & TempTable.TextMatrix(i,2) & "' and 日期='" & TempTable.TextMatrix(i,1) & "'" 
 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 ors=Nothing

Next
'若重量进行了修改,且修改值小于原值,则把原值修改并增加一条记录
For i=1 To TempTable.Rows-2
   ssql="select 重量 from PF where  任务编号 = '" & TempTable.TextMatrix(i,2) & "' and 日期='" & TempTable.TextMatrix(i,1) & "'"
   Set ors=CreateObject("ADODB.RecordSet")
   Set ocom=CreateObject("ADODB.Command")
   ocom.commandtype=1
   Set ocom.ActiveConnection=conn
   ocom.CommandText=ssql
   Set ors=ocom.Execute
 
   '判断重量是否进行了修改
   If CSng(ors.fields(0))> CSng(TempTable.TextMatrix(i,4)) Then
     intiWeight=ors.fields(0)
     Set ors=Nothing
     
     '修改重量
     ssql="Update PF set 重量='" & TempTable.TextMatrix(i,4) & "' where  任务编号 = '" & TempTable.TextMatrix(i,2) & "' and 日期='" & TempTable.TextMatrix(i,1) & "'"

     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 ors=Nothing

     '增加一条记录,先计算当前日期,当前槽罐号任务编号的最大数值是什么,然后新的任务编号在此基础上+1
     ssql="select max(任务编号) from PF Where 槽罐编号='" &  TempTable.TextMatrix(i,3) & "' and 日期='" & TempTable.TextMatrix(i,1) & "'"

     Set ors=CreateObject("ADODB.RecordSet")
     Set ocom=CreateObject("ADODB.Command")
     ocom.commandtype=1
     Set ocom.ActiveConnection=conn
     ocom.CommandText=ssql
     Set ors=ocom.Execute
     Taskid=ors.fields(0)
     Taskid=Taskid+1
     Set ors=Nothing
   ssql="insert into PF(日期,任务编号,槽罐编号,重量,分配状态) values('" & TempTable.TextMatrix(i,1) & "',N'" & taskid & "',N'" & TempTable.TextMatrix(i,3) _
   & "',N'" & CStr(intiWeight-TempTable.TextMatrix(i,4)) & "',N'未分配') "
   Set ors=CreateObject("ADODB.RecordSet")
     Set ocom=CreateObject("ADODB.Command")
   Set ocom.activeconnection=conn
   ocom.CommandType=1
   ocom.CommandText=ssql
   Set ors=ocom.Execute
   Set ors=Nothing
   conn.close
   Set conn=Nothing
   Else '若修改值大于原始值,那么不增加新记录,将原设定值修改
     ssql="Update PF set 重量='" & TempTable.TextMatrix(i,4) & "' where  任务编号 = '" & TempTable.TextMatrix(i,2) & "' and 日期='" & TempTable.TextMatrix(i,1) & "'"
     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 ors=Nothing
   End If

Next
End Sub

 

需要注意的是处理数据表中中文字符,前面加N。补充ERP任务表数据结构如下:

 

posted @ 2021-01-31 11:15  来自金沙江的小鱼  阅读(1018)  评论(0编辑  收藏  举报