前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Excel实战技巧66:创建向导样式的数据输入窗体5

Excel实战技巧66:创建向导样式的数据输入窗体5

作者头像
fanjy
发布2019-12-11 17:39:03
1.6K0
发布2019-12-11 17:39:03
举报
文章被收录于专栏:完美Excel完美Excel

到目前为止,我们已经完成了最艰难的工作。接下来,我们来编写用户窗体代码,将已完成的对象放进HRWizard用户窗体里并使这些对象工作。

编写HRWizard用户窗体代码

打开HRWizard用户窗体代码窗口,添加下列模块级的变量声明:

Dim m_oEmployee As cPerson

Dim m_oLM As cListManager

Dim m_oWizard As cStepManager

Dim m_colSteps As Collection

虽然我们创建了9个分开的类模块来运行我们的应用程序,但是许多类都是通过在声明部分列出来内部使用。使用cPeason类收集新员工的数据,使用cListManager类来填充HRWizard用户窗体中不同的组合框,使用cStepManager类决定何时且按什么顺序显示哪个界面,并控制导航命令按钮的可用性。最后,使用标准的VBA Collection对象,用于存储cStepManager对象的PageSettings集合。

初始化应用程序

在HRWizard用户窗体的Initialize事件中,将初始化自定义的对象并添加代码来设置向导、列表和显示用户窗体。

在UserForm_Initialize事件中添加下列代码:

Private Sub UserForm_Initialize()

Set m_oEmployee = New cPerson

Set m_oLM = New cListManager

Set m_oWizard = New cStepManager

InitWizard

InitLists

InitForm

End Sub

下面,创建三个Init函数,分别设置向导、列表管理器和用户窗体对象。

初始化向导

在用户窗体代码窗口添加新的过程,将其命名为InitWizard,并添加下列代码:

Private Sub InitWizard()

With m_oWizard

Set .Worksheet =Sheets("UFormConfig")

.NumberOfSettings = 3

Set m_colSteps =.PageSettings

Set .PreviousButton =Me.cmdPrevious

Set .NextButton =Me.cmdNext

.CurrentPage =MultiPage1.Value + 1

End With

End Sub

上述代码完成下列工作:

1.告诉cStepManager对象在哪里找到配置数据

Set .Worksheet = Sheets("UFormConfig")

2.告诉cStepManager对象获取数据的列数

.NumberOfSettings = 3

3.放置页设置到集合里

Set m_colSteps = .PageSettings

4.设置导航按钮

Set .PreviousButton = Me.cmdPrevious

Set .NextButton = Me.cmdNext

5.设置当前页

.CurrentPage = MultiPage1.Value + 1

因为多页控件的Page集合基于0,所以使用多页控件的Value属性加1来设置CurrentPage属性。

在初始化用户窗体之前,必须设置cStepManager对象,因为该用户窗体使用PageSettings集合来设置它自已。

初始化组合框

下一步是将组合框绑定到它们各自的列表。该列表被存储在ListMgr工作表中。

在用户窗体代码窗口添加新的过程InitLists,输入下列代码:

Private Sub InitLists()

With m_oLM

.BindListToRange "Departments", Me.cboDept

.BindListToRange "Locations", Me.cboLocation

.BindListToRange "NetworkLvl", Me.cboNetworkLvl

.BindListToRange "ParkingSpot", Me.cboParkingSpot

.BindListToRange "YN", Me.cboRemoteAccess

End With

End Sub

同样,上述代码也非常简单,它们为应用程序中的每个列表调用cListManager对象的BindListToRange方法,给组合框添加数据项。

初始化用户窗体

在设置应用程序中的最后一步是初始化用户窗体自身。添加一个名为InitForm的新过程,并输入下列代码:

Private Sub InitForm()

Dim iFirstPage As Integer

Dim i As Integer

Dim iPageCount As Integer

iFirstPage =m_colSteps("1").Order - 1

Me.MultiPage1.Value =iFirstPage

Me.MultiPage1.Pages((m_colSteps("1").Page) - 1).Caption =m_colSteps("1").Caption

m_oWizard.HandleControls

iPageCount =MultiPage1.Pages.Count

For i = 1 To iPageCount -1

MultiPage1.Pages(i).Visible = False

Next

End Sub

这里,设置多页控件的Value属性为PageSetting集合(m_colSteps)的项目(其键值为1),并设置其标题:

iFirstPage = m_colSteps("1").Order - 1

Me.MultiPage1.Value = iFirstPage

Me.MultiPage1.Pages((m_colSteps("1").Page) - 1).Caption =m_colSteps("1").Caption

注意,我们传递Order属性的值作为键值,这使得它非常容易去判断要移动至哪页。当设置多页控件的Value属性时,正使用相对应的值激活该页。在这里,该值为1。

然后调用m_oWizard对象的HandleControls方法初始化导航按钮为正确的设置:

m_oWizard.HandleControls

接下来,隐藏除第一页外的所有页:

iPageCount = MultiPage1.Pages.Count

For i = 1 To iPageCount - 1

MultiPage1.Pages(i).Visible = False

Next

注意,多页控件的Page集合是基于0的,因此通过以1开始循环计数器,保持该页面可见。此时,可以运行该用户窗体。

1.在VBE中,双击工程资源管理器窗口的用户窗体。

2.单击标准工具栏中的“运行子过程/用户窗体”按钮或者按F5键,如下图24所示。

图24

注意,下图25在选项卡中出现的标题,并且前一步按钮被禁用。

图25

再看看Department组合框,已经绑定了Departments命名区域到该组合框,如下图26所示。

图26

3、通过单击右上方的X按钮,停止用户窗体的运行。

给用户窗体添加导航

导航按钮要在向导应用程序中完成移动步骤的任务,但它们也需要具备放置每个界面中的数据到其在用户窗体的cPerson对象里的位置的能力。

在cmdNext_Click中添加下列代码:

Private Sub cmdNext_Click()

Dim iNext As Integer

StoreData

iNext =m_oWizard.NextPage

Me.MultiPage1.Value =m_colSteps(CStr(iNext)).Order - 1

Me.MultiPage1.Pages((m_colSteps(CStr(iNext)).Page)- 1).Caption = m_colSteps(CStr(iNext)).Caption

ShowNextPage"up"

End Sub

在向导中移到下一步之前首先需要做的是保留在当前用户窗体中输入的值。StoreData方法决定用户处于哪一步并基于该位置调用正确的存储方法,代码如下所示:

Private Sub StoreData()

Select Casem_oWizard.CurrentPage

Case 1

StorePerson

Case 2

StoreAddress

Case 3

StoreEquipment

Case 4

StoreAccess

End Select

End Sub

上述代码中的存储方法的代码如下:

Private Sub StorePerson()

With m_oEmployee

.FName = Me.txtFname.Value

.MidInit =Me.txtMidInit.Value

.LName =Me.txtLname.Value

IfLen(Me.txtDOB.Value & "") > 0 Then

.DOB =Me.txtDOB.Value

End If

.SSN =Me.txtSSN.Value

.Department = Me.cboDept.Text

.JobTitle =Me.txtJobTitle.Value

.Email =Me.txtEmail.Value

End With

End Sub

Private Sub StoreAddress()

With m_oEmployee.Address

.StreetAddress =Me.txtStreetAddr.Value

.StreetAddress2 =Me.txtStreetAddr2.Value

.City =Me.txtCity.Value

.State =Me.txtState.Value

.ZipCode =Me.txtZip.Value

.PhoneNumber =Me.txtPhone.Value

.CellPhone =Me.txtCell.Value

End With

End Sub

Private Sub StoreEquipment()

Dim opt As MSForms.OptionButton

Withm_oEmployee.Equipment

For Each opt In Me.fraPCType.Controls

If opt.Value =True Then

.PCType =opt.Caption

Exit For

End If

Next

For Each opt In Me.fraPhoneType.Controls

If opt.Value =True Then

.PhoneType =opt.Caption

Exit For

End If

Next

.Location =Me.cboLocation.Text

If Me.chkFaxYN = TrueThen

.FaxYN ="Y"

Else

.FaxYN ="N"

End If

End With

End Sub

Private Sub StoreAccess()

Dim opt As MSForms.OptionButton

With m_oEmployee.Access

If Len(Me.cboNetworkLvl.Text & "") > 0 Then

.NetworkLevel =CInt(Me.cboNetworkLvl.Text)

End If

.ParkingSpot =Me.cboParkingSpot.Text

.RemoteYN = Me.cboRemoteAccess.Text

For Each opt In Me.fraBuilding.Controls

If opt.Value =True Then

.Building =opt.Caption

Exit For

End If

Next

End With

End Sub

这段代码简单地从界面中接收数据,并将其放置在cPerson里的相应的对象中。

接下来,确定下一页。(记住,多页集合是基于0的,因此从Order属性中减1以获得下一页的值)

iNext = m_oWizard.NextPage

Me.MultiPage1.Value = m_colSteps(CStr(iNext)).Order - 1

Me.MultiPage1.Pages((m_colSteps(CStr(iNext)).Page) - 1).Caption =m_colSteps(CStr(iNext)).Caption

然后,调用ShowNextPage方法,告诉它我们想移动的方式:

ShowNextPage "up"

ShowNextPage方法的代码如下:

Private Sub ShowNextPage(Direction As String)

Dim iCurrPage As Integer

Dim iUpDown As Integer

iCurrPage =MultiPage1.Value

If LCase(Direction) ="up" Then

iUpDown = 1

Else

iUpDown = -1

End If

MultiPage1.Pages(iCurrPage + iUpDown).Visible = True

MultiPage1.Pages(iCurrPage).Visible = False

End Sub

这个方法查找CurrentPage属性的值,基于传递给该方法的Direction参数加或减1。

cmdPrevious按钮的Click事件看起来非常相似:

Private Sub cmdPrevious_Click()

Dim iPrevious As Integer

StoreData

iPrevious =m_oWizard.PreviousPage

Me.MultiPage1.Value =m_colSteps(CStr(iPrevious)).Order - 1

Me.MultiPage1.Pages((m_colSteps(CStr(iPrevious)).Page) - 1).Caption =m_colSteps(CStr(iPrevious)).Caption

ShowNextPage"down"

End Sub

唯一的差别是传递关键字down到ShowNextPage方法以便向用户移动到合适的方向。

下面,添加最后一个事件处理来帮助我们使用导航。无论何时改变多页控件中的页面,控件的Change事件被触发。我们使用事件去捕捉当前页面的值,并将其存储在m_oWizard对象的CurrentPage属性中。

添加下面的代码到MultiPage1控件的Change事件:

Private Sub MultiPage1_Change()

m_oWizard.CurrentPage =MultiPage1.Value + 1

End Sub

现在,让我们来试试导航的工作。

1.在设计视图下打开用户窗体,单击标准工具栏中的“运行子程序/用户窗体”按钮或按F5键。

2.启动用户窗体后,单击下一步按钮移动到向导中的第二步(已在配置工作表中定义),应该是Address界面。注意到两个导航按钮现在都能用了,如下图27所示。

图27

3.单击前一步按钮导航回到Personal界面,此时前一步按钮不再是活动的了。

4.单击下一步按钮直至最后一个界面(已在配置工作表中定义),应该是Access界面,此时下一步按钮不再能够使用,如下图28所示。

图28

5.通过单击右上方的X按钮,停止用户窗体的运行。

保存员工记录

至此,我们已经做了大量的工作,从自定义对象获得了一些完美干净的功能提供给用户窗体。唯一没有做的就是将数据保存到EmpData工作表。

一般来说,可以创建一个子过程,将其命名如SaveData(),将从cmdSave_Click事件中调用该程序,但是cHRData类已经具有了SaveEmployee方法。我们可以直接从cmdSave_Click中调用而不需要再创建保存函数。

在cmdSave_Click事件中插入下列代码:

Private Sub cmdSave_Click()

Dim oHRData As cHRData

Set oHRData = New cHRData

Set oHRData.Worksheet =Sheets("EmpData")

oHRData.SaveEmployee m_oEmployee

Set oHRData = Nothing

End Sub

在设置Worksheet属性之后,以便于cHRData对象知道在哪里保存数据,调用SaveEmployee方法,传递m_oEmployee对象,那里包含要保存的所有数据。

清理

我们几乎已经获得了一个完整的应用程序。下面让我们添加Cancel按钮的代码并在用户窗体的Terminate事件中放置清理代码。

在cmdCancel按钮的Click事件中添加下面的代码行:

Private Sub cmdCancel_Click()

Unload Me

End Sub

这行代码简单地卸载用户窗体而不保存任何数据。

现在我们清除HRWizard用户窗体使用的对象。在UserForm_Terminate事件处理中添加下列代码:

Private Sub UserForm_Terminate()

Set m_oEmployee = Nothing

Set m_oLM = Nothing

Set m_oWizard = Nothing

End Sub

下面再添加一个简单的函数用来打开向导窗体。在VBE中,添加一个标准模块,在其中添加下列代码:

Sub StartWizard()

HRWizard.Show

End Sub

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 完美Excel 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档