VBA在限定Excel工作表用户按钮中的应用_第1页
VBA在限定Excel工作表用户按钮中的应用_第2页
VBA在限定Excel工作表用户按钮中的应用_第3页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

VBA在限定Excel工作表用户按钮中的应用

摘要通过研究VBE及其下层对象的访问方法,本文详细地探讨了按钮过程的代码控制技术,从而实现了Excel测试软件中工作表用户按钮的执行限定。关键词按钮过程VBE下层对象代码限定1引言作为一个优秀的表格处理软件和系统开发平台,Excel拥有许多无可替代的优势。基于Excel环境开发的管理信息系统,具有操作直观性强、开发周期短的特点,因此形成了熟悉Excel操作的广大用户。为了保证开发系统的正常渠道流通及著作者利益,必须保护系统的使用权限,本文通过VBA的开发应用,提出了一种Excel工作表用户按钮的限定方法,以此来完善其系统测试软件的功能。2限定按钮执行及其对应过程代码限定工作表用户按钮的执行包括两个方面的含义,即限定其按钮对象的显示及其指定宏过程代码的有效性,两者结合在一起加以实现,才能起到既展现软件功能,又真正限制其过分执行操作的作用,从而体现对用户软件的测试目的。2.1查找按钮执行过程代码限定按钮对象及其执行代码,首要的问题便是获得其对应的执行代码过程名,并在当前工程的所有代码模块中查找其代码位置。实践表明,按钮对象与图形图像和艺术字体一样,都属于Shape形状对象,它们都有其对应的OnAction属性,代表其被指定的宏过程代码名称。需要指出的是窗体类型按钮对应的宏过程代码一般位于工程的标准模块中,而ActiveX按钮过程代码则位于工作表代码模块中,且其对应的正确执行过程名为其按钮名与相应的事件名的连接串。为了查找某个按钮对应的过程代码,需要对VBE(VisualBasic编辑器)的下层对象VBComponents进行搜索。VBComponents对象代表VBE编辑器下的各个代码模块VBComponent。通过对某一VBComponent的下一层对象CodeModule的相关属性的访问,可以获得诸如模块代码总行数等信息,也可以通过其Find方法查找指定内容的代码行。下面即为查找按钮过程、处理按钮过程代码的算法代码。SheetsCount=ActiveWorkbook.Worksheets.Count'对所有工作表中的所有按钮对象循环Fori=1ToSheetsCountSetMySheet=Worksheets(i)MySheet.ActivateForEachshInMySheet.Shapessh.Visible=Truesh.Select'取得选定对象所对应的过程名MyProname=sh.OnAction'对于ActiveX按钮,则只取得其onClick事件过程名Ifsh.Type=msoOLEControlObjectThen

MyProname=sh.Name&"_Click"EndIf……'StartLine、StartCol为设置查找按钮过程名的开始行、列序号,并在代码查找成功时'返回所在的代码行、列序号StartLine=1StartCol=1SetMyCoponent=Application.VBE.ActiveVBProject.VBComponents'在各代码模块中查找按钮过程ForEachchInMyCoponent

Ifsh.Type=msoOLEControlObjectAndch.Name<>sh.Parent.CodeNameThen

GoToLabel4EndIf'本代码模块的代码总行数

LinesCount=ch.CodeModule.CountOfLines

Endline=LinesCount

'忽略注释行,查找正确的过程头部位置

DoWhilech.CodeModule.Find("Sub"&MyProname&"()",StartLine,StartCol,Endline,1,False,False)AndLeft(Trim(ch.CodeModule.Lines(StartLine,1)),1)="'"StartLine=StartLine+1StartCol=1Endline=LinesCount

Loop

'找到了过程头部位置

Ifch.CodeModule.Find("Sub"&MyProname&"()",StartLine,StartCol,LinesCount,1,False,False)Andch.CodeModule.ProcOfLine(StartLine,vbext_pk_Proc)=MyPronameThen

'若还没有插入规定的代码

IfTrim(ch.CodeModule.Lines(StartLine+1,1))<>"'隐藏过程代码"Then

'代码1……,在按钮过程代码的首部加入过程调用代码

'代码2……,调整本代码行以后的已经插入的代码行调用参数

EndifEndIfLabel4:NextNextNextiActiveWorkbook.Save2.2插入过程调用代码经过查找按钮的执行过程代码的正确位置,就能够限定其执行的有效性。本文的处理方法是,在按钮的对应过程代码的首部加入两行代码,如:'隐藏过程代码Call模块5.隐藏过程代码(256,73,”Sheet2”,2,3)可以看出第一行代码是一注释行,第二行代码是一过程调用。正是这一过程调用,在按钮点击时首先被执行,从而实现了对按钮执行的准确计数,并在按钮执行到达规定次数时,阻止其执行。下面的代码通过对找到的按钮过程所在代码模块VBComponent的下层对象CodeModule采用InsertLines方法,首先在按钮对应过程的首部插入两行临时代码,然后通过该对象的ReplaceLine方法,将它们分别替换为正确的上述两行代码。这样先插入代码行、后替换代码行的目的是,在插入代码行后便于获得准确的过程起始代码行号,从而为下面的替换代码行语句准备正确的参数。下面即是上述查找按钮过程代码中“代码1”位置处的算法代码,其功能是在查找到的按钮过程代码的首部加入上述的两行代码:ModuleName=Application.VBE.SelectedVBComponent.Nam'获得过程所处的代码模块名CodeName=ch.Name'插入两行临时代码行ch.CodeModule.InsertLinesStartLine+1,"'插入代码行1"ch.CodeModule.InsertLinesStartLine+2,"'插入代码行2"'获得模块代码总行数、过程起始行号、过程代码总行数LinesCount=ch.CodeModule.CountOfLines'过程代码起始行号ProcStartline=ch.CodeModule.ProcStartline(MyProname,vbext_pk_Proc)'过程代码总行数ProcCountLines=ch.CodeModule.ProcCountLines(MyProname,vbext_pk_Proc)'替换为两行正确的代码行ch.CodeModule.ReplaceLineStartLine+1,"'隐藏过程代码"ch.CodeModule.ReplaceLineStartLine+2,"Call"&ModuleName&".隐藏过程代码("&ProcStartline&","&ProcCountLines&","&""""&CodeName&""""&","&i&","&sh.ZOrderPosition&")"此外,当按钮被点击执行并进入到插入的调用过程内部时,还需要确定哪个按钮被执行、执行的次数情况、以及执行按钮的对应过程代码的行范围等情况,以便准确地实施对执行按钮及其过程代码的控制,所以在上述为按钮过程替换为正确的过程调用代码的同时,需要添入正确的下列五个过程调用参数:(1)按钮的对应过程头部所在代码模块中的代码起始行号;(2)按钮过程的对应代码行数;(3)按钮过程所处的代码模块名;(4)按钮所在的工作表序号;(5)按钮在所在工作表上的Shape形状对象集合的序号。从上面的插入代码中可以看出获得这些参数的方法。针对上例的过程调用语句:Call模块5.隐藏过程代码(256,73,”Sheet2”,2,3),其参数含义是:当第2个工作表中的第3个Shape对象(按钮)执行次数到达规定次数时,则将名称为“Sheet2”的代码模块中从256行起的73行代码设为无效,并将该按钮进行隐藏。值得注意的是,由于某些按钮的对应过程代码加入了上述的过程调用代码,必然导致与之处于同一代码模块的其他按钮过程、并已经添入的上述过程调用代码中的参数值出现偏差,因此需要对其中的过程代码起始行参数值作修改。下面的代码就是起这个作用,此代码须插入于前述查找按钮过程代码的“代码2”位置。'调整代码查找起始位置Line1=StartLine+3Col1=1Endline=LinesCountDoIfNotch.CodeModule.Find("'隐藏过程代码",Line1,Col1,Endline,1,False,False)Then

ExitDoEndIf'如果查找的代码不符合插入的代码格式,则继续查找IfCol1>1Then

GoToLabel3EndIf'调整代码调用参数Str1=ch.CodeModule.Lines(Line1+1,1)IfInStr(Str1,"Call")ThenStr2=Mid(Str1,InStr(Str1,"(")+1,InStr(Str1,",")-InStr(Str1,"(")+1)Str2=Trim(Str(Val(Trim(Str2))+2))Str1=Left(Str1,InStr(Str1,"("))&Str2&Mid(Str1,InStr(Str1,","))ch.CodeModule.ReplaceLineLine1+1,Str1EndIfLabel3:Line1=Line1+1Col1=1Endline=LinesCountLoop2.3限定按钮对象及其执行过程代码限定按钮对象本身,之前我们可以为之添加一个名为“按钮运行次数记录表”的工作表,以便使用其第i行j列的单元格来记录当前工程第i个工作表上第j个形状对象的运行次数。此外,为了实现对按钮执行的准确计数,也需要在工程打开时清除其内容,为了防止工作表数据意外修改,最好将其隐藏。这些均可以通过创建自动宏来加以实现。下面的代码即是按钮执行时首先被调用的过程,其作用为对按钮执行进行计数,在按钮执行到达规定次数(这里暂定为5次)时,隐藏该按钮,并将其执行过程代码设为无效。这里将代码行设为无效的方式是将其改成注释,方法仍然是通过访问指定的VBComponent下CodeModule对象的Lines属性,并采用ReplaceLine方法来实现。改成的注释行的格式为:'隐藏行*:原代码行,其中*号代表其在本代码模块中的行号。下面的代码需要与前述的查找按钮过程代码位于同一代码模块。PublicSub隐藏过程代码(ByValBeginlineAsInteger,ByValLinesCountAsInteger,ByValCodeNameAsString,ByValSheetIndexAsInteger,ByValButtonIndexAsLong)……

Sheets("按钮运行次数记录表").Cells(SheetIndex,ButtonIndex).Value=Sheets("按钮运行次数记录表").Cells(SheetIndex,ButtonIndex).Value+1

IfSheets("按钮运行次数记录表").Cells(SheetIndex,ButtonIndex).Value>=5ThenSetMyCoponent=Application.VBE.ActiveVBProject.VBComponentsForEachchInMyCoponentIfch.Name<>CodeNameThen

GoToLabel5EndIf'将参数规定范围的代码改为注释Fork=BeginlineToBeginline+LinesCount-1

Str1=ch.CodeModule.Lines(k,1)

Str1="'隐藏行"&k-Beginline+1&":"&Str1

ch.CodeModule.ReplaceLinek,Str1Nextk'隐藏执行的按钮ActiveWorkbook.Sheets(SheetIndex).Shapes(ButtonIndex).Visible=FalseLabel5:Next……

EndIfEndSub3支撑对象与软件恢复提供对VBE及其下层对象的访问,需要创建对其支撑对象的引用,方法是进入VBE编辑环境,单击“工具”菜单的“引用”命令,然后加入对“MicrosoftVisualBasicforApplicationExtensibility5.3”的引用。此外,软件运行不应该影响其本来面目,所以在其被打开时需要将其本身提供的界面恢复初态,在工程保存时将已经变为注释行的代码恢复原状,下面通过编写当前工程的自动宏AUTO_OPEN和“ThisWorkbook”模块的Workbook_BeforeSave事件过程去分别实现这两个软件恢复功能:PublicSubAUTO_OPEN()'查找辅助工作表SheetsCount=Application.ActiveWorkbook.Worksheets.CountFori=1ToSheetsCountIfActiveWorkbook.Sheets(i).Name="按钮运行次数记录表"Then

FoundSheet=TrueEndIfNexti'添加或清除辅助工作表内容IfNotFoundSheetThenActiveWorkbook.UnprotectWorksheets.add.MoveAfter:=Worksheets(SheetsCount)ActiveSheet.Name="按钮运行次数记录表"ActiveSheet.Visible=FalseElseSheets("按钮运行次数记录表").Cells.ClearSheets("按钮运行次数记录表").Visible=FalseEndIf'将工作表中按钮恢复为显示状态SheetsCount=ActiveWorkbook.Worksheets.CountFori=1ToSheetsCountSetMySheet=Worksheets(i)ForEachshInMySheet.Shapes

Ifsh.Visible=FalseThensh.Visible=TrueNex

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论