作者 | 主题 |
---|---|
合 奇侠 经验值:6088 发帖数:3970 精华帖:20 |
楼主 2009-08-18 17:23:18
主题:应用探讨-WinCC脚本应用
脚本的应用给WinCC项目带来了极大的灵活性和开放性。通过使用脚本可以完成一些 WinCC 基本组态无法实现的功能。
从版本V6起,WinCC同时提供了C 和VB 两套脚本系统,使脚本功能更加丰富、易用。 9月11日之前,特召集广大网友围绕WinCC的 C 和VB 脚本展开讨论,欢迎在此分享讨论各种和脚本功能、性能相关的经验、技巧或问题,大家可以一起攻克难题、共同提高。 最后可以将大家交流的精华加以整理,便于今后作为实际应用的参考。参加探讨和在讨论中有突出表现的网友都将获得加倍奖励。 预祝大家交流畅快,收获丰富! |
dcount107 侠圣 经验值:2862 发帖数:1760 精华帖:55 |
楼 2009-08-18 18:05:58
主题:回复:应用探讨-WinCC脚本应用
VBS的另外一个弱点就是无法直接调用API函数,只能通过其他的方法解决。
网上常见的方法应该是通过dynwrap.dll先注册再调用,比如: quote: Dim UserWrap Set UserWrap = CreateObject("DynamicWrapper") ' Call MessageBoxA(), first register the API function UserWrap.Register "USER32.DLL", "MessageBoxA", "I=HsSu", _ "f=s", "R=l" ' now call the function UserWrap.MessageBoxA Null, "MessageBox (ANSI)", _ "From DynaWrap Object", 3 dynwrap的下载地址我已经找不到了,大家可以上网搜索。另外安装DriveMonitor后就会有这个文件,详细用法在DriveMonitor帮助信息中也可以找到。 另外我试过利用Excel代为声明,VBS调用Excel的宏来实现,这是一篇我写的关于VBS结合EXCEL调用API函数的心得总结,内容太长我就不贴了,直接见附件,附件DOC附有本文档用到的Excel文件、VBS文件以及C函数。 VBS_EXCEL_API.rar 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。
非淡泊无以明志,非宁静无以致远
|
城外之人 版主 经验值:17271 发帖数:8461 精华帖:18 |
楼 2009-08-19 08:01:44
主题:回复:应用探讨-WinCC脚本应用
还有一点值得注意,就是C脚本和VBS在WinCC运行系统中是独立的。可以做到特殊场合下的并行运行。
一般的编程人员,最好能掌握这两种脚本语言。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。
无论成与败,无论甜与苦,我还是我。
|
dcount107 侠圣 经验值:2862 发帖数:1760 精华帖:55 |
楼 2009-08-19 17:41:34
主题:回复:应用探讨-WinCC脚本应用
编写C脚本常用的一些书籍和工具:
C语言基础(需要注意的是WInCC并不是支持所有的标准C函数): 87712838C语言编程宝典.rar 29886299C语言函数大全(语法着色版).rar WinCC标准函数总结(内部函数目前没有看到相关的资料,看帮助就OK了) 32830635WinCC标准函数总结 再有就是自V4版本开始官方发布的手册《WINCC组态手册1.pdf》,其中的第4章是学习WinCC C脚本的最佳资料: 60447518WINCC组态手册1.rar 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。
非淡泊无以明志,非宁静无以致远
|
dcount107 侠圣 经验值:2862 发帖数:1760 精华帖:55 |
楼 2009-08-20 10:48:38
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用masscer在2009-08-20 10:06:38的发言: 有一次,我的WinCC需要读取一个科尔摩根伺服控制器中的数据,就是用VB调用科尔摩根提供的API函数写了一个控件,然后嵌入WinCC,万事大吉。但是我其实一直想直接在WinCC中调用科尔摩根API函数的,没有实现,哪位大侠提供点信息 在函数和动作中使用 DLL WinCC 允许用户使用自己的 DLL(动态链接库)。 通过对各自的函数或动作进行必要补充,可以在函数和动作中启用现有 DLL 中的函数。 在函数或动作前添加下列代码: #pragma code(" . . . #pragma code() 实例: #pragma code("kernel32.dll") VOID GetLocalTime(LPSYSTEMTIME lpSystemTime); #pragma code() SYSTEMTIME st; GetLocalTime(&st); 对于上述过程,也可以在“Apdefap.h”头文件中作必要补充。 在 WinCC 中使用自己的 DLL 时,必须使用发行版。 WinCC 是发行版,因而也使用系统 DLL 的发行版。 如果在调试版中生成自定义 DLL,则可能 DLL 的发行版和调试版二者都将装载,进而会增加需要的内存空间。 DLL 的结构必须使用 1 个字节对齐方式方式进行设置。 ----------------------------------------------------------------- 不管采用什么方法,达到目的就行,没必要什么都用WinCC去实现。相反我认为还是使用嵌入控件的方式更加方便,毕竟WInCC的资源是有限的。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。
非淡泊无以明志,非宁静无以致远
|
dcount107 侠圣 经验值:2862 发帖数:1760 精华帖:55 |
楼 2009-08-21 09:28:33
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用城外之人在2009-08-21 07:51:23的发言: 如何定义当前画面、父画面、基画面、其它画面上的对象?这是编程中经常遇到的问题。 还有,用Web Navigator发布的画面,引用又有不同,还请大家在此一一列出,作个总结! VBS访问主画面的方法,以下三种方法均可,需要注意画面名称不要有.pdl后缀: Set objScreen = HMIRuntime.Screens(1) Set objScreen = HMIRuntime.Screens("") Set objScreen = HMIRuntime.Screens("BaseScreenName") VBS访问当前画面对象,可省略Screens: Set MyObj = ScreenItems("ObjectName") 相信大家都用过画面窗口这个控件,主要用于主画面导航、操作面板等,VBS访问子画面中的对象相当麻烦,非得把画面的路径写全了才行,非常讨厌。比如: Set objScreen = HMIRuntime.Screens("BaseScreenName.ScreenWindow:ScreenName") 如果有多层画面窗口嵌套,就会类似于下面的语句: Set objScreen = HMIRuntime.Screens("Main.PicWind1:A.PicWind2:B") 如果你使用的是标准PCS7界面,怎是一个烦字了得,呵呵。 这点不知道在新版本中有没有改进,或者目前有没有更好的解决办法? C脚本则不存在这样的问题,比如SetText(lpszPictureName,lpszObjectName,szText);中的 lpszPictureName只需要填写画面的名称即可。当然lpszPictureName也可以按照VBS这种写法。 WebNavigator没有动手试过,不好妄下评论。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。
非淡泊无以明志,非宁静无以致远
|
阿瑟斯 游民 经验值:124 发帖数:25 精华帖:3 |
楼 2009-08-25 09:17:05
主题:回复:应用探讨-WinCC脚本应用
贴一段C脚本数据库访问的例子:
__object *cn, *rs; int i,fields=10; cn=__object_create("ADODB.Connection"); rs=__object_create("ADODB.RecordSet"); // Connect cn->Open("Provider=SQLOLEDB.1;Integrated Security=SSPI;Initial Catalog=Northwind;Data Source=(local)\\WinCC"); if (cn->State == 0) printf ("DB Connect failed\n"); else { rs->Open("Select * FROM Products",cn,1); rs->MoveFirst; while(!rs->eof) { for(i=0;i printf("\r\n"); rs->MoveNext; } rs->Save("C:\\my.xml",1); rs->Close; cn->Close; 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
cop 游民 经验值:119 发帖数:25 精华帖:2 |
楼 2009-08-25 14:05:04
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用永不言懂在2009-08-25 12:54:05的发言: 一直以来的一个疑问,WinCC 启动以后以变量变化触发的全局脚本都会被执行一次,虽然可以根据变量的值来判断是否需要执行,但有些特殊需求下就无法完成了,不知道有没有什么更好的办法。 我也遇到过这种问题,因为刚启动时,系统确实扫描到值的变化,所以很忠实的却又很多余地执行了一下脚本。 最后,我是加了标志判断来保证刚启动时脚本不执行。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
et2008 游士 经验值:240 发帖数:34 精华帖:4 |
楼 2009-08-26 09:25:47
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用et2008在2009-08-19 10:26:28的发言: quote:以下是引用阿阿涛在2009-08-19 07:18:35的发言: 我想请教各位高手,怎样通过WINCC实现有声音的报警,出现故障后,电脑发出一定频率声音! #pragma code("kernel32.dll") long Beep(long lFrequency,long lDuration); #pragma code() Beep(880,500);//高音 Beep(440,500);//低音 这段脚本可能会引起脚本堵塞,同样Sleep()也会堵塞脚本队列。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
checkitout 官方工程师 经验值:1628 发帖数:180 精华帖:17 |
楼 2009-08-26 09:32:29
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用et2008在2009-08-26 09:25:47的发言: quote:以下是引用et2008在2009-08-19 10:26:28的发言: quote:以下是引用阿阿涛在2009-08-19 07:18:35的发言: 我想请教各位高手,怎样通过WINCC实现有声音的报警,出现故障后,电脑发出一定频率声音! #pragma code("kernel32.dll") long Beep(long lFrequency,long lDuration); #pragma code() Beep(880,500);//高音 Beep(440,500);//低音 这段脚本可能会引起脚本堵塞,同样Sleep()也会堵塞脚本队列。 对于发声功能可以考虑用异步播放方式比较好: #pragma code("winmm.dll") BOOL PlaySound(LPCTSTR lpszSound,HMODULE hModule,DWORD dwSound); #define SND_FILENAME 0x00020000L #define SND_ASYNC 0x0001 #pragma code() PlaySound("C:\\sound.wav",NULL,SND_FILENAMESND_ASYNC); 或者使用PC短促声音:MessageBeep((WORD)-1); 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
北方明珠 侠圣 经验值:2006 发帖数:96 精华帖:27 |
楼 2009-09-04 21:05:37
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用剑忠在2009-09-04 17:56:09的发言: 如果对于用户自定义的控件,能够正确进行打包安装并注册,一般情况下是可以正常稳定地使用的。但是由于WinCC提供了一个大的控件容器,而用户的控件(是一种COM组件)要由控件容器进行调度,因此与WinCC直接使用脚本相比,效率就会降低一些,因此不能过多的使用. 但是若是从扩展WinCC的功能而言(比如说支持基于.NET的应用程序访问Web服务器),编写这种.NET控件也不失为一种好的选择.你这样用第三方软件写WinCC脚本程序即费时,修改又麻烦,DLL库文件版本的兼容性、稳定性都不高,运行WinCC的Windows系统DLL库文件配置稍有不当(例如:更换了WinCC工作站的PC电脑后),将极易造成Windows系统死机。况且还得Visual Studio .NET开发工具,这东西安装后自身就是一个庞然大物,安装时间又长,资源消耗也大,平时用就是一堆垃圾? 此方式我在多年前用VB 6.0开发工具时曾大量使用过,但效果不佳,主要是既繁琐,又稳定性差。每次更换和维护WinCC工作站后,都会因一些细节处理不好而出些问题。 各位大侠们:这在安全性、稳定性要求极高的工控领域,是不能大量使用的,本来是想展示自己的编程技能,赢得领导的青睐,而实际是弄不好使自己名声扫地,陷于被动和难堪!但作为从业人员的一项技能,是可以学习的。 剑忠兄说了 Visual Studio .NET 开发工具是一个庞然大物,那么如果WinCC也支持.NET类编译开发的化,想必WinCC也有可能变成庞然大物(其所要支持的Dll和库文件众多).并且,这种用户自定义的控件开发,确实要求开发者具有一定的编程经验,费事和麻烦应该也很自然吧,就好比您自己开发了一个.NET程序,也是要不断修改编译执行的,这毕竟是用到了WinCC的扩展功能,而不是WinCC做为组态软件必须具有的功能. 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
北方明珠 侠圣 经验值:2006 发帖数:96 精华帖:27 |
楼 2009-09-07 14:50:29
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用阿磊在2009-09-05 09:45:27的发言: 虽然WinCC的全局脚本(对应于进程 Gscrt.exe - Global s cript Runtime)与画面中的脚本分别运行在不同的进程,但是全局脚本的各个动作同时运行在同一个线程中,其中一个动作发生阻塞,会影响另外一个动作。请问高人一个问题:两个全局C脚本,其中一个被阻塞了,另一个会怎样,是不是也会被阻塞?多个全局脚本是独立的单线程吗? 可以设计两个全局脚本动作,进行如下的测试: 动作1:每隔2秒钟执行一次,变量1加1。 动作2:每隔2秒钟执行一次,变量2加1,使用Sleep函数延迟5秒钟。 结论:使用输入\输出域显示两个变量,两个变量都是大约每隔5秒钟加1(如果没有Sleep函数,两个变量都是大约每隔2秒钟加1)。因此,全局脚本的多个动作是互相影响的。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |
北方明珠 侠圣 经验值:2006 发帖数:96 精华帖:27 |
楼 2009-09-08 10:29:42
主题:回复:应用探讨-WinCC脚本应用 quote:以下是引用阿磊在2009-09-07 23:24:26的发言: 不知道您使用的是全局脚本项目函数,还是全局动作呢?如果在画面中调用的是全局项目函数,应该属于画面的脚本线程,切换画面的时候,重新启动新的画面周期,执行该画面中的脚本,前一画面中未执行的脚本队列被释放。全局C脚本里面对PLC的值进行读取和更新,有对数据库的操作,但有的时候发现设备不动作,点击按钮进入状态界面(用于显示PLC的状态),观察PLC的值。此时设备就会继续动作,按钮中未写任何脚本,只是用直接连接来给一个内部变量赋值以用于切换画面? 怀疑是全局脚本中对数据库的操作阻塞了脚本的运行,不知道是不是原因啊?为什么点击按钮后又能解除呢?恳请高人帮忙啊? 如果您怀疑是数据库的操作阻塞了进程,您可以在脚本中屏蔽掉操作数据库的代码,观察是否还出现阻塞的现象;也可以在您的全局脚本中加入printf函数,输出到GSC诊断窗口中,判断是否发生阻塞。 一般来说,如果您在一个项目中组态的动作(包括全局动作或画面中周期调用的动作)不能被正确或及时地处理,例如,动作的触发周期为2秒钟,但是执行该脚本所需要的时间为5秒钟,这样大量动作累积起来,不能处理的动作被输入队列。如果在脚本队列中的任务数目达到了5000,那么路径“ 另外,关于WinCC对C脚本的诊断方法有很多,以下几种仅供参考,在WinCC的帮助文档中可以找到更多详细的内容: 1.GSC运行系统:提供关于所有(全局脚本)动作的动态特性信息。 2.GSC诊断:按调用的顺序输出 printf 指令,可以将变量的数值和错误信息等输出到诊断窗口。 3.ApDiag工具:WinCC 自带的诊断工具 “ApDiag.exe” 对故障和性能问题进行了详细的分析,关于如何使用诊断工具“APDiag”来调试C脚本,请参见如下链接:http://support.automation.siemens.com/CN/view/zh/22892912。 管理员注:本帖已被纳入此次探讨发帖整理WinCC脚本应用,请点此详阅。 |