WinCC读写
读:
#include "apdefap.h"
void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)
{
#pragma code("Shell32.dll")//调用动态链接库
char tag1[10],tag2[10];
__object* pExcel = NULL; //建立 pExcel 指针 用来对 EXCEL 进行操作
HWND handle=NULL;
handle=FindWindow(NULL,"WinCC-运行系统 - ");
if (MessageBox(handle,"Start","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel = __object_create("Excel.Application");
if (MessageBox(handle,"After Creat","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->Visible = 0;//控制excel文件是否可见,当1时,excel文件可见.
pExcel->Workbooks ->Open ("d:\\SetPointToPLC.xls");
if (MessageBox(handle,"After Open","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
if (MessageBox(handle,pExcel->Worksheets("sheet1")->Range("B1")->Value,"Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
strcpy(tag1,pExcel->Worksheets("sheet1")->Range("B1")->Value);
strcpy(tag2,pExcel->Worksheets("sheet1")->Range("B2")->Value);
SetTagChar("NewTag1",pExcel->Worksheets("sheet1")->Range("B1")->Value);//将excel文件B2里面的内容写到外部变量NewTag1
SetTagChar("NewTag2",pExcel->Worksheets("sheet1")->Range("B2")->Value);//将excel文件B3里面的内容写到外部变量NewTag2
if (MessageBox(handle,"After Read","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->Workbooks->Close();//关闭文件
pExcel->Quit();//退出Excel
__object_delete(pExcel);
}
写:
#include "apdefap.h"
void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)
{
#pragma code("Shell32.dll")//调用动态链接库
char tag1[10],tag2[10];
__object* pExcel = NULL; //建立 pExcel 指针 用来对 EXCEL 进行操作
HWND handle=NULL;
handle=FindWindow(NULL,"WinCC-运行系统 - ");
if (MessageBox(handle,"Start","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel = __object_create("Excel.Application");
if (MessageBox(handle,"After Creat","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGRO
UND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->Visible = 0;//控制excel文件是否可见,当1时,excel文件可见.
pExcel->Workbooks ->Open ("d:\\SetPointToPLC.xls");
if (MessageBox(handle,"After Open","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
if (MessageBox(handle,pExcel->Worksheets("sheet1")->Range("B1")->Value,"Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->Worksheets("sheet1")->Range("B3")->Value = GetTagChar("NewTag3"); //Return-Type: char*
pExcel->Worksheets("sheet1")->Range("B4")->Value = GetTagChar("NewTag4"); //Return-Type: char*
if (MessageBox(handle,"After Write","Test", MB_YESNO|MB_ICONQUESTION
|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->ActiveWorkbook->Save();
if (MessageBox(handle,"After Save","Test", MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_SYSTEMMODAL)==IDYES) { }
pExcel->DisplayAlerts = 0;
pExcel->Workbooks->Close();//关闭文件
pExcel->Quit();//退出Excel
__object_delete(pExcel);
===================================================================================================================
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
#pragma code("Shell32.dll")//调用动态链接库
__object* pExcel = NULL; //建立 pExcel 指针 用来对 EXCEL 进行操作
HWND handle=NULL;
handle=FindWindow(NULL,"WinCC-运行系统 - ");
pExcel = __object_create("Excel.Application");
//pExcel->Visible = 0;//控制excel文件是否可见,当1时,excel文件可见.
pExcel->Workbooks ->Open ("d:data\\ bb.xls");
SetTagFloat("xmaoyou",pExcel->Worksheets("sheet1")->Range("B30")->Value);//将excel文件B2里面的内容写到外部变量NewTag1
SetTagFloat("xchengpinyou",pExcel->Worksheets("sheet1")->Range("C30")->Value);
pExcel->Workbooks->Close();//关闭文件
pExcel->Quit();//退出Excel
__object_delete(pExcel);
}
===================================================================================================================
有一个老项目,现在需要改进
用wincc6.2创建了一个按钮,编写按钮的动作时vbs动作,下面是执行代码。其中d:\shuju.xls是预先用excel创建好的。
dim fso,myfile
set fso = CreatObject("Scripting.FileSystemObject")
set myfile = fso.GetFile("d:\shuju.xls")
dim objExcelApp
set objExcelApp = CreatObject("Excel.Application")
objExcelApp.Visible = true
objExcelApp.Workbooks.Open myfile
dim aa_data
set aa_data = HMTRuntime.Tags("@ServerName")
aa_data.Read
objExcelApp.worksheets("sheet1").cells(1,2).VAlue = aa_data.Value
objExcelApp.worksheets("sheet2").cells(1,2).VAlue = aa_data.Value
objExcelApp.ActiveWorkbook.Save
objExcelApp.Workbook.close
set objExcelApp = nothing
可是运行画面,点击此按钮没有一点运行的标记。而且shuju.xls文件没有任何记录。
是我设置错误还是程序错误。还是不能这样运行。
求详细解答!
1.“编写按钮的动作时vbs动作” 改用按钮按下或释放时动作vbs
可以将 objExcelApp.Workbooks.Open myfile 改成 objExcelApp.Workbooks.Open "d:\shuju.xls" 试一下。
删除最后的 set objExcelApp = nothing 这个没有必要。
===========================================================================================================
Dim objExcelApp
Set objExcelApp = CreateObject("Excel.Application")
objExcelApp.Visible = True
objExcelApp.Workbooks.Open "D:XQ\ExcelExample.xls"
objExcelApp.Cells(4, 3).Value = ScreenItems("IOField1").OutputValue
objExcelApp.ActiveWorkbook.Save
objExcelApp.Workbooks.Close
objExcelApp.Quit
Set objExcelApp = Nothing
为什么我便在在WINCC的一个按钮的VBS脚本里后 运行后画面上点那个按钮EXCEL的表画面跳了下就没了就闪了一下 谢谢哪位高手指点下
==================================================================================================================
WinCC VBS利用EXCEL调用Windows API函数
前面已经讨论过利用VBS的CreateObject方法来干很多以前不敢想象的事情,但Windows API却没有办法,虽有DynmicWrapper.dll这样的东西,毕竟使用起来不方便,而且功能也有限。如果利用EXCEL作为突破口,VBS调用EXCEL的宏,而由EXCEL的宏来调用Windows API正可以很好的解决这一问题。
1. 简单举例
在API.XLS的Sheet1中加入如下代码:
Private Declare Function SHShutDownDialog Lib "shell32" Alias "#60" (ByVal
YourGuess As Long) As Long
Public Sub ShowShutDownDlg() '显示关机界面
SHShutDownDialog 0
End Sub
在WinCC调用之前先用EXCEL运行一下,效果如下:
接下来由WinCC的VBS调用如下:
Dim oExcelFile,oExcel,oWorkBook,oSheet
oExcelFile= HMIRuntime.ActiveProject.Path + "\APIXLS\API.XLS"
Set oExcel = CreateObject("Excel.Application")
Set oWorkBook = oExcel.workbooks.OPen(oExcelFile)
Set oSheet = oWorkBook.Sheets("Sheet1")
oExcel.run "Sheet1.ShowShutDownDlg"
oWorkBook.Close
Set oWorkBook = Nothing
oExcel.quit
Set oExcel = nothing
效果和EXCEL中是一模一样的,^_^。
2. 如何传递参数,和取得返回值
但大多数时候我们需要调用一些API函数,传递某些值来获取返回值,比如FindWindow。
oExcel.run传递参数是可以的,比如EXCEL有宏:
Public Sub TestMsg(Msg As String)
MsgBox Msg
End Sub
那么调用的时候用oExcel.run "Sheet1. TestMsg",”TEST MSG HERE” 即可。
但oExcel.run却不支持返回值的,因此得另想办法。其实也简单,利用Sheet1的表格来存放返回值就可以了,EXCEL宏调用后将值写入Range中,而VBS则读取该Range的值即可,以此达到取得返回值之目的,^_^。下面以FindWindow为例:
在API.XLS的Sheet1中加入如下代码:
接下来由WinCC的VBS调用如下:
但oExcel.run却不支持返回值的,因此得另想办法。其实也简单,利用Sheet1的表格来存放返回值就可以了,EXCEL宏调用后将值写入Range中,而VBS则读取该Range的值即可,以此达到取得返回值之目的,^_^。下面以FindWindow为例:
在API.XLS的Sheet1中加入如下代码:
代码
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal
lpClassName As String, ByVal lpWindowName As String) As Long
Public Sub xlsFindWindow(WindowTitle As String)
Dim hwnd As Long
hwnd = FindWindow(vbNullString, WindowTitle)
Sheet1.Range("A1").Value = hwnd
End Sub
接下来由WinCC的VBS调用如下:
代码
Dim oExcelFile,oExcel,oWorkBook,oShee
t
oExcelFile= HMIRuntime.ActiveProject.Path + "\APIXLS\API.XLS"
Set oExcel = CreateObject("Excel.Application")
Set oWorkBook = oExcel.workbooks.OPen(oExcelFile)
Set oSheet = oWorkBook.Sheets("Sheet1")
oExcel.run "Sheet1.xlsFindWindow","WinCC-Runtime - "
'#向FindWindow传递参数
MsgBox oSheet.Range("A1").Value '#从Sheet中取得返回值
oExcel.DisplayAlerts = False
'#关闭EXCEL提示,因为我们对Sheet进行了修改,退出的时候会提示是否保存
oWorkBook.Close
Set oWorkBook = Nothing
oExcel.quit
Set oExcel = nothing
3. 性能优化
大家都知道EXCEL调用起来是很慢的,尤其是每次CreateObject、workbooks.Open、oWorkBook.Close、oExcel.quit等等一整套程序下来,太浪费时间了,如果能像Public对象那样,自WinCC打开后就一直共享,自然要省事的多,而且也提高了执行效率。可以利用WinCC的DataSet对象来是Excel成为公共对象,关于DataSet详细使用见我的另一篇心得《WinCC V6使用DataSet创建全局对象.doc》。
将以下代码放在起始页的OnOpen事件中:
代码
On Error Resume Next '#必加,否则GetObject会报错
Dim oExcelFile,oExcel,oWorkBook,oSheet
oExcelFile= HMIRuntime.ActiveProject.Path + "\APIXLS\API.XLS"
'MsgBox oExcelFile
Set oExcel = GetObject(,"Excel.Application") '#试图获取已经打开的EXCEL进程
'MsgBox TypeName(oExcel)
If VarType(oExcel)=vbEmpty Then '#如果为到EXCEL进程,则由CreateObject新建
Set oExcel = CreateObject("Excel.Application") '#新建EXCEL进程
End If
Set oWorkBook = oExcel.workbooks(“API.XLS”) '#试图获取已经打开的Excel文件
'MsgBox TypeName(oWorkBook)
If VarType(oWorkBook)=vbEmpty Then '#如未到,则有Open打开Excel文件
Set oWorkBook = oExcel.workbooks.OPen(oExcelFile) '#打开Excel文件
'MsgBox oExcelFile & " Open Succeed!"
End If
Set oSheet = oWorkBook.Sheets("Sheet1")
HMIRuntime.DataSet.Remove("oExcel")
HMIRuntime.DataSet.Add "oExcel",oExcel
'#将oExcel保存到DataSet中,以供其它调用
HMIRuntime.DataSet.Remove("oSheet")
HMIRuntime.DataSet.Add "oSheet",oSheet
'#将oSheet保存到DataSet中,以供其它调用
上面的代码用于WinCC启动后首先检测是否有EXCEL进程,否则则新建EXCEL进程,以保证同时只有一个EXCEL.EXE在进程中,然后将API.XLS打开,并将oExcel和oSheet保存到DataSet中,以供其它调用。
下面是WinCC任何页面中的调用方法:
代码
Dim oExcel,oSheet
Set oExcel = HMIRuntime.DataSet("oExcel").Value
Set oSheet = HMIRuntime.DataSet("oSheet").Value
write的返回值oExcel.run "Sheet1.xlsFindWindow","WinCC-Runtime - " '#向FindWindow传递参数
MsgBox oSheet.Range("A1").Value
由于省掉了CreateObject和quit,调用速度非常快。
4.WinCC退出后关闭
当然在WinCC退出时要想办法把刚开始打开的EXCEL进程给关闭掉,否则内存都给EXCEL吃掉了。
标准函数里提供了OnDeactivateExecute,但这
是C脚本,没有办法获取VBS的DataSet对象。只有在退出按钮中想办法了:
代码
'#结束EXCEL
Dim oExcel
Set oExcel = HMIRuntime.DataSet.Item("oExcel").Value
oExcel.DisplayAlerts = False
oExcel.quit
Set oExcel = Nothing
'#退出WinCC
Dim WinCCODK
Set WinCCODK = CreateObject("WinCCODK.Admin")
WinCCODK.ExitWinCCEx &H1
不过也可以利用OnDeactivateExecute来调用相关的VBS而达到关闭EXCEL进程的目的。
代码
void OnDeactivateExecute()
{
#define GetObject GetObject
__object *oWSH=NULL;
__object *HMIProj=NULL;
char VbsPath[255];
oWSH= __object_create("WScript.Shell");
HMIProj= __object_create("CCHMIRTProject.HMIProject");
sprintf(VbsPath,"%s\\OnDeactivateExecute.VBS",(char*)HMIProj->Path);
//MessageBox(NULL,VbsPath,"test",MB_OK);
oWSH->Run(VbsPath);
__object_delete(oWSH);
__object_delete(HMIProj);
}
鉴于C脚本调用自动化对象比较难调试,而且OnDeactivateExecute已经没有办法使用GSC诊断,因此以上的C脚本仅为调用项目路径下的OnDeactivateExecute.VBS,剩下的工作交给它就可以了。
代码
'****该脚本用于WinCC退出时由标准函数OnDeactivateExecute进行调用***
On Error Resume Next
Dim oExcel,oWorkBook
Dim fso,FilePath
Set fso=CreateObject("Scripting.FileSystemObject")
FilePath=fso.GetFolder(".").Path & "API.xls"
'MsgBox FilePath
Set oExcel = GetObject(,"Excel.Application")
oExcel.DisplayAlert = False
oExcel.WorkBooks(FilePath).Close
oExcel.quit
Set oExcel = nothing
Set fso = Nothing
==================================================================================================================
在WINCC中,有一个在对象区域鼠标动作,出相对应的画面,并在画面窗口属性中写入画面名称和变量前缀,显示为1. char *tagprefix; char str2[50] ; 其中有 sprintf(str2,"%s%s",tagPrefix,"PictureName"); SetPropChar(parentPicture,str,"PictureName",GetTag
Char(str2);
这个 sprintf(str2,"%s%s",tagPrefix,"PictureName");怎样理解?
比如这样写有什么不同? sprintf(str2,"%s%s",“PictureName",tagPrefix);望热心的大哥帮助小第。
sprintf();的主要作用是生成格式化字符串:
假设:tagPrefix[] = "abds";
那么: sprintf(str2,"%s%s",tagPrefix,"PictureName");的结果是”abdsPictureName“
sprintf(str2,"%s%s",“PictureName",tagPrefix);的结果是”PictureNameabds“
需要注意str2的长度是否足够!
追问:
还有,那GetTagChar(str2);的输出应该是什么?是"abdsPictrueName"吗?如果是那SetPropChar(parentPicture,str,"PictureName",GetTagChar(str2);图片名称应该是以“.PDL"为后缀,那是怎样写入图片名称的呢?很感谢你的帮助,在此先谢了!
追答:
GetTagChar是WinCC下开发的使用的函数,其中的参数是变量名(关键字)通过该变量名查到它的对应值。
对于它的使用类似于C中的getenv(”XXX“); 用来获取环
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论