VBA的控件及用户窗体.docx
《VBA的控件及用户窗体.docx》由会员分享,可在线阅读,更多相关《VBA的控件及用户窗体.docx(180页珍藏版)》请在冰豆网上搜索。
![VBA的控件及用户窗体.docx](https://file1.bdocx.com/fileroot1/2023-5/29/da48aa8b-f4d9-4f03-8fff-7dffec13db37/da48aa8b-f4d9-4f03-8fff-7dffec13db371.gif)
VBA的控件及用户窗体
第8章控件与用户窗体
技巧1限制文本框的输入
用户在使用文本框输入数据时,往往希望能限制输入数据的类型,比如只能输入数字。
但是没有内置的属性能限制在文本框中只能输入数字,只能在文本框的事件过程中使用代码来测试输入的是哪类字符,然后只允许输入数字字符和一个“-”号、一个“.”号,如下面的代码所示。
#001PrivateSubTextBox1_KeyPress(ByValKeyANSIAsMSForms.ReturnInteger)
#002SelectCaseKeyANSI
#003CaseAsc("0")ToAsc("9")
#004CaseAsc("-")
#005IfInStr(1,Me.TextBox1.Text,"-")>0Or_
#006Me.TextBox1.SelStart>0Then
#007KeyANSI=0
#008EndIf
#009CaseAsc(".")
#010IfInStr(1,Me.TextBox1.Text,".")>0Then
#011KeyANSI=0
#012EndIf
#013CaseElse
#014KeyANSI=0
#015EndSelect
#016EndSub
代码解析:
文本框的KeyPress事件过程,测试键盘输入的是哪类字符,只允许输入数字字符和一个“-”号、一个“.”号。
KeyPress事件的语法如下:
PrivateSubobject_KeyPress(ByValKeyANSIAsMSForms.ReturnInteger)
参数Object是必需的,一个有效的对象。
参数KeyANSI是可选的,整数值,代表标准的数字ANSI键代码。
第2行代码使用CaseElse语句测试文本框KeyPress事件的KeyANSI参数值。
第3行代码,如果键盘输入的是0到9之间的数字字符,则允许输入。
如果想在文本框中允许其它类型的字符输入,在此句代码中列出允许输入的字符即可。
第4行到第8行代码,如果键盘输入的是“-”号,先使用InStr函数测试文本框中是否已有“-”号,如果InStr函数返回值大于0,说明文本框中已有“-”号。
接下来使用文本框的SelStart属性来测试插入点,如果文本框的SelStart属性值大于0,说明“-”号的插入点不是第一个。
如果以上两个条件中有任何一个成立,将KeyAscii参数值设置为0,使文本框只能在第一位输入一个“-”号。
第9行到第12行代码,如果键盘输入的是“.”号的话,使用InStr函数测试文本框中是否已有“.”号,如果已有“.”号,将KeyAscii参数值设置为0,使文本框只能输入一个“.”号。
第13、14行代码,如果键盘输入的是其他字符则将KeyAscii参数值设置为0,使文本框不能输入其他字符。
经过以上设置文本框只允许输入数字字符和一个“-”号、一个“.”号,但是能输入中文字符。
如果希望限制中文字符的输入,可以在文本框的Change事件中进行设置,如下面的代码所示。
#001PrivateSubTextBox1_Change()
#002DimiAsInteger
#003DimsAsString
#004WithTextBox1
#005Fori=1ToLen(.Text)
#006s=Mid(.Text,i,1)
#007SelectCases
#008Case".","-","0"To"9"
#009CaseElse
#010.Text=Replace(.Text,s,"")
#011EndSelect
#012Next
#013EndWith
#014EndSub
代码解析:
文本框的Change事件,判断输入的字符是否为数字字符和“-”号、“.”号,如果不是则使用Replace函数将文本框中输入的其他字符替换成空白。
第5、6行代码在文本框输入的所有字符中循环。
第8行代码列出允许输入的字符。
如果想在文本框中允许其它字符输入,在此句代码中列出即可。
第9、10行代码,如果不是允许输入的字符,使用Replace函数替换成空白。
经过以上的设置,文本框中只能在第一位输入一个“-”号、一个“.”号和“0”到“9”的数字。
技巧2文本框添加右键快捷菜单
VBA中的控件没有提供右键快捷菜单,用户可以使用Excel中的命令栏自已添加右键快捷菜单。
步骤1:
按组合键进入VBE窗口,单击菜单“插入”→“模块”,在其代码窗口输入以下代码:
#002PublicSubCreateShortCutMenu()
#003DimShortCutMenuAsCommandBar
#004DimShortCutMenuItemAsCommandBarButton
#005DimsCaptionAsVariant
#006DimiFaceIdAsVariant
#007DimsActionAsVariant
#008DimiAsInteger
#009sCaption=Array("剪切(&C)","复制(&T)","贴粘(&P)","删除(&D)")
#010iFaceId=Array(21,19,22,1786)
#011sAction=Array("Action_Cut","Action_Copy","Action_Paste","Action_Delete")
#012OnErrorResumeNext
#013Application.CommandBars("ShortCut").Delete
#014SetShortCutMenu=Application.CommandBars.Add("ShortCut",msoBarPopup)
#015WithShortCutMenu
#016Fori=0To3
#017SetShortCutMenuItem=.Controls.Add(msoControlButton)
#018WithShortCutMenuItem
#019.Caption=sCaption(i)
#020.faceID=Val(iFaceId(i))
#021.OnAction=sAction(i)
#022EndWith
#023Next
#024EndWith
#025EndSub
代码解析:
第1行代码,在模块级别中声明变量ActiveTB是用来对应窗体中的文本框所触发的所有事件的变量。
CreateShortCutMenu过程用来创建标题为“ShortCut”的右键快捷菜单,并添加4个菜单项。
关于自定义右键快捷菜单请参阅技巧86。
#001PublicSubShowPopupMenu(txtCtrAsMSForms.TextBox)
#002DimActionAsVariant
#003SetActiveTB=txtCtr
#004WithApplication.CommandBars("ShortCut")
#005.Controls
(1).Enabled=txtCtr.SelLength>0
#006.Controls
(2).Enabled=.Controls
(1).Enabled
#008.Controls(4).Enabled=.Controls
(1).Enabled
#009.ShowPopup
#010EndWith
#011EndSub
代码解析:
ShowPopupMenu过程根据文本框中字符的选中状态设置右键快捷菜单菜单项的Enabled属性后使用ShowPopup方法显示右键快捷菜单。
第5行代码,如果当前文本框中已有选中的字符则“剪切”按钮有效。
第6行代码,如果当前文本框中已有选中的字符则“复制”按钮有效。
第7行代码,如果剪贴板中包含对象支持的数据。
则“贴粘”按钮有效。
第8行代码,如果当前文本框中已有选中的字符则“删除”按钮有效。
第9行代码,显示快捷菜单。
#001PublicSubAction_Cut()
#002
#003EndSub
#004PublicSubAction_Copy()
#006EndSub
#007PublicSubAction_Paste()
#009EndSub
#010PublicSubAction_Delete()
#011DimsAsString
#012WithActiveTB
#013s=.SelText
#014.Value=Replace(.Value,s,"")
#015EndWith
#016EndSub
代码解析:
Action_Cut过程是快捷菜单中单击“剪切”菜单项所运行的过程。
使用Cut方法将当前选中的文本框中的文本删除并移至剪贴板。
Action_Copy过程是快捷菜单中单击“复制”菜单项所运行的过程。
使用Copy方法将文本框选中的文本复制到剪贴板上。
Action_Paste过程是快捷菜单中单击“贴粘”菜单项所运行的过程。
使用Paste方法把剪贴板上的内容传送到一个文本框中。
Action_Delete过程是快捷菜单中单击“贴粘”菜单项所运行的过程。
使用Replace函数将文本框中选中的文本的文本替换成空字符。
#001PublicSubDeleteShortCutMenu()
#002OnErrorResumeNext
#003Application.CommandBars("ShortCut").Delete
#004EndSub
代码解析:
DeleteShortCutMenu过程删除创建的右键快捷菜单。
步骤2:
在VBE窗口中,单击菜单“插入”→“用户窗体”,在窗体上添加两个文本框控件。
双击窗体,在其代码窗口中输入下面的代码。
#001PrivateSubUserForm_Initialize()
#002CallCreateShortCutMenu
#003EndSub
#004PrivateSubTextBox1_MouseUp(ByValButtonAsInteger,ByValShiftAsInteger,ByValXAsSingle,ByValYAsSingle)
#005IfButton=2ThenShowPopupMenuActiveControl
#006EndSub
#007PrivateSubTextBox2_MouseUp(ByValButtonAsInteger,ByValShiftAsInteger,ByValXAsSingle,ByValYAsSingle)
#008IfButton=2ThenShowPopupMenuActiveControl
#009EndSub
#010PrivateSubUserForm_QueryClose(CancelAsInteger,CloseModeAsInteger)
#011CallDeleteShortCutMenu
#012EndSub
代码解析:
第1行到第3行代码,窗体的Initialize事件,在窗体初始化时运行CreateShortCutMenu过程创建右键快捷菜单。
第4行到第9行代码,文本框的MouseUp事件,当用户右健单击文本框时运行ShowPopupMenu过程在选中的菜单项上显示右键快捷菜单。
第10行到第12行代码,窗体的QueryClose事件,在关闭窗体时运行DeleteShortCutMenu过程删除右键快捷菜单。
窗体运行后,右键单击文本框显示右键快捷菜单,如图991所示。
图991文本框快捷菜单
技巧3文本框回车自动输入
在使用文本框向工作表输入数据时,为了加快输入速度,可以利用文本框的KeyDown事件,回车后自动输入并清空文本框,如下面的代码所示。
#001PrivateSubTextBox1_KeyDown(ByValKeyCodeAsMSForms.ReturnInteger,ByValShiftAsInteger)
#002WithTextBox1
#003IfLen(Trim(.Value))>0Then
#004IfKeyCode=vbKeyReturnThen
#005Sheet1.Range("A65536").End(xlUp).Offset(1,0)=.Value
#006.Text=""
#007EndIf
#008EndIf
#009EndWith
#010EndSub
代码解析:
文本框的KeyDown事件,在输入数据并按键后自动将数据录入到工作表A列最后一个非空单元格的下一个单元格中。
KeyDown事件在按下键盘按键时发生,语法如下:
PrivateSubobject_KeyDown(ByValKeyCodeAsMSForms.ReturnInteger,ByValShiftAsfmShiftState)
参数object是必需的,一个有效的对象。
参数KeyCode是必需的,代表被按下的键的键代码。
参数Shift是可选的,Shift、Ctrl和Alt的状态。
第3行代码,为了防止误输入空白数据,使用Len函数和Trim函数检查文本框内是否为有效数据。
第4行代码,根据KeyCode参数值判断是否按下了回车键。
如果用户按下了回车键,KeyCode参数返回常数vbKeyReturn。
第5、6行代码,将文本框数据输入到工作表A列的最后一个单元格内,同时清空文本框内容准备下一次输入。
技巧4自动选择文本框内容
如果希望光标进入文本框时能自动选择文本框内容,可以在文本框的MouseUp事件中来完成,如下面的代码所示。
#001PrivateSubTextBox1_MouseUp(ByValButtonAsInteger,ByValShiftAsInteger,ByValXAsSingle,ByValYAsSingle)
#002WithTextBox1
#003IfButton=2Then
#004.SelStart=0
#005.SelLength=Len(.Text)
#006EndIf
#007EndWith
#008EndSub
代码解析:
文本框的MouseUp事件,在光标进入文本框释放鼠标右键时自动选择文本框内容。
MouseUp事件在用户释放鼠标按键时发生,语法如下:
PrivateSubobject_MouseUp(ByValButtonAsfmButton,ByValShiftAsfmShiftState,ByValXAsSingle,ByValYAsSingle)
参数object是必需的,一个有效的对象。
参数Button是可选的,设置引起该事件的鼠标按键的整数值,如表格1011所示。
常数
值
说明
fmButtonLeft
1
按下左键。
fmButtonRight
2
按下右键。
fmButtonMiddle
3
按下中键。
表格1011Button参数值
参数Shift是可选的,Shift、Ctrl和Alt的状态。
参数X和参数Y是可选的,窗体、框架或页的位置的横坐标与纵坐标。
第3行到第6行代码,如果用户进入文本框释放鼠标右键,设置文本框的SelStart属性为0,SelLength属性为文本框的全部字符数。
SelStart属性指定选中文本的起点,语法如下:
object.SelStart[=Long]
参数object是必需的,一个有效的对象。
参数Long是可选的,指定选中文本的起点。
SelLength属性指定文本框或组合框的文本部分中选中的字符数,语法如下:
object.SelLength[=Long]
参数object是必需的,一个有效的对象。
参数Long是可选的,指定选中的字符数。
运行窗体,当光标进入文本框释放鼠标右键时自动选择文本框内容,如图1011所示。
图1011自动选择文本框内容
技巧5设置文本框数据格式
文本框在用来输入数据时,除了限制输入的数据类型外,还可以设置文本框的数据格式,如下面的代码所示。
)
#002TextBox1=Format(TextBox1,"0.00")
#003EndSub
#004PrivateSubTextBox2_Exit(ByValCancelAsMSForms.ReturnBoolean)
#005TextBox2=Format(TextBox2,"0.00")
#006EndSub
代码解析:
文本框的Exit事件过程,在文本框输入数据时使用Format函数格式化为两位小数格式。
控件的Exit事件在同一窗体中的一个控件即将把焦点转移到另一个控件之前发生,语法如下:
PrivateSubobject_Exit(ByValCancelAsMSForms.ReturnBoolean)
参数Object是必需的,一个有效的对象。
参数Cancel是必需的,事件状态。
如果设置为False表示由该控件处理这个事件(默认方式)。
设置为True表示由应用程序处理这个事件,并且焦点留在当前控件上。
当文本框在输入完数据失去焦点时使用Format函数格式化自定义数值格式。
Format函数语法如下:
Format(expression[,format[,firstdayofweek[,firstweekofyear]]])
参数expression是必需的,任何有效的表达式。
参数format是可选的,有效的命名表达式或用户自定义格式表达式。
参数firstdayofweek是可选的,常数,表示一星期的第一天。
参数firstweekofyear是可选的,常数,表示一年的第一周。
在本例中,将文本框的数据格式化成自定义的两位小数的数值格式,关于Format函数格式化日期和时间等其他数据请参阅VBA中Format函数的帮助。
#001PrivateSubTextBox1_Change()
#002TextBox3=Format(Val(TextBox1)*Val(TextBox2),"0.00")
#003EndSub
#004PrivateSubTextBox2_Change()
#005TextBox3=Format(Val(TextBox1)*Val(TextBox2),"0.00")
#006EndSub
代码解析:
文本框的Change事件过程,在两个文本框输入完数据后,使用文本框的Change事件使TextBox3显示其相乘的金额并格式化为两位小数的数据格式。
Change事件在控件的Value属性改变时发生,语法如下:
PrivateSubobject_Change()
参数object是必需的,一个有效的对象。
Change事件过程可以使显示在控件上的数据同步或一致。
在本例中,当TextBox1或TextBox2的数据发生改变时,两者相乘的金额的金额也随之改变并在TextBox3中显示。
因为文本框的数据类型是文本字符串,不能直接进行计算的,所以计算前先使用Val函数转换为数字,才能进行计算。
运行窗体,输入数据后格式化为两位小数的数据格式,如图1021所示。
图1021设置文本框的数据格式
技巧6限制文本框的输入长度
在使用文本框输入数据时,可能希望限制能输入的字符长度,即只能输入一定长度的字符,超过设置数值就不能输入,这时可以通过设置文本框的MaxLength属性来实现,如下面的代码所示。
#001PrivateSubWorksheet_Activate()
#002Me.TextBox1.MaxLength=6
#003EndSub
代码解析:
工作表的激活事件过程,将文本框的MaxLength属性设置为6,使文本框只能输入6个字符,超过6个字符即不能输入。
应用于文本框控件的MaxLength属性规定用户可以在文本框中输入的最多字符数,语法如下:
object.MaxLength[=Long]
参数object是必需的,一个有效的对象。
参数Long是可选的,整数,表示所允许的字符数。
如果将MaxLength属性设置为0,表示只要内存允许则没有限制。
技巧7将光标返回文本框中
在用文本框往工作表录入数据时,一般会在录入到工作表前验证输入的数据是否正确,如果错误,则清空文本框内容,提示用户重新输入。
但此时光标已经不在文本框中,需要重新选择文本框才能输入。
可以在Exit事件中可以设置Cancel参数值使光标停留在当前文本框中,如下面的代码所示。
#001PrivateSubTextBox1_Exit(ByValCancelAsMSForms.ReturnBoolean)
#002WithTextBox1
#003If.Text<>""AndLen(Trim(.Text))<>15AndLen(Trim(.Text))<>18Then
#004.Text=""
#005MsgBox"身份证号码录入错误!
"
#006Cancel=True
#007EndIf
#008EndWith
#009EndSub
代码解析:
文本框的Exit事件,在输入身份证号码后即将把焦点转移到录入按钮控件之前检查输入的身份证号码是否正确。
Exit事件在一个控件从同一窗体的另一个控件实际接收到焦点之前发生,语法如下:
PrivateSubobject_Exit(ByValCancelAsMSForms.ReturnBoolean)
Cancel参数为事件状态。
False表示由该控件处理这个事件(这是默认方式)。
True表示由应用程序处理这个事件,并且焦点应当留在当前控件上。
第3行代码,使用Len函数和Trim函数检查输入的身份证号码是否为15位或18位。
第4行到第6行代码,如果输入的身份证号码不正确,清空文本框以便重新输入并提示用户,设置Cancel参数为True使光标停留在文本框中。
在Exit事件中之所以把文本框为空也做为通过验证的条件之一,因为如果不加上“TextBox1.Text<>""”这一条件,那么在窗体显示后,如果用户取消输入或关闭输入窗体,也会提示输入错误。
所以在录入到工作表之前再验证文本框