I need to calculate the average of a certain range (“C2:C11”) from several worksheets into a new worksheet. The function should still work if a new sheet is added and data is entered into the specified range.
So far I have this
….
Sheets.Add
Dim myavg As Collection
Set myavg = New Collection
For Each wsheet In Worksheets
myavg.Add wsheet.Range("B2:B11")
Next
For i = 1 To myavg.Count
avg1 = Application.WorksheetFunction.Average(Range("B2:B11"))
Next
curColumn = 5
curRow = 4
For i = 1 To myavg.Count
ActiveSheet.Cells(curRow, curColumn).Value = avg1
curRow = curRow + 1
Next
…
It returns one number into the desired range of the new sheet and its not accurate
Please help me understand what I am doing wrong.
Thank you in advance.
Putting aside whether or not a
Collectionis a good idea for this task, lets examine your code:General
You may have already done this, but it warrents repeating
Use
Option Explicitand decalre all your variablesYour Code
This adds a new
Worksheetto the activeWorkbook, and puts it before the currently active sheet, then activates the new sheet.Problems:
You are relying on the default behaviour to get a new
Worksheet, you can’t be sure where the new sheet is located, and you have no reference to it.Suggestions:
Get a reference to a workbook object and use that throughout your code
Control what, where and how you add to the workbook
Your Code
This creates a
CollectionofRange‘s, from everyWorksheetin the book, including the one we just created. I’m guessing you don’t want to include that one. For ease of maintenance you should create a variable to hold the range and use that throughout the code.Lets apply the above
Your Code
Problems:
You are iterating over the
Collectionbut not referencing it in the loop. Each time through you calculateavg1and then overwrite it on the next loop.Each time through the loop you calculate the average of a range on the Active Sheet (which will be the blank new sheet just added)
Suggestions:
Jumping ahead, it looks like you want to list the averages on the new sheet, one per sheet on successive rows. So lets store the averages in an array to be put on the summary sheet later. Note that if any of the
Range‘s are empty,Averagewill cause an error.Your Code
Problems:
This code simply puts the last calculated value of
avg1onto successive rowsPutting the result onto the new sheet: having collected the averages into an array, lets put that onto the sheet
Whats not delt with so far is
Error Handling. There are many ways code can go wrong, so it’s wise to includeError Handlingin your code. Eg what if there was already a sheet named “Summary”? What ifAveragereturns an error?Turning to whether this is a good method, it should be clear that having created an array to hold the results, that array could be populated in the pass through the workbook.
Something like this
This code may still have problems, depending on your exact requirements (eg if “Summary” sheets already exists, this will process it in the average loop)