|
楼主 |
发表于 2009-7-10 17:33
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
第11部分 其他应用
技巧196 职工花名册
于 在实际工作中,往往需要一个花名册用于录入职工的各项信息,在需要时可以方便的进行查找、统计以方便日常工作。
使用Excel制作职工花名册可以方便的录入职工信息,对所录入的信息进行修改、筛选择等,制作步骤如下:
步骤1,新建工作簿,将Sheet1工作表名称修改为“花名册”,设置成如图所示的格式。
步骤2,在工作表的B列输入职工姓名,F列输入身份证号码,G列输入职称。
“部门”、“职务”及“备注”从工作表中的数据有效性中选择,在VBE中双击Sheet1表,在打开的代码窗口写入下面的代码:- #001 Private Sub Worksheet_SelectionChange(ByVal Target As Range)
- #002 Dim r As Integer
- #003 r = Sheet1.Range("B65536").End(xlUp).Row
- #004 With Target
- #005 If .Count = 1 And .Row > 5 And .Row <= r Then
- #006 Sheet1.Unprotect
- #007 Select Case .Column
- #008 Case 8
- #009 With .Validation
- #010 .Delete
- #011 .Add Type:=xlValidateList, _
- #012 AlertStyle:=xlValidAlertStop, _
- #013 Operator:=xlBetween, _
- #014 Formula1:="经理室,办公室,行政科,生技科,财务科," _
- #015 & "营业部,制水车间,污水厂,其他,安装公司,退休"
- #016 End With
- #017 Case 9
- #018 With .Validation
- #019 .Delete
- #020 .Add Type:=xlValidateList, _
- #021 AlertStyle:=xlValidAlertStop, _
- #022 Operator:=xlBetween, _
- #023 Formula1:="经理,副经理,支书,副支书,经理助理," _
- #024 & "中层正职,中层副职,总账会计,辅助会计," _
- #025 & "辅助会计,出纳会计,协理员,管理员,驾驶员," _
- #026 & "办事员,科档员,计量员,收费员,发货员," _
- #027 & "采购员,化验员,监察队员,班组长,拆表工," _
- #028 & "抄表工,勘估设计,预决算,校表工,换表工," _
- #029 & "机修工,电工,中控值班,制水工,安装工," _
- #030 & "外借,内退"
- #031 End With
- #032 Case 10
- #033 With .Validation
- #034 .Delete
- #035 .Add Type:=xlValidateList, _
- #036 AlertStyle:=xlValidAlertStop, _
- #037 Operator:=xlBetween, _
- #038 Formula1:="在职,内退,退休"
- #039 End With
- #040 End Select
- #041 Sheet1.Protect
- #042 End If
- #043 End With
- #044 End Sub
复制代码 代码解析:
工作表的SelectionChange事件过程,当选择工作表的H、I和J列时自动生成相应的数据有效性,请参阅技巧12-1。
“性别”、“出生年月”及“年龄”由输入的身份证号码自动生成,在Sheet1表的代码窗口写入下面的代码:- #001 Private Sub Worksheet_Change(ByVal Target As Range)
- #002 Sheet1.Unprotect
- #003 With Target
- #004 If .Count = 1 And .Row > 5 And .Column = 6 Then
- #005 If .Text <> "" Then
- #006 Application.EnableEvents = False
- #007 .Offset(0, -5).FormulaR1C1 = "=ROW()-5"
- #008 .Offset(0, -3) = IIf(Mid(.Text, 17, 1) Mod 2 = 0, "女", "男")
- #009 .Offset(0, -2) = Format(Mid(.Text, 7, 8), "#-00-00")
- #010 .Offset(0, -1).FormulaR1C1 = "=DATEDIF(TEXT(MID(RC[1],7,8),""#-00-00""),TODAY(),""y"")"
- #011 Application.EnableEvents = True
- #012 Else
- #013 Rows(.Row) = ""
- #014 End If
- #015 End If
- #016 End With
- #017 Sheet1.Protect
- #018 End Sub
复制代码 代码解析:
工作表的Change事件过程,当输入职工身份证号码后在工作表的C、D和E列自动生成相应的“性别”、“出生年月”及“年龄”。
第7行代码,在A列写入序号的公式。
第8行代码,根据身份证号码的最后第二位数在C列中写入性别。
第9行代码,根据身份证号码中的出生年月信息在D列中写入出生年月。
第10行代码,根据身份证号码中的出生年月信息在E列中写入判断年龄的公式,因为年龄是动态的,所以只能写入公式。
在工作表的H2、H3单元格中写入统计人员类别的公式。
步骤3,为了方便使用,在VBE窗口中单击菜单“插入”→“模块”,在打开的代码窗口写入下面的代码:- #001 Sub SectorSort()
- #002 Dim r As Integer
- #003 With Sheet1
- #004 .Unprotect
- #005 r = .Range("B65536").End(xlUp).Row
- #006 If MsgBox("是否按公司部门顺序进行排序?", 36) = 6 Then
- #007 .Range("A6:J" & r).Sort Key1:=.Range("H6"), _
- #008 Order1:=xlAscending, Key2:=Range("D6"), _
- #009 OrderCustom:=13
- #010 End If
- #011 .Protect
- #012 End With
- #013 End Sub
复制代码 代码解析:
SectorSort过程对职工花名册按部门进行排序。
第7行到第9行代码使用Sort方法对职工花名册进行排序,应用于Range对象的Sort方法对数据透视表、单元格区域或活动区域(如果指定区域仅包含一个单元格)进行排序,语法如下:
expression.Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)
其中Key1参数是可选的,指定第一个排序字段,本例中按部门进行排序。
Order1参数是可选的,在Key1参数中指定的字段或区域的排序顺序。
Key2参数是可选的,指定第二个排序字段,本例中按出生年月进行排序。
OrderCustom参数是可选的,是从 1 开始的整数,指定了在自定义排序顺序列表中的索引号。如果省略参数,则使用常规排序。本例中在工作簿中添加了自定义的部门序列,索引号为13,如图所示。
- #001 Sub AgeSort()
- #002 Dim r As Integer
- #003 Dim imsg As Integer
- #004 With Sheet1
- #005 r = .Range("B65536").End(xlUp).Row
- #006 imsg = MsgBox("选择[是]按升降序排序,选择[否]按降序排序", 3)
- #007 Select Case imsg
- #008 Case 6
- #009 .Unprotect
- #010 .Range("A6:J" & r).Sort Key1:=.Range("E6"), _
- #011 Order1:=xlAscending, Key2:=.Range("D6")
- #012 Case 7
- #013 .Unprotect
- #014 .Range("A6:J" & r).Sort Key1:=.Range("E6"), _
- #015 Order1:=xlDescending, Key2:=.Range("D6")
- #016 End Select
- #017 .Protect
- #018 End With
- #019 End Sub
复制代码 代码解析:
AgeSort过程对职工花名册依据年龄进行排序。
第10、11行代码,使用Sort方法对职工花名册按年龄进行升序排序,Sort方法的Order1参数排序顺序,可为表格所示的XlSortOrder 常量之一。
第14、15行代码,使用Sort方法对职工花名册按年龄进行降序排序。- #001 Sub Forshow()
- #002 Dim r As Integer
- #003 With Sheet1
- #004 .Unprotect
- #005 r = .Range("B65536").End(xlUp).Row
- #006 .Range("A6:J" & r).Sort Key1:=.Range("H6"), _
- #007 Order1:=xlAscending, Key2:=Range("D6"), _
- #008 OrderCustom:=13
- #009 .Protect
- #010 End With
- #011 UserForm1.Show
- #012 End Sub
复制代码 代码解析:
Forshow过程对职工花名册按部门进行排序后显示按部门进行筛选的窗体。- #001 Sub AgeSortForshow()
- #002 Dim r As Integer
- #003 With Sheet1
- #004 .Unprotect
- #005 r = .Range("B65536").End(xlUp).Row
- #006 .Range("A6:J" & r).Sort Key1:=.Range("E6"), _
- #007 Order1:=xlAscending, Key2:=.Range("D6")
- #008 .Protect
- #009 End With
- #010 UserForm2.Show
- #011 End Sub
复制代码 代码解析:
AgeSortForshow过程对职工花名册按年龄进行排序后显示按年龄进行筛选的窗体。
步骤4,在VBE窗口中单击菜单“插入”→“插入窗体”,在窗体中添加一个列表框控件和两个按钮按件,如图 所示。
双击窗体,在打开的代码窗口写入下面的代码:- #001 Private Sub UserForm_Initialize()
- #002 On Error Resume Next
- #003 Dim Col As New Collection
- #004 Dim rng As Range, arr
- #005 Dim i As Integer
- #006 For Each rng In Sheet1.Range("H6:H" & Sheet1.Range("B65536").End(xlUp).Row)
- #007 If Trim(rng) <> "" Then
- #008 Col.Add rng, key:=CStr(rng)
- #009 End If
- #010 Next
- #011 ReDim arr(1 To Col.Count)
- #012 For i = 1 To Col.Count
- #013 arr(i) = Col(i)
- #014 Next
- #015 With Me.ListBox1
- #016 .List = arr
- #017 .ListStyle = 1
- #018 .MultiSelect = 1
- #019 End With
- #020 End Sub
复制代码 代码解析:
窗体的Initialize事件过程,窗体显示时将部门名称加载到窗体的列表框中。
第6行到第14行代码,使用Add方法将工作表H列中的部门名称去除重复值。
第15行到第19行代码,将部门名称加载到窗体的列表框并将列表框设置为显示多重选择列表的列表框。窗体显示时如图所示。
双击窗体的“筛选”按钮写入下面的代码:- #001 Private Sub CommandButton1_Click()
- #002 Dim i As Integer
- #003 Dim r As Integer
- #004 Dim r2 As Integer
- #005 Sheet1.Unprotect
- #006 Sheet2.Unprotect
- #007 Application.ScreenUpdating = False
- #008 r2 = Sheet2.Range("B65536").End(xlUp).Row
- #009 If r2 > 5 Then
- #010 With Sheet2.Range("A6:J" & r2)
- #011 .ClearContents
- #012 .Borders.LineStyle = xlNone
- #013 End With
- #014 End If
- #015 r = Sheet1.Range("B65536").End(xlUp).Row
- #016 For i = 0 To ListBox1.ListCount - 1
- #017 If ListBox1.Selected(i) = True Then
- #018 Sheet1.Range("A5:J" & r).AutoFilter Field:=8, Criteria1:="=" & ListBox1.List(i)
- #019 With Sheet2
- #020 r2 = .Range("B65536").End(xlUp).Row
- #021 Sheet1.Range("A6:J" & r).SpecialCells(12).Copy
- #022 .Cells(r2 + 1, 1).PasteSpecial Paste:=xlPasteValues
- #023 Application.CutCopyMode = False
- #024 With .Range("A6:A" & .Range("B65536").End(xlUp).Row)
- #025 .FormulaR1C1 = "=ROW()-5"
- #026 .Value = .Value
- #027 End With
- #028 End With
- #029 End If
- #030 Next
- #031 With Sheet2
- #032 .Range("A6:J" & .Range("B65536").End(xlUp).Row).Borders.LineStyle = xlContinuous
- #033 Application.Goto Reference:=.Range("A2"), Scroll:=True
- #034 .Protect
- #035 End With
- #036 Sheet1.Range("A1:J" & r).AutoFilter
- #037 Sheet1.Protect
- #038 Unload Me
- #039 Application.ScreenUpdating = True
- #040 End Sub
复制代码 代码解析:
“筛选”按钮的单击过程,将窗体列表框中所选中的部门数据筛选后复制到工作表中。
第10行到第12行代码,删除工作表中原有的数据,去除边框线。
第16行到第29行代码,将窗体列表框中所选中的部门数据进行筛选后依次复制到工作表中。
其中第18行代码使用AutoFilter方法进行筛选。应用于Range对象的AutoFilter方法使用“自动筛选”筛选出一个列表,语法如下:
expression.AutoFilter(Field, Criteria1, Operator, Criteria2, VisibleDropDown)
参数Field是可选的,相对于作为筛选基准字段(从列表左侧开始,最左侧的字段为第一个字段)的偏移量。本例中设置为8,即指定工作表中的H列进行筛选。
参数Criteria1是可选的,筛选条件。本例中设置为窗体列表框中所选中的部门名称。
第32行代码,将筛选后的数据画上边框线。
步骤5,在VBE窗口中单击菜单“插入”→“插入窗体”,在窗体中添加一个框架控件和两个组合框按件,如图 所示。
双击窗体,在打开的代码窗口写入下面的代码:- #001 Private Sub UserForm_Initialize()
- #002 On Error Resume Next
- #003 Dim Col As New Collection
- #004 Dim rng As Range, arr
- #005 Dim i As Integer
- #006 For Each rng In Sheet1.Range("E6:E" & Sheet1.Range("B65536").End(xlUp).Row)
- #007 Col.Add rng, key:=CStr(rng)
- #008 Next
- #009 ReDim arr(1 To Col.Count)
- #010 For i = 1 To Col.Count
- #011 arr(i) = Col(i)
- #012 Next
- #013 Me.ComboBox1.List = arr
- #014 Me.ComboBox2.List = arr
- #015 End Sub
复制代码 代码解析:
窗体的Initialize事件过程,窗体显示时将所有的年龄加载到窗体的组合框中。
第6行到第12行代码,使用Add方法将工作表E列中的年龄去除重复值。
第13、14行代码,将年龄加载到窗体的组合框中。
双击窗体的“筛选”按钮写入下面的代码:- #001 Private Sub CommandButton1_Click()
- #002 Dim r As Integer
- #003 Dim r2 As Integer
- #004 Dim dInput As Double
- #005 If Me.ComboBox1.Value = "" Or Me.ComboBox2.Value = "" Then
- #006 MsgBox "请选择需要筛选的年龄!"
- #007 Exit Sub
- #008 End If
- #009 If Me.ComboBox1.Value > Me.ComboBox2.Value Then
- #010 MsgBox "开始年龄不能等结束年龄,请重新选择!"
- #011 Me.ComboBox1.ListIndex = -1
- #012 Me.ComboBox2.ListIndex = -1
- #013 Exit Sub
- #014 End If
- #015 Application.ScreenUpdating = False
- #016 With Sheet1
- #017 r = .Range("B65536").End(xlUp).Row
- #018 .Unprotect
- #019 .Range("A5:J" & r).AutoFilter Field:=5, Criteria1:=">=" & Me.ComboBox1.Value, Operator:=xlAnd, Criteria2:="<=" & Me.ComboBox2.Value
- #020 With Sheet2
- #021 .Unprotect
- #022 r2 = .Range("B65536").End(xlUp).Row
- #023 If r2 > 5 Then
- #024 With .Range("A6:J" & r2)
- #025 .ClearContents
- #026 .Borders.LineStyle = xlNone
- #027 End With
- #028 End If
- #029 Sheet1.Range("A6:J" & r).SpecialCells(12).Copy
- #030 .Cells(6, 1).PasteSpecial Paste:=xlPasteValues
- #031 Application.CutCopyMode = False
- #032 With .Range("A6:A" & .Range("B65536").End(xlUp).Row)
- #033 .FormulaR1C1 = "=ROW()-5"
- #034 .Value = .Value
- #035 End With
- #036 .Range("A6:J" & .Range("B65536").End(xlUp).Row).Borders.LineStyle = xlContinuous
- #037 Unload Me
- #038 Application.Goto Reference:=.Range("A3"), Scroll:=True
- #039 .Protect
- #040 End With
- #041 .Range("A1:J" & r).AutoFilter
- #042 .Protect
- #043 End With
- #044 Application.ScreenUpdating = True
- #045 End Sub
复制代码 代码解析:
“筛选”按钮的单击过程,将根据窗体组合框中所选中的年龄进行筛选后的数据复制到工作表中。
第5行到第8行代码,年龄不能为空。
第9行到第14行代码,开始年龄不能小于结束年龄。
第19行代码,使用AutoFilter方法进行筛选。将第一个筛选条件设置为开始年龄,第二个筛选条件设置为结束年龄。
第23行到第28行代码,删除工作表中原有的数据,去除边框线。
第29行到第35行代码,将筛选后的数据复制到工作表中。
第36行代码,将筛选后的数据画上边框线。
步骤6,为了方便使用,在工作表中单击菜单“视图”→“工具栏”→“窗体”,添加两个框架,在每个框架中添加两个单选框,将模块中的宏指定给单选框,如图所示。
步骤7,为了保存筛选后的数据,将工作簿的Sheet2表重命名为“筛选数据”,并设置成如图所示的格式。
步骤8,选择“花名册”表的B、F和G列第6行以下区域,去除其锁定属性后保护工作表,对“筛选数据”表进行保护。在工作表中单击菜单“工具”→“选项”,在显示的选项对话框的视图页中去除工作表的行号列标及网格线后保存关闭工作簿。
打开工作簿,在“花名册”表中输入职工姓名、身份证号及职称后“花名册”表如图所示。
对表中数据进行筛选,比如按部门中的“生技科”进行筛选后“筛选数据”表中如图所示。
|
|