VBA在多个工作表上search值并给出总计
我有一个传统的电子表格,其中有团队中每个人的工作表。
工作表有多个列,我感兴趣的列是A和B,A有一个工作名称,B有一个人在这个工作上工作的总小时数。
在另一张表格(称为“合并”)中,我有列A,其中也有工作名称,列H列出所有项目人员总共需要工作的小时数。
目前,我有以下代码:
'Modified from: http://www.rondebruin.nl/win/s9/win006.htm Private Function Find_First(ByVal sht As Integer, ByVal cell As String) Dim FindString As String Dim Rng As Range FindString = Sheets(sht).Range(cell).value If Trim(FindString) <> "" Then With Sheets(sht).Range("A:A") Set Rng = .Find(What:=FindString, _ After:=.Cells(.Cells.Count), _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False) If Not Rng Is Nothing Then Find_First = Rng End If End With End If End Function Public Function getSummary(ByVal myCell As Range) Dim total As Integer For i = 1 To Sheets.Count ' Iterate over all the sheets If Sheets(i).Name = "Consolidation" Then ' If the sheet is "Consolidation" then skip to next element GoTo NextIteration End If Dim job As Range Dim value As Range Set job = Find_First(i, myCell) Set value = job.Offset(0, 1).value total = total + value NextIteration: Next getSummary = total End Function
我使用=getSummary(A3)
从列H3中调用它。 H3然后等于#VALUE !,我不知道为什么…正如你可以从代码告诉我,我不是VBA专家,我不知道从哪里开始,因为似乎没有很多debugging工具的方式…
更新 :感谢大卫和CodeJockey,我有几个function,完全按照我需要:
'Modified from: http://www.rondebruin.nl/win/s9/win006.htm Private Function FindFirst(ByVal sht As Integer, ByVal cell As String) As Range Dim FindString As String Dim Rng As Range FindString = Sheets("Consolidation").Range(cell).value If Trim(FindString) <> "" Then With Sheets(sht).Range("A:A") Set Rng = .Find(What:=FindString, _ After:=.Cells(.Cells.Count), _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False) If Not Rng Is Nothing Then Set FindFirst = Rng End If End With End If End Function Private Function getData(ByVal myCell As Range, ByVal offset As Integer) Dim total As Integer total = 0 For i = 1 To Sheets.Count ' Iterate over all the sheets If Sheets(i).Name = "Consolidation" Then ' If the sheet is "Consolidation" then skip to next element GoTo NextIteration End If Dim job As Range Dim value As String Set job = FindFirst(i, myCell.Address) If Not job Is Nothing Then value = job.offset(0, offset).value If Not IsEmpty(value) And IsNumeric(value) Then total = total + value End If End If NextIteration: Next getData = total End Function Function getBurnHours(ByVal myCell As Range) Application.Volatile getBurnHours = getData(myCell, 1) End Function Public Function getBurnDays(ByVal myCell As Range) Application.Volatile getBurnDays = getData(myCell, 2) End Function Public Function getActualHours(ByVal myCell As Range) Application.Volatile getActualHours = getData(myCell, 3) End Function Public Function getActualDays(ByVal myCell As Range) Application.Volatile getActualDays = getData(myCell, 4) End Function
myCell
是一个Range对象,但Find_First
函数Find_First
一个String参数。
所以你应该改变这个:
Set job = Find_First(i, myCell)
对此:
Set job = Find_First(i, myCell.Address)
您还需要更改return语句,以便返回值与job
variables(Range)中预期的数据type
相匹配,您需要在此作业中使用Set
关键字:
Set Find_First = Rng
或者,您需要将声明的job
types更改为Range对象以外的其他job
。 我不确定你期望返回什么,但是因为你的数据types都是怪人,所以很难推荐一个精确的解决scheme。
同样, Value
作为Range对象的声明也不能接受job.Offset(0, 1).Value
(它返回一个string),而不会引起不匹配的错误。 所以再一次,你需要改变这个variables的声明或改变对象的赋值。
否则,这可能是有用的:
函数Find_First(sht, cell)
返回“Rng”中的值,而不是对象本身。 要返回对象,请使用“Set”运算符。 请参阅下面的编辑:
If Not Rng Is Nothing Then Set Find_First = Rng End If
这是允许的,因为你的私人函数返回一个变体,而不是一个范围。 为了清楚起见,我也会改变这一点:
Private Function Find_First(ByVal sht As Integer, ByVal cell As String)
对此:
Private Function Find_First(ByVal sht As Integer, ByVal cell As String) as Range