前段时间的一个项目用SE的vba做了一套报表,运用的是时间触发计数,每小时记一次,一个班记8次数据,本次这次项目需要用WINCC做报表,触发条件是事件触发,WINCC自带报表功能可以满足,但是WINCC对数据归档的数量有限制,而且记录的数据会出现一次数据分两行或者三行记录,数据拆分。因此就自学用VBS做报表,大概流程是:先用全局脚本把需要记录的数据写入SQL数据库,然后再用按钮脚本把数据库需要的数据提取出来,在MSFlexGrid控件中显示出来,再用一个按钮脚本把MSFlexGrid控件的数据通过excel进行打印,这种方法还有一个好处就是能对记录的数据进行处理和筛选再进行打印。
下面先看一下记录数据的全局脚本: Option Explicit Function action Dim cn Dim is_SQL Dim riqi Dim mw1,mw2,mw3,mw4,mw5,mw6 Dim y,m,d,h,mi,s y = CStr(Year(Now)) m = CStr(Month(Now)) d = CStr(Day(Now)) h = CStr(Hour(Now)) mi= CStr(Minute(Now)) s = CStr(Second(Now)) riqi = y & '-' & m & '-' & d & ' ' & h & ':' & mi & ':' & s 'riqi=Now'获取系统日期时间; a001=HMIRuntime.Tags('SL3_11#_One').Read b001=HMIRuntime.Tags('11b').Read Set cn=CreateObject('ADODB.connection') If a001= 1 And b001=0 Then Set mw1= HMIRuntime.Tags('001')'通过Set语句将mw1对象指向建立的通讯变量。 mw1.Read Set mw2= HMIRuntime.Tags('002')'通过Set语句将mw2对象指向建立的通讯变量。 mw2.Read Set mw3= HMIRuntime.Tags('003')'通过Set语句将mw3对象指向建立的通讯变量。 mw3.Read Set mw4= HMIRuntime.Tags('004')'通过Set语句将mw4对象指向建立的通讯变量。 mw4.Read Set mw5= HMIRuntime.Tags('005')'通过Set语句将mw5对象指向建立的通讯变量。 mw5.Read Set mw6= HMIRuntime.Tags('006')'通过Set语句将mw6对象指向建立的通讯变量。 mw6.Read cn.connectionString= 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DATA;Data Source=.\wincc' '拼写访问数据库的字符串,包括驱动名称、数据库、访问权限等 cn.Open '执行打开数据库指令 is_SQL='INSERT INTO ribaoVALUES(''&riqi&'',''&mw1.Value &'',''&mw2.Value &'',''&mw3.Value &'',''&mw4.Value &'',''&mw5.Value &'',''&mw6.Value &'')' '拼写存储到数据库的SQL的语句 cn.Executeis_SQL'执行此操作 cn.Close'结束访问数据库 End If HMIRuntime.Tags('11b').Write a001 End Function 以上是记录数据的程序,在记录数据前需要先在SQL里面建一个DATA数据库,并在DATA数据库建一个riqi表。 接下来需要往MSFlexGrid控件提取某个时间段的数据记录,需要用到DTpicker时间控件,即以下程序: Sub OnClick(Byval Item) Dim Text1,Date1,Date2,MSFlexGrid1 Dim By, Bm, Bd,Ny, Nm, Nd Dim Sql,strcn,conn,oRs,oCom, n Dim BeginDate Dim EndDate Dim z,i, t Dim a1, b1, c1, d1, e1, f1 Set Text1 = ScreenItems('Text1') Set Date1 = ScreenItems('Date1') Set Date2 = ScreenItems('Date2') Set MSFlexGrid1 = ScreenItems('MSFlexGrid1') By = Year(Date1.Value) Bm = Month(Date1.Value) Bd = Day(Date1.Value) Ny = Year(Date2.Value) Nm = Month(Date2.Value) Nd = Day(Date2.Value) BeginDate = By & '-' &Bm& '-' &Bd&' '& '00:00:00' EndDate = Ny& '-' & Nm & '-' &Nd&' '& '23:59:59' 'e = By & '-' &Bm& '-' &Bd 'f = Ny& '-' & Nm & '-' &Nd 'If By >Ny Or By = Ny And Bm> Nm Or By = Ny And Bm = Nm And Bd>Nd Then 'MsgBox '输入的时间不正确', vbOK, '错误的起始时间' 'End If '建立连接 'Sql = 'SELECT CONVERT(char(19), riqi, 20) AS riqi, mw1, mw2, mw3, mw4, mw5, mw6 FROM ribao WHERE riqi BETWEEN '' &BeginDate& '' and'' &EndDate& ''ORDER BY riqi' Sql = 'SELECT * FROM ribao WHERE riqi BETWEEN '' &BeginDate& '' and'' &EndDate& ''ORDER BY riqi' 'Sql = 'SELECT * FROM ribao ORDER BY riqi' 'Sql = 'SELECT * FROM ribao' strcn = 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DATA;Data Source=.\wincc' '创建一个ADO连接,连接运行数据库DATA Set conn = CreateObject('ADODB.Connection') '创建ADO连接对象,对数据库操作 conn.ConnectionString = strcn conn.CursorLocation = 3 conn.Open' 打开数据库连接 '使用命令文本查询 Set oRs = CreateObject('ADODB.Recordset') Set oCom = CreateObject('ADODB.Command') oCom.CommandType = 1 Set oCom.ActiveConnection = conn oCom.CommandText = Sql Set oRs = oCom.Execute n = oRs.RecordCount Text1.Text = n If n = 0 Then MsgBox '对不起,没有找到符合条件的数据', vbOK, '没有相关数据' End If oRs.Requery MSFlexGrid1.Clear MSFlexGrid1.Rows = oRs.RecordCount+2'显示的行数为查询到数据数目+6 MSFlexGrid1.ColWidth(0) = 800'第1列宽度 MSFlexGrid1.ColWidth(1) = 2100'第2列宽度 MSFlexGrid1.ColWidth(2) = 1200'第3列宽度 MSFlexGrid1.ColWidth(3) = 1200'第4列宽度 MSFlexGrid1.ColWidth(4) = 1200'第5列宽度 MSFlexGrid1.ColWidth(5) = 1200'第6列宽度 MSFlexGrid1.ColWidth(6) = 1200'第7列宽度 MSFlexGrid1.ColWidth(7) = 1200'第8列宽度 '合并单元格,显示标题 MSFlexGrid1.Row = 0'选中第一行。注意第一行,或者是第一列都从0开始 For z = 0 To 7 MSFlexGrid1.Col = z MSFlexGrid1.Text = '南大傲拓NA400采集日报表''通过FOR,NEXT操作,将8列内容都显示为'NA400数据采集日报表' Next MSFlexGrid1.MergeCells = 4'设置一个值4表明如何及何时将有相同内容的记录进行合并 MSFlexGrid1.MergeRow(0) = True'设置将0行内容合并 '显示属性 MSFlexGrid1.TextMatrix(1, 0) = 'id' MSFlexGrid1.TextMatrix(1, 1) = 'riqi' MSFlexGrid1.TextMatrix(1, 2) = 'MW1' MSFlexGrid1.TextMatrix(1, 3) = 'MW2' MSFlexGrid1.TextMatrix(1, 4) = 'MW3' MSFlexGrid1.TextMatrix(1, 5) = 'MW4' MSFlexGrid1.TextMatrix(1, 6) = 'MW5' MSFlexGrid1.TextMatrix(1, 7) = 'MW6' MSFlexGrid1.ColAlignment(0) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(1) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(2) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(3) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(4) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(5) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(6) = 4'设置当前列的对齐方式 MSFlexGrid1.ColAlignment(7) = 4'设置当前列的对齐方式 'oRs.MoveFirst For i = 1 TooRs.RecordCount MSFlexGrid1.TextMatrix(i + 1, 0) = i'第一列显示每条记录编号 'Next 'If (n > 0) Then ' oRs.MoveFirst ' i = 0 'End If 'Do While Not oRs.EOF 'i = i + 1 t = CStr(oRs.Fields(0).Value) a1 =CStr(oRs.Fields(1).Value)'取第2条记录的值。ADO Field 对象包含有关Recordset对象中某一列的信息。Recordset中的每一列对应一个 Field 对象 b1 =CStr(oRs.Fields(2).Value) c1 = CStr(oRs.Fields(3).Value) d1 = CStr(oRs.Fields(4).Value) e1 = CStr(oRs.Fields(5).Value) f1 =CStr(oRs.Fields(6).Value) a1 = Int(a1 * 10 ^ 3 + 0.5) / (10 ^ 3) b1 = Int(b1 * 10 ^ 3 + 0.5) / (10 ^ 3) c1 = Int(c1 * 10 ^ 3 + 0.5) / (10 ^ 3) d1 = Int(d1 * 10 ^ 3 + 0.5) / (10 ^ 3) e1 = Int(e1 * 10 ^ 3 + 0.5) / (10 ^ 3) f1 = Int(f1 * 10 ^ 3 + 0.5) / (10 ^ 3) MSFlexGrid1.TextMatrix(i + 1, 1) = t MSFlexGrid1.TextMatrix(i + 1, 2) = a1 MSFlexGrid1.TextMatrix(i + 1, 3) = b1 MSFlexGrid1.TextMatrix(i + 1, 4) = c1 MSFlexGrid1.TextMatrix(i + 1, 5) = d1 MSFlexGrid1.TextMatrix(i + 1, 6) = e1 MSFlexGrid1.TextMatrix(i + 1, 7) = f1 oRs.MoveNext Next oRs.close conn.close'退出程序前,关闭与数据库,记录集的连接 End Sub 接下来是从控件数据打印功能脚本: ubOnClick(Byval Item) Dim ExcelApp Dim ExcelBook Dim ExcelSheet Dim MSFlexGrid1 Dim i,irow,ICOL Dim z,k Set MSFlexGrid1 = ScreenItems('MSFlexGrid1') Set ExcelApp = CreateObject('Excel.Application') Set ExcelBook = ExcelApp.Workbooks.Add Set ExcelSheet = ExcelBook.Worksheets(1) ExcelApp.Visible = True ExcelSheet.Range('A1:H1').Merge For irow = 0 To MSFlexGrid1.Rows - 1 For ICOL = 0 To MSFlexGrid1.Cols - 1 z=MSFlexGrid1.Rows ExcelSheet.Cells(irow + 1,icol+1)=Trim(MSFlexGrid1.TextMatrix(irow, icol)) Next Next ExcelSheet.Range( 'A1:H'&z&'').Borders(1).Weight =2 ExcelSheet.Range( 'A1:H'&z&'').Borders(2).Weight =2 ExcelSheet.Range( 'A1:H'&z&'').Borders(3).Weight =2 ExcelSheet.Range( 'A1:H'&z&'').Borders(4).Weight =2 ExcelSheet.Rows(1).RowHeight = 0.75/0.035 ExcelSheet.Cells.EntireColumn.AutoFit ExcelSheet.Rows(1).Font.Name = '宋体' ExcelSheet.Rows(1).Font.Bold = True ExcelSheet.Rows(1).Font.Size = 16 ExcelSheet.Cells.HorizontalAlignment =3 'ExcelSheet.PageSetup.TopMargin = 2/0.035 'ExcelSheet.PageSetup.BottomMargin = 2/0.035 'ExcelSheet.PageSetup.LeftMargin = 2/0.035 'ExcelSheet.PageSetup.RightMargin = 2/0.035 ExcelSheet.PageSetup.CenterHorizontally = 2/0.035 ExcelSheet.printpreview'打印阅览 'ExcelSheet.PrintOut'打印时用此句 ExcelBook.Close ExcelApp.Quit Set ExcelApp = Nothing End Sub 一个完整的报表就做完了,希望对大家有所帮助。 作者介绍: 申培源 微信3群成员 申培源,郑州轻冶科技股份有限公司,电气工程师
|