下面,創(chuàng)建一個(gè)簡(jiǎn)單的用戶(hù)窗體,,用于輸入“入職員工信息”數(shù)據(jù),。
設(shè)計(jì)用戶(hù)窗體
下表是個(gè)簡(jiǎn)單的“入職員工信息”數(shù)據(jù)庫(kù),用戶(hù)窗體用于收集信息并將數(shù)據(jù)信息保存到該數(shù)據(jù)庫(kù)中,。
打開(kāi)VBE,,插入用戶(hù)窗體,默認(rèn)名為UserForm1,。按下表在用戶(hù)窗體中添加控件并設(shè)置屬性,。
完成的用戶(hù)窗體如下圖所示。
編寫(xiě)代碼
1 編寫(xiě)找到數(shù)據(jù)庫(kù)工作表中下一個(gè)空白行的代碼
在VBE中,,插入一個(gè)類(lèi)模塊,,并命名為cExcelUtils,輸入下列代碼:
Function FindEmptyRow(ws As Worksheet) As Long Dim lngReturn As Long lngReturn = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row FindEmptyRow = lngReturn End Function
2 編寫(xiě)代碼以包含每個(gè)員工信息的值,,以及存儲(chǔ)數(shù)據(jù)庫(kù)工作表的位置,,將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)
插入一個(gè)類(lèi)模塊,并命名為cEmployeeInfo,,添加下面的代碼在模塊的聲明部分:
Private m_lngID As Long Private m_strName As String Private m_strSchool As String Private m_blnAbility As Boolean Private m_blnObey As Boolean Private m_xlWksht As Worksheet Private m_oXL As cExcelUtils
前5個(gè)變量是我們?cè)谟脩?hù)窗體中要輸入的數(shù)據(jù),,以及從數(shù)據(jù)庫(kù)工作表中產(chǎn)生的ID字段。變量m_xlWksht包含數(shù)據(jù)庫(kù)工作表的位置,。變量m_oXL決定在哪里放置新數(shù)據(jù)。
首先,,添加數(shù)據(jù)屬性,。
Property Get ID() As Long ID = m_lngID End Property Property Get Name() As String Name = m_strName End Property Property Let Name(newName As String) m_strName = newName End Property Property Get School() As String School = m_strSchool End Property Property Let School(newSchool As String) m_strSchool = newSchool End Property Property Get Ability() As Boolean Ability = m_blnAbility End Property Property Let Ability(newAbility As Boolean) m_blnAbility = newAbility End Property Property Get Obey() As Boolean Obey = m_blnObey End Property Property Let Obey(newObey As Boolean) m_blnObey = newObey End Property Property Get DBWorkSheet() As Worksheet Set DBWorkSheet = m_xlWksht End Property Property Set DBWorkSheet(newSheet As Worksheet) Set m_xlWksht = newSheet End Property
注意,ID屬性沒(méi)有Property Let方法,,因此該屬性是只讀的,。
下面,添加GetNextID方法找到最后一行,,從第一列中獲取值,,然后增加1,,以此來(lái)設(shè)置ID屬性的值。
Public Function GetNextID() As Long Dim lngReturn As Long lngReturn = m_xlWksht.Cells(Rows.Count, 1).End(xlUp).Value + 1 m_lngID = lngReturn '設(shè)置ID屬性 GetNextID = lngReturn End Function
接下來(lái),,添加初始化和清除代碼:
Private Sub Class_Initialize() Set m_oXL = New cExcelUtils End Sub Private Sub Class_Terminate() Set m_oXL = Nothing End Sub
再繼續(xù)完善該類(lèi)的功能,。先添加一些驗(yàn)證代碼。如果Name屬性和School屬性沒(méi)有數(shù)據(jù)的話(huà),,則不會(huì)保存記錄,。
Public Function ValidateData() As Boolean Dim blnReturn As Boolean If (Len(Me.Name & "") * Len(Me.School & "")) = 0 Then blnReturn = False Else blnReturn = True End If ValidateData = blnReturn End Function
通過(guò)文本值的長(zhǎng)度相乘,能夠決定是否填充數(shù)據(jù),。
接下來(lái),,編寫(xiě)保存功能的代碼。需要知道下一個(gè)可用行的行號(hào)為數(shù)據(jù)輸入,,需要知道該行所在的工作表,,并且如果沒(méi)有錯(cuò)誤,返回True,。
Public Function Save() As Boolean Dim lngNewRowNum As Long Dim blnReturn As Boolean If m_xlWksht Is Nothing Then blnReturn = False GoTo Exit_Function End If lngNewRowNum = m_oXL.FindEmptyRow(m_xlWksht) With m_xlWksht .Cells(lngNewRowNum, 1).Value = Me.ID .Cells(lngNewRowNum, 2).Value = Me.Name .Cells(lngNewRowNum, 3).Value = Me.School .Cells(lngNewRowNum, 4).Value = Me.Ability .Cells(lngNewRowNum, 5).Value = Me.Obey End With If Err.Number = 0 Then blnReturn = True End If Exit_Function: Save = blnReturn Exit Function End Function
代碼首先檢查以確保工作表對(duì)象存在,,如果不存在則返回False并退出函數(shù)。接下來(lái),,從cExcelUtils對(duì)象中獲取空行位置,。然后,使用代表數(shù)據(jù)庫(kù)工作表的m_xlWksht變量,,使用從類(lèi)屬性中的數(shù)據(jù)填充每列,。最后,檢查沒(méi)有發(fā)生錯(cuò)誤,,設(shè)置返回值為T(mén)rue,,然后退出函數(shù)。
這就是cEmployeeInfo類(lèi),,包含從用戶(hù)窗體中的輸入值,,為任何新記錄找到下一個(gè)ID值,保存數(shù)據(jù)到工作表中下一個(gè)空行,。
編寫(xiě)用戶(hù)窗體代碼
在用戶(hù)窗體代碼模塊中添加下列模塊級(jí)變量:
Private m_oEmployeeInfo As cEmployeeInfo Private m_blnSaved As Boolean
變量m_blnSaved存儲(chǔ)從m_oEmployeeInfo對(duì)象的Save方法中返回的值,。下面,編寫(xiě)用戶(hù)窗體初始化和中止事件代碼:
Private Sub UserForm_Initialize() Set m_oEmployeeInfo = New cEmployeeInfo Set m_oEmployeeInfo.DBWorkSheet = Sheets("入職員工信息") m_oEmployeeInfo.GetNextID lblID.Caption = m_oEmployeeInfo.ID m_blnSaved = False ClearForm End Sub Private Sub UserForm_Terminate() Set m_oEmployeeInfo = Nothing End Sub
在用戶(hù)窗體初始化時(shí),,實(shí)例化oEmployeeInfo對(duì)象,,然后設(shè)置DBWorksheet屬性。然后,,獲取下一個(gè)可用的ID號(hào)并將其放置到標(biāo)簽中,。也清除了窗體中的控件值。
Private Sub ClearForm() Me.txtName.Value = "" Me.txtSchool.Value = "" Me.chkAbility.Value = False Me.chkObey.Value = False End Sub
用戶(hù)窗體中有三個(gè)命令按鈕:一個(gè)用于保存輸入的數(shù)據(jù),一個(gè)用于清除用戶(hù)窗體數(shù)據(jù)并添加新記錄,,一個(gè)用于取消數(shù)據(jù)輸入操作并且不保存數(shù)據(jù)而關(guān)閉用戶(hù)窗體,。
“保存”按鈕應(yīng)該執(zhí)行下列功能:
- 發(fā)送數(shù)據(jù)到cEmployeeInfo類(lèi)
- 驗(yàn)收數(shù)據(jù),如果數(shù)據(jù)無(wú)效則返回一條消息
- 如果數(shù)據(jù)有效則保存數(shù)據(jù),,并且如果保存成功則返回一條消息
- 保存后清除用戶(hù)窗體數(shù)據(jù),,并重設(shè)保存標(biāo)志
代碼如下:
Private Sub cmdSave_Click() With m_oEmployeeInfo .Name = txtName.Text .School = txtSchool.Text .Ability = chkAbility.Value .Obey = chkObey.Value End With If Not m_oEmployeeInfo.ValidateData Then MsgBox "姓名和畢業(yè)院校必填", vbOKOnly, "不能保存" Exit Sub Else m_blnSaved = m_oEmployeeInfo.Save End If DoAfterSave m_blnSaved End Sub
過(guò)程DoAfterSave用于執(zhí)行清理。
Private Sub DoAfterSave(success As Boolean) If success Then ClearForm lblID.Caption = m_oEmployeeInfo.GetNextID MsgBox "記錄已保存" Else MsgBox "沒(méi)有保存記錄" End If m_blnSaved = False '重設(shè)標(biāo)志 End Sub
“新建”按鈕的代碼如下,,在新建之前,,檢查文本字段看用戶(hù)窗體中是否有任何數(shù)據(jù):
Private Sub cmdNew_Click() '為新記錄設(shè)置窗體 Dim iAnswer As Integer '檢查當(dāng)前記錄是否被保存 If Not m_blnSaved Then '是否有輸入的文本沒(méi)有被保存 If (Len(Me.txtName.Value & "") + Len(Me.txtSchool.Value & "")) <> 0 Then iAnswer = MsgBox("有沒(méi)有保存的數(shù)據(jù),想繼續(xù)嗎?", vbYesNo, "沒(méi)有保存數(shù)據(jù)") If iAnswer = vbYes Then ClearForm End If Else ClearForm End If End If End Sub
“取消”按鈕用來(lái)清除用戶(hù)窗體并關(guān)閉該用戶(hù)窗體:
Private Sub cmdCancel_Click() ClearForm Unload UserForm1 End Sub
現(xiàn)在,運(yùn)行用戶(hù)窗體來(lái)看看效果,。
如上圖所示,,當(dāng)“入職員工信息”用戶(hù)窗體顯示后,ID顯示為102,,而表中最后一行的ID值為101,,第3行為可用的數(shù)據(jù)輸入行。
現(xiàn)在,,可以測(cè)試代碼,,在“姓名”文本框中輸入信息,而讓“畢業(yè)院校”留空,,單擊“保存”按鈕,,此時(shí)會(huì)彈出消息提示框,如下圖所示,。
輸入“畢業(yè)院校”信息,,選擇必要的復(fù)選框,單擊“保存”,。此時(shí),,顯示保存成功的消息框,第3行已經(jīng)包含了剛才在用戶(hù)窗體中輸入的數(shù)據(jù),。注意到,,用戶(hù)窗體中的ID號(hào)現(xiàn)在已更新,以便輸入下一條記錄,。
再測(cè)試“新建”按鈕,。單擊“新建”按鈕,用戶(hù)窗體中除ID號(hào)外都為空,,什么也沒(méi)有發(fā)生,。然而,如果你選擇了復(fù)選框,,再單擊該按鈕,會(huì)清除復(fù)選框的選擇,。如果輸入了姓名,,而單擊“新建”按鈕,,將會(huì)收到一條警告數(shù)據(jù)沒(méi)有保存的消息,如下圖所示,。
如果單擊“否”,,將返回到用戶(hù)窗體而不會(huì)有任何變化;如果單擊“是”,,將清除用戶(hù)窗體中的數(shù)據(jù),,以便輸入新數(shù)據(jù)。
至此,,一個(gè)簡(jiǎn)單的數(shù)據(jù)輸入窗體已經(jīng)完成,。這里使用了類(lèi)模塊技術(shù)。