创建向导样式的数据输入窗体.docx
《创建向导样式的数据输入窗体.docx》由会员分享,可在线阅读,更多相关《创建向导样式的数据输入窗体.docx(51页珍藏版)》请在冰豆网上搜索。
创建向导样式的数据输入窗体
创建向导样式的数据输入窗体
2011年04月12日,2:
14下午
Loading...
引言:
本文来源于《ProExcelVBA》的第4章的示例,主要为学习VBA用户窗体提供参考。
本文“超长”,但如果能够仔细研读,一定会有很丰富的收获。
可以先下载示例文档:
向导样式的输入是相当普遍的技术,用于帮助用户输入较多的或复杂的数据。
向导允许将数据分成相互联系的部分,通过按顺序输入数据的过程指导用户。
示例工作簿名称为HRWizard.xlsm,由2个工作表组成,名为EmpData的工作表为员工数据库工作表,名为ListMgr的工作表包含在创建数据输入窗体向导时使用的不同的列表。
(其实还有一个名为UFormConfig的工作表,存放着向导步骤的信息)
EmpData工作表被分成4部分:
Personal、Address、Equipment、Access,如下列图所示。
员工个人信息
员工地址信息
员工设备信息
员工访问信息
下面的向导窗体将引导用户为新员工输入信息。
布局向导窗体
1、打开VBE,添加新用户窗体。
2、将用户窗体的高度设置为320,宽度为332。
3、将用户窗体重命名为HRWizard。
4、在用户窗体顶部添加标签,将其Caption属性设置为:
MyCompany–HRWizard,设置字体为大尺寸,如18pt。
5、在用户窗体中添加一个多页控件。
6、设置该控件的Height属性为216,Width属性为270。
7、将其在用户窗体中居中,在用户窗体底部留出空间。
此时的用户窗体如下图所示。
由于有4个数据集合部分,需要再添加两个页。
1、在多页控件顶部的选项卡中单击右键。
2、在快捷菜单中选择“新建页”,如下图所示。
3、重复上面的步骤。
此时的用户窗体如下图所示。
在用户窗体中添加控件
在“Page1”中添加的控件如下表所示,与EmpData工作表中个人信息列标题一致。
表:
HRWizard用户窗体控件
在多页控件的下方添加四个命令按钮。
现在的用户窗体和下图相似。
在“Page2”中添加的控件如下表所示,与EmpData工作表中地址信息列标题一致。
表:
Address选项卡控件设置
Page2如下图所示。
在“Page3”中添加的控件如下表所示,与EmpData工作表中设备信息列标题一致。
表:
设备选项卡控件设置
Page3如下图所示。
在“Page4”中添加的控件如下表所示,与EmpData工作表中访问信息列标题一致。
表:
访问选项卡控件设置
Page4如下图所示。
至此,界面设计完成。
接下来,设置一些类来使用户窗体工作。
一开始,可能认为一个与数据记录相联系的类就满足要求了,但我们将在定义类时分解功能区,设计一两个类帮助定义向导步骤。
最终,将有一个灵活的向导应用程序,提供非常容易修改步骤的顺序的能力,甚至添加一个步骤也相当简单。
HRWizard类
由于正收集的某些员工信息将被传递给其它部门去处理,因此在自已的类中放置从每个屏幕中获得的数据。
也需要一个监控向导步骤的类,同时考虑一个帮助使用ListMgr工作表中数据填充列表的类。
下表列出了每个类并描述了其功能。
表:
HRWizard应用程序类模块
类
描述
cPerson
包含新记录中的所有个人信息
cAddress
包含新记录中的所有地址信息
cEquipment
包含新记录中的所有设备信息
cAccess
包含新记录中的所有访问信息
cStep
包含向导每一步的配置值
cStepMgr
控制向导的操作及管理cStep对象的集合
cListMgr
控制用户窗体中填充组合框的列表
cHRData
从商业对象中将数据转移到数据库;将数据从数据库发送到商业对象
HRWizard商业对象
下面开始设计商业对象。
这些类存储每个对象的数据,包含每个对象的一些商业规则。
在工程中添加一个新的类模块并将其命名为cPerson,再添加另外三个类模块,分别将它们命名为cAddress、cEquipment和cAccess。
cPerson对象包含一个cAddress对象、cEquipment对象、一个cAccess对象。
要保持它们同步,对这四个商业对象类的每一个都添加一个ID属性。
在每个类中,添加下列模块级的声明:
Privatem_lngIDAsLong
PublicPropertyGetID()AsLong
ID=m_lngID
EndProperty
PublicPropertyLetID(newIDAsLong)
m_lngID=newID
EndProperty
现在,让我们集中开发cPerson类。
每个类实质上对应着先前我们设计的每一个界面。
在cPerson类中添加下列模块级变量声明:
Privatem_sFNameAsString
Privatem_sMidInitAsString
Privatem_sLNameAsString
Privatem_dtDOBAsDate
Privatem_sSSNAsString
Privatem_sJobTitleAsString
Privatem_sDepartmentAsString
Privatem_sEmailAsString
Privatem_oAddressAscAddress
Privatem_oEquipmentAscEquipment
Privatem_oAccessAscAccess
注意,除了从屏幕设计中的数据输入项外,还包括包含地址、设备和访问信息的对象。
这里首先要做的是初始化cPerson类,设置一些默认值。
在Class_Initialize事件中,添加下列代码:
PrivateSubClass_Initialize()
m_lngID=RandomNumber(100000,999999)
Setm_oAddress=NewcAddress
Setm_oEquipment=NewcEquipment
Setm_oAccess=NewcAccess
SetObjectIDs
EndSub
上述代码中,设置了私有的ID变量m_lngID为随机的6位数字,并初始化私有的商业对象变量。
然后调用私有的函数SetObjectIDs设置所有四个商业对象的ID值为相同的值。
添加下列代码到cPerson类中生成随机数字和同步ID字段:
PrivateFunctionRandomNumber(upperAsLong,lowerAsLong)AsLong
'生成一个介于upper和lower之间的随机数
Randomize
RandomNumber=Int((upper-lower+1)*Rnd+lower)
EndFunction
PrivateSubSetObjectIDs()
m_oAddress.ID=m_lngID
m_oEquipment.ID=m_lngID
m_oAccess.ID=m_lngID
EndSub
在IDPropertyLet函数中添加对上面的过程的调用。
这样,如果手工对ID字段赋值,那么所有的商业对象都获取这个新值。
最终的IDPropertyLet过程代码如下:
PublicPropertyLetID(newIDAsLong)
m_lngID=newID
SetObjectIDs'保持所有对象同步使用相同的ID
EndProperty
cPerson类的剩余部分非常直观。
最终的cPerson类的代码如下:
PropertyGetFName()AsString
FName=m_sFName
EndProperty
PropertyLetFName(newFNameAsString)
m_sFName=newFName
EndProperty
PropertyGetMidInit()AsString
MidInit=m_sMidInit
EndProperty
PropertyLetMidInit(newMidInitAsString)
m_sMidInit=newMidInit
EndProperty
PropertyGetLName()AsString
LName=m_sLName
EndProperty
PropertyLetLName(newLNameAsString)
m_sLName=newLName
EndProperty
PropertyGetDOB()AsDate
DOB=m_dtDOB
EndProperty
PropertyLetDOB(newDOBAsDate)
m_dtDOB=newDOB
EndProperty
PropertyGetSSN()AsString
SSN=m_sSSN
EndProperty
PropertyLetSSN(newSSNAsString)
m_sSSN=newSSN
EndProperty
PropertyGetJobTitle()AsString
JobTitle=m_sJobTitle
EndProperty
PropertyLetJobTitle(newJobTitleAsString)
m_sJobTitle=newJobTitle
EndProperty
PropertyGetDepartment()AsString
Department=m_sDepartment
EndProperty
PropertyLetDepartment(newDepartmentAsString)
m_sDepartment=newDepartment
EndProperty
PropertyGetEmail()AsString
Email=m_sEmail
EndProperty
PropertyLetEmail(newEmailAsString)
m_sEmail=newEmail
EndProperty
PropertyGetAddress()AscAddress
SetAddress=m_oAddress
EndProperty
PropertySetAddress(newAddressAscAddress)
Setm_oAddress=newAddress
EndProperty
PropertyGetEquipment()AscEquipment
SetEquipment=m_oEquipment
EndProperty
PropertySetEquipment(newEquipmentAscEquipment)
Setm_oEquipment=newEquipment
EndProperty
PropertyGetAccess()AscAccess
SetAccess=m_oAccess
EndProperty
PropertySetAccess(newAccessAscAccess)
Setm_oAccess=newAccess
EndProperty
至此,已经完成Person数据元素的添加,以及3个对象类属性。
同时,想要添加一个属性,返回员工的全名。
下面的代码在cPerson中添加只读的FullName属性:
PropertyGetFullName()AsString
DimsReturnAsString
DimblnMidInitAsBoolean
blnMidInit=Len(m_sMidInit&"")>0
IfblnMidInitThen
sReturn=m_sFName&""&m_sMidInit&""&m_sLName
Else
sReturn=m_sFName&""&m_sLName
EndIf
FullName=sReturn
EndProperty
这就是我们所需要的cPerson类。
下面列出其它3个类的代码。
cAddress类:
Privatem_lngIDAsLong
Privatem_sStreetAddressAsString
Privatem_sStreetAddress2AsString
Privatem_sCityAsString
Privatem_sStateAsString
Privatem_sZipCodeAsString
Privatem_sPhoneNumberAsString
Privatem_sCellPhoneAsString
PublicPropertyGetID()AsLong
ID=m_lngID
EndProperty
PublicPropertyLetID(newIDAsLong)
m_lngID=newID
EndProperty
PublicPropertyGetStreetAddress()AsString
StreetAddress=m_sStreetAddress
EndProperty
PublicPropertyLetStreetAddress(newAddressAsString)
m_sStreetAddress=newAddress
EndProperty
PublicPropertyGetStreetAddress2()AsString
StreetAddress2=m_sStreetAddress2
EndProperty
PublicPropertyLetStreetAddress2(newAddress2AsString)
m_sStreetAddress2=newAddress2
EndProperty
PublicPropertyGetCity()AsString
City=m_sCity
EndProperty
PublicPropertyLetCity(newCityAsString)
m_sCity=newCity
EndProperty
PublicPropertyGetState()AsString
State=m_sState
EndProperty
PublicPropertyLetState(newStateAsString)
m_sState=newState
EndProperty
PublicPropertyGetZipCode()AsString
ZipCode=m_sZipCode
EndProperty
PublicPropertyLetZipCode(newZipCodeAsString)
m_sZipCode=newZipCode
EndProperty
PublicPropertyGetPhoneNumber()AsString
PhoneNumber=m_sPhoneNumber
EndProperty
PublicPropertyLetPhoneNumber(newPhoneNumberAsString)
m_sPhoneNumber=newPhoneNumber
EndProperty
PublicPropertyGetCellPhone()AsString
CellPhone=m_sCellPhone
EndProperty
PublicPropertyLetCellPhone(newCellPhoneAsString)
m_sCellPhone=newCellPhone
EndProperty
cEquipment类:
Privatem_lngIDAsLong
Privatem_sPCTypeAsString
Privatem_sPhoneTypeAsString
Privatem_sLocationAsString
Privatem_sFaxYNAsString
PublicPropertyGetID()AsLong
ID=m_lngID
EndProperty
PublicPropertyLetID(newIDAsLong)
m_lngID=newID
EndProperty
PublicPropertyGetPCType()AsString
PCType=m_sPCType
EndProperty
PublicPropertyLetPCType(newPCTypeAsString)
m_sPCType=newPCType
EndProperty
PublicPropertyGetPhoneType()AsString
PhoneType=m_sPhoneType
EndProperty
PublicPropertyLetPhoneType(newPhoneTypeAsString)
m_sPhoneType=newPhoneType
EndProperty
PublicPropertyGetLocation()AsString
Location=m_sLocation
EndProperty
PublicPropertyLetLocation(newLocationAsString)
m_sLocation=newLocation
EndProperty
PublicPropertyGetFaxYN()AsString
FaxYN=m_sFaxYN
EndProperty
PublicPropertyLetFaxYN(newFaxYNAsString)
m_sFaxYN=newFaxYN
EndProperty
cAccess类:
Privatem_lngIDAsLong
Privatem_sBuildingAsString
Privatem_iNetworkLevelAsInteger
Privatem_sRemoteYNAsString
Privatem_sParkingSpotAsString
PublicPropertyGetID()AsLong
ID=m_lngID
EndProperty
PublicPropertyLetID(newIDAsLong)
m_lngID=newID
EndProperty
PublicPropertyGetBuilding()AsString
Building=m_sBuilding
EndProperty
PublicPropertyLetBuilding(newBuildingAsString)
m_sBuilding=newBuilding
EndProperty
PublicPropertyGetNetworkLevel()AsInteger
NetworkLevel=m_iNetworkLevel
EndProperty
PublicPropertyLetNetworkLevel(newNetworkLevelAsInteger)
m_iNetworkLevel=newNetworkLevel
EndProperty
PublicPropertyGetRemoteYN()AsString
RemoteYN=m_sRemoteYN
EndProperty
PublicPropertyLetRemoteYN(newRemoteYNAsString)
m_sRemoteYN=newRemoteYN
EndProperty
PublicPropertyGetParkingSpot()AsString
ParkingSpot=m_sParkingSpot
EndProperty
PublicPropertyLetParkingSpot(newParkingSpotAsString)
m_sParkingSpot=newParkingSpot
EndProperty
管理列表
在HRWizard用户窗体中输入的一些数据是通过组合框控件显示给用户的。
HRWizard工作簿文件包含一个名为ListMgr的工作表,其中包含每个列表的数据。
这些数据存储在ListMgr工作表的命名区域。
cListManager类包含的函数可以从这些命名区域中填充组合框,同时也有一个将列表绑定到VBACollection对象的方法。
插入一个新的类模块,将其命名为cListManager,在其中添加下面两个方法:
PublicSubBindListToRange(ListRangeNameAsString,TheComboAsMSForms.ComboBox)
TheCombo.RowSource=ListRangeName
EndSub
PublicSubBindListToCollection(TheCollectionAsCollection,TheComboAsMSForms.ComboBox)
DimiNumItemsAsInteger
DimiAsInteger
iNumItems=TheCollection.Count
Fori=1ToiNumItems
TheCombo.AddItemTheCollection(i)
Nexti
EndSub
BindListToRa