這裏有兩個VBA解決方案。第一個是這樣的:
- 檢查工作表是否存在「合計」。創建它,如果它不
- 複印的第一行(A至Q)第一片的以「總計」
- 複印塊A2:Q33爲「總計」片材起始於第2行
- 重複對所有其他表,每次
第二個顯示瞭如何複製前做列數據的一些操作追加32行低:對於每一列其應用WorksheetFunction.Sum()
,但你可以替換成你想要的任何其他聚合函數使用。然後它將結果(每張紙一行)複製到「總計」表中。
這兩個解決方案都在工作簿中,您可以下載from this site。運行宏,並從顯示的選項列表中選擇合適的宏。您可以通過調用VBA編輯器來編輯代碼。
Sub aggregateRaw()
Dim thisSheet, newSheet As Worksheet
Dim sheetCount As Integer
Dim targetRange As Range
sheetCount = ActiveWorkbook.Sheets.Count
' add a new sheet at the end:
If Not worksheetExists("totals") Then
Set newSheet = ActiveWorkbook.Sheets.Add(after:=Sheets(sheetCount))
newSheet.Name = "totals"
Else
Set newSheet = ActiveWorkbook.Sheets("totals")
End If
Set targetRange = newSheet.[A1]
' if you want to clear the sheet before copying data, uncomment this line:
' newSheet.UsedRange.Delete
' assuming you want to copy the headers, and that they are the same
' on all sheets, you can copy them to the "totals" sheet like this:
ActiveWorkbook.Sheets(1).Range("1:1").Copy targetRange
Set targetRange = targetRange.Offset(1, 0) ' down a row
' copy blocks of data from A2 to Q33 into the "totals" sheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> newSheet.Name Then
ws.Range("A2", "Q33").Copy targetRange
Set targetRange = targetRange.Offset(32, 0) ' down 32 rows
End If
Next ws
End Sub
Sub aggregateTotal()
Dim thisSheet, newSheet As Worksheet
Dim sheetCount As Integer
Dim targetRange As Range
Dim columnToSum As Range
sheetCount = ActiveWorkbook.Sheets.Count
' add a new sheet at the end:
If Not worksheetExists("totals") Then
Set newSheet = ActiveWorkbook.Sheets.Add(after:=Sheets(sheetCount))
newSheet.Name = "totals"
Else
Set newSheet = Sheets("totals")
End If
' assuming you want to copy the headers, and that they are the same
' on all sheets, you can copy them to the "totals" sheet like this:
Set targetRange = newSheet.[A1]
ActiveWorkbook.Sheets(1).Range("A1:Q1").Copy targetRange
Set targetRange = targetRange.Offset(1, 0) ' down a row
For Each ws In ActiveWorkbook.Worksheets
' don't copy data from "total" sheet to "total" sheet...
If ws.Name <> newSheet.Name Then
' copy the month label
ws.[A2].Copy targetRange
' get the sum of the coluns:
Set columnToSum = ws.[B2:B33]
For colNum = 2 To 17 ' B to Q
targetRange.Offset(0, colNum - 1).Value = WorksheetFunction.Sum(columnToSum.Offset(0, colNum - 2))
Next colNum
Set targetRange = targetRange.Offset(1, 0) ' next row in output
End If
Next ws
End Sub
Function worksheetExists(wsName)
' adapted from http://www.mrexcel.com/forum/excel-questions/3228-visual-basic-applications-check-if-worksheet-exists.html
worksheetExists = False
On Error Resume Next
worksheetExists = (Sheets(wsName).Name <> "")
On Error GoTo 0
End Function
最終剪輯(?): 如果你想這個腳本來自動運行每次有人進行了更改工作簿,您可以通過添加代碼到工作簿捕捉SheetChange
事件。你這樣做如下:
- 打開Visual Basic編輯器()
- 在Project Explorer(畫面左側),展開的VBAProject上 「的ThisWorkbook」
- 單擊鼠標右鍵,並選擇「查看代碼」
- 在打開,複製/粘貼下面的代碼行窗口:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' handle errors gracefully:
On Error GoTo errorHandler
' turn off screen updating - no annoying "flashing"
Application.ScreenUpdating = False
' don't respond to events while we are updating:
Application.EnableEvents = False
' run the same sub as before:
aggregateRaw
' turn screen updating on again:
Application.ScreenUpdating = True
' turn event handling on again:
Application.EnableEvents = True
Exit Sub ' if we encountered no errors, we are now done.
errorHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
' you could add other code here... for example by uncommenting the next two lines
' MsgBox "Something is wrong ... " & Err.Description
' Err.Clear
End Sub
閱讀更仔細地(張貼的代碼快速位之後),我不知道你打算用的3行做什麼可能工作表。我認爲它將被複制到彙總表的第3行,但現在我看到你想把JUNE的第2行放在那裏。來自其他行的數據如何處理?你能澄清一下嗎? – Floris 2013-04-10 18:57:38
到目前爲止,我已經提出了一個解決方案,但它非常乏味和耗時,儘管結果是我正在尋找的。有人建議我輸入以下內容:「總計」工作表中每個相應單元格的'= SheetName!單元格'。這是一個瘋狂的工作量,但是它完成了我想要的工作,它將工作簿中所有電子表格上的所有數據合併到總計工作表中。 – Brandon 2013-04-11 13:30:51