在工作中,零星工程项目是最令人头疼的,又杂又乱,项目繁多且大小不一,一直不好管理。这几天,试着利用Excel做了一个简易的零星工程项目管理系统,以方便对零星工程项目的管理。当然,先试用,然后再作进一步的改进和完善。大家如果有兴趣,可以下载附件的示例,给我提提意见或建议。
(#1对于简单的数据库,Excel是一个好的选择。设计良好的Excel工作表和结构可以帮助很好地组织和管理数据,并制作报表)
设计数据输入工作表
下面是数据工作表,名为“工程清单”,共15列。

除序号外,其它列的信息为项目信息和跟踪信息。
考虑到查询的需要,当输入一个新项目后,有一些必填项,因此,在工作表中使用了条件格式,如果这些必填项未填写,该行将呈现红色,如下图所示。

只有当必填项填写完成,红色才消失。
条件格式公式如下:
=AND($A2<>“”,OR($E2=”",$G2=”",$I2=”",$K2=”",$M2=”",$N2=”"))
即当第1列不为空时,列E、列G、列I、列K、列M、列N必须要有输入。
(#2防错性设计。即利用Excel提供的功能提示用户必须的操作或不需要的操作)
同时,动态命名工作表中的列表数据。
名称:ProjectList
公式:=OFFSET(工程清单!$B$1,0,-1,COUNTA(工程清单!$B:$B),15)
这样,添加数据后,命名区域立即更新。
(#3动态命名。使用公式动态命名区域,可以保持使用工作表中最新的数据。)
设计查询工作表
在“工作查询”工作表中,选择相应的查询条件后,下方显示满足条件的所有数据记录。

黄色单元格区域可以选择条件。选择后,相应的记录在下方显示。
在这个工作表中,有5个命名区域:
SelSQ=工作查询!$B$3
SelMKS=工作查询!$C$3
SelWG=工作查询!$B$6
SelYS=工作查询!$C$6
SelEmployee=工作查询!$F$3
ExtractProjects=工作查询!$A$8:$O$8
其中,B3、C3、B6、C6都使用了简单的数据有效性,F3中的数据有效性使用了名称,即“人员列表”工作表中获取人员姓名(下文讲述)。
该工作表模块对应的代码为:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngCrit As Range
Set rngCrit = Nothing
Application.EnableEvents = False
On Error GoTo exitHandler
Select Case Target.Address
Case Range("SelSQ").Address
Set rngCrit = wksCrit.Range("CriteriaSQ")
Range("SelMKS").ClearContents
Range("SelWG").ClearContents
Range("SelYS").ClearContents
Range("SelEmployee").ClearContents
Case Range("SelMKS").Address
Set rngCrit = wksCrit.Range("CriteriaMKS")
Range("SelSQ").ClearContents
Range("SelWG").ClearContents
Range("SelYS").ClearContents
Range("SelEmployee").ClearContents
Case Range("SelWG").Address
Set rngCrit = wksCrit.Range("CriteriaWG")
Range("SelSQ").ClearContents
Range("SelMKS").ClearContents
Range("SelYS").ClearContents
Range("SelEmployee").ClearContents
Case Range("SelYS").Address
Set rngCrit = wksCrit.Range("CriteriaYS")
Range("SelSQ").ClearContents
Range("SelMKS").ClearContents
Range("SelWG").ClearContents
Range("SelEmployee").ClearContents
Case Range("SelEmployee").Address
Set rngCrit = wksCrit.Range("CriteriaEmployee")
Range("SelSQ").ClearContents
Range("SelMKS").ClearContents
Range("SelWG").ClearContents
Range("SelYS").ClearContents
End Select
If Not rngCrit Is Nothing Then
rngCrit.Cells(2, 1).Value = Target.Value
wksProjects.Range("ProjectsList").AdvancedFilter _
Action:=xlFilterCopy, _
CriteriaRange:=rngCrit, _
CopyToRange:=Range("ExtractProjects"), _
Unique:=False
End If
exitHandler:
Application.EnableEvents = True
Exit Sub
errHandler:
Resume exitHandler
End Sub
代码前段的Case语句表示,当选择其中一个命名区域时,将查询条件工作表(下文介绍)中对应的查询条件区域赋值给对象变量,将其它命名区域清空。
代码后段表示,将当前区域的值赋给相应的查询条件区域,然后利用该区域的值作为高级筛选的筛选条件,并将筛选后的结果复制到当前工作表指定区域。
(#4高级筛选。利用高级筛选获取所需要的数据)
设计查询条件工作表
每一个用于筛选的条件,都存放在“查询条件”工作表中。

这样,在“工作查询”工作表中选择相应的条件后,“查询条件”工作表中相应的值得到更新,并在高级筛选中应用。
“查询条件”工作表中命名的区域为:
CriteriaSQ=查询条件!$B$1:$B$2
CriteriaMKS=查询条件!$D$1:$D$2
CriteriaWG=查询条件!$F$1:$F$2
CriteriaYS=查询条件!$H$1:$H$2
CriteriaEmployee=查询条件!$J$1:$J$2
人员列表
在“人员列表”工作表中,使用数据透视表功能从工程清单中获取人员名单,并在筛选条件中使用。

在该工作表中,定义了动态名称用于获取最新的人员列表:
EmployeeList=OFFSET(人员列表!$B$3,1,0,COUNTA(人员列表!$B:$B)-COUNTA(人员列表!$B$1:$B$3),1)
同时,当工作簿刚打开时,以及切换“工程清单”工作表时,更新数据透视表,以获取最新的数据:
Private Sub Workbook_Open()
Dim pt As PivotTable
For Each pt In wksLists.PivotTables
pt.RefreshTable
Next pt
End Sub
Private Sub Worksheet_Deactivate()
Dim pt As PivotTable
For Each pt In wksLists.PivotTables
pt.RefreshTable
Next pt
End Sub
(#5数据透视表。使用数据透视表可以容易地获得所需要的数据)
完整的示例
“工程清单”工作表用于输入数据,“工作查询”工作表用于查询,以便了解工作实施进展情况。“查询条件”和“人员列表”工作表不需要做任何操作。
示例下载
应用演示
注:本示例的灵感来源于http://blog.contextures.com中的文章《Create a Movie Collection Database in Excel》。