View Full Version : Solved: Rolling average
Northender
09-17-2007, 06:29 AM
I was hoping somebody would be able to help me get started on converting some excel formula into VBA. I have a spreadsheet that is updated from various other workbooks with usage data on a daily basis. This is done via a vba button. What I would like is for this button to also update the moving average for each line. I have wrote the formula for this, but would really like to consolidate into one cell that is updated for each line. Problem is I dont know where to start to convert this.
 
Please see attached sample sheet
 
Thanks
Bob Phillips
09-17-2007, 08:18 AM
Private Sub Worksheet_Change(ByVal Target As Range)
Const WS_RANGE As String = "2:10"     '<== change to suit
Dim mpSummary As Long
Dim mpLastRow As Long
Dim mpDataCol As Long
Dim mpSum As Double
Dim mpCount As Long
Dim i As Long
    On Error GoTo ws_exit
    Application.EnableEvents = False
    If Not Intersect(Target, Me.Range(WS_RANGE)) Is Nothing Then
        With Target
            If .Column > 3 Then
                mpLastRow = Me.Cells(Me.Rows.Count, "A").End(xlUp).Row
                On Error Resume Next
                mpSummary = Application.Match(Me.Cells(.Row, "A"), Me.Range("A14:A" & mpLastRow), 0)
                On Error GoTo 0
                If mpSummary = 0 Then
                    mpSummary = mpLastRow + 1
                    Me.Rows(mpSummary).Insert
                    Me.Cells(mpSummary, "A").Value = Me.Cells(.Row, "A").Value
                    With Me.Range("B" & mpSummary).Resize(1, 6)
                        .Borders(xlDiagonalDown).LineStyle = xlNone
                        .Borders(xlDiagonalUp).LineStyle = xlNone
                        With .Borders(xlEdgeLeft)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                        .Borders(xlEdgeTop).LineStyle = xlNone
                        With .Borders(xlEdgeBottom)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                        With .Borders(xlEdgeRight)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                    End With
                    With Me.Range("B" & mpSummary)
                        .Borders(xlInsideVertical).LineStyle = xlNone
                        .Borders(xlDiagonalDown).LineStyle = xlNone
                        .Borders(xlDiagonalUp).LineStyle = xlNone
                        With Selection.Borders(xlEdgeLeft)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                        .Borders(xlEdgeTop).LineStyle = xlNone
                        With .Borders(xlEdgeBottom)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                        With .Borders(xlEdgeRight)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = xlAutomatic
                        End With
                    End With
                    mpSummary = mpSummary - 13
                End If
                mpDataCol = Me.Range("A" & .Row).End(xlToRight).Column
                Me.Cells(mpSummary + 13, "B").Value = mpDataCol - 3
                If mpDataCol - 4 < 4 Then mpDataCol = 8
                mpSum = 0: mpCount = 0
                For i = 1 To 5
                    Me.Cells(mpSummary + 13, i + 2).Value = Me.Cells(.Row, mpDataCol - i + 1).Value
                    mpSum = mpSum + Me.Cells(.Row, mpDataCol - i + 1).Value
                    If Me.Cells(.Row, mpDataCol - i + 1).Value > 0 Then mpCount = mpCount + 1
                Next i
                Me.Cells(mpSummary + 13, "I").Value = Round(mpSum / mpCount, 0)
            End If
        End With
    End If
ws_exit:
    Application.EnableEvents = True
End Sub
Private Sub Latest5(RowNum As Long)
    
End Sub
This is worksheet event code, which means that it needs to be
placed in the appropriate worksheet code module, not a standard
code module. To do this, right-click on the sheet tab, select
the View Code option from the menu, and paste the code in.
Northender
09-18-2007, 04:03 AM
xld,
 
Thankyou for your reply. Unfortunately I may not have made myself clear enough in my original post, for this I apologize. I have tried to work through your code to extract what I need to make it work but dont seem to be able to do this correctly. To clarify what it is I am trying to do.
 
In my sheet that I attached I have information that runs in rows 2 to 10 and along columns D to AI. This is updated by pressing a button and being extracted from various workbooks. What I then want to happen is for AJ to be updated with the average from the last five days figures ( >0 ). I know the formulas to do this, as layed out in the lower section. I dont want to place all these columns at the end to do the calculations, rather a code to carry out the calculation and then drop the answer in. Ideally I want to place this code at the end of the extraction process.
 
I apologize if I have wasted your time with this, although I have learned a bit from reading the code, just seems not quite enough to solve the problem.
Bob Phillips
09-18-2007, 04:24 AM
Public Sub ProcessData()
Dim mpLastRow As Long
Dim mpDataCol As Long
Dim mpSum As Double
Dim mpCount As Long
Dim i As Long, j As Long
     
    
    With ActiveSheet
    
        mpLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        
        For i = 2 To mpLastRow
        
            If .Cells(i, "D").Value <> "" Then
                mpDataCol = .Range("A" & i).End(xlToRight).Column
                .Cells(i, "AJ").Value = mpDataCol - 3
                If mpDataCol - 4 < 4 Then mpDataCol = 8
                mpSum = 0: mpCount = 0
                For j = 1 To 5
                    .Cells(i, 36 + j).Value = .Cells(i, mpDataCol - j + 1).Value
                    mpSum = mpSum + .Cells(i, mpDataCol - j + 1).Value
                    If .Cells(i, mpDataCol - j + 1).Value > 0 Then mpCount = mpCount + 1
                Next j
                .Cells(i, "AP").Value = Round(mpSum / mpCount, 0)
            End If
        Next i
        .Range("AJ2:AO" & mpLastRow).BorderAround Weight:=xlThin
        .Range("AJ2:AJ" & mpLastRow).BorderAround Weight:=xlThin
    End With
     
End Sub
Northender
09-18-2007, 05:32 AM
Thanks for your help with this, hopefully just one more question...
 
 Next j 
.Cells(i, "AP").Value = Round(mpSum / mpCount, 0) 
End If 
 
Can you just help with if this is an error. I have just come across a line with all zero's in, which causes an overflow error in the script.
Bob Phillips
09-18-2007, 05:50 AM
Replace that line with
                If mpCount = 0 Then
                    .Cells(i, "AP").Value = 0
                Else
                    .Cells(i, "AP").Value = Round(mpSum / mpCount, 0)
                End If
Northender
09-18-2007, 06:03 AM
:bow: Thanks for your help with is, much appreciated</IMG>
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.