I have written some VBA to sum the values across columns in a row. I have found however that when i run the code it receives a type mismatch error on random rows and i cannot figure out why. When i delete all other columns except from the four that are to be added it suddenly does not have this error?
I've also noticed that for some reason it does not add the "serving player backhand" column value as it should and i can't figure out why.
Sub sumShotsInRally()
'Set rawData sheet as active
Dim sht1 As Worksheet
Set sht1 = Sheets("Input")
sht1.Activate
'Find the Columns to Add
Dim serverForehandColNum As Integer
serverForehandColNum = ActiveSheet.Rows(1).Find(what:="Serving player forehand", lookat:=xlWhole).Column
Dim serverBackhandColNum As Integer
serverBackhandColNum = ActiveSheet.Rows(1).Find(what:="Serving player backhand", lookat:=xlWhole).Column
Dim returnerForehandColNum As Integer
returnerForehandColNum = ActiveSheet.Rows(1).Find(what:="Returning player forehand", lookat:=xlWhole).Column
Dim returnerBackhandColNum As Integer
returnerBackhandColNum = ActiveSheet.Rows(1).Find(what:="Returning player backhand", lookat:=xlWhole).Column
'Insert two new columns for the x and y
ActiveSheet.Columns(serverForehandColNum + 1).Insert
' Add New col headings
ActiveSheet.Cells(1, serverForehandColNum + 1).Value = "Rally Count"
Dim rallyCountColNum As Integer
rallyCountColNum = ActiveSheet.Rows(1).Find(what:="Rally Count", lookat:=xlWhole).Column
'Split the cell values
'Define the range to iterate over as the used range of the found column
Dim SForehandRange As Range
Dim SBackhandRange As Range
Dim RForehandRange As Range
Dim RBackhandRange As Range
Dim rallyRange As Range
With ActiveSheet
Set SForehandRange = .Range(.Cells(2, serverForehandColNum), .Cells(.UsedRange.Rows.Count, serverForehandColNum))
Set SBackhandRange = .Range(.Cells(2, serverBackhandColNum), .Cells(.UsedRange.Rows.Count, serverBackhandColNum))
Set RForehandRange = .Range(.Cells(2, returnerForehandColNum), .Cells(.UsedRange.Rows.Count, returnerForehandColNum))
Set RBackhandRange = .Range(.Cells(2, returnerBackhandColNum), .Cells(.UsedRange.Rows.Count, returnerBackhandColNum))
Set rallyRange = .Range(.Cells(2, rallyCountColNum), .Cells(.UsedRange.Rows.Count, rallyCountColNum))
End With
Dim results()
'You redimension the results array to the number of entries in your table
ReDim results(1 To SForehandRange.Rows.Count)
'You loop over your table and sum the values from count and restocked
For i = 1 To SForehandRange.Rows.Count
rallyRange(i, 1).Value = SForehandRange(i, 1).Value + SBackhandRange(i, 1).Value + RForehandRange(i, 1).Value + RBackhandRange(i, 1).Value
'results(i) = SForehandRange(i, 1) + SBackhandRange(i, 1) + RForehandRange(i, 1) + RBackhandRange(i, 1)
Next i
'You write the array to the range count and delete the values in restocjed
'rallyRange = Application.Transpose(results)
End Sub
A sample of the table:
+------------------+----------+----------+-------------------+-------------------+------------------+------------+--------------------+-------------------+-------------------+-------------+------------------+------------+------------+--------------------+------------+-----------------+--------------+--------------+-----------+-----------+-----------+---------------+----------------+-----------------+--------------------+-------------------+-------------+----------------------+-----------------------+------------------------+---------------------+---------------------+----------------------+-----------------------+--------------------+---------------+-------------------+--------------+-----------+---------------------+--------------+-------------+---------------------------+-------------------------+---------------+---------------------+----------------------+-----------------------+--------------------+--------------+----------------------+-----------------------+------------------------+---------------------+---------------+---------------------+---------------------------+-------------------------+-----------------------+
| Name | Position | Duration | 1st serve outcome | 1stReturnLocation | 1stServeLocation | 1stServeXY | 2nd return outcome | 2nd return stroke | 2nd serve outcome | 2ndReturnXY | 2ndServeLocation | 2ndServeXY | Date | Final shot outcome | Game score | Opponent player | Point score | Point won by | S/R | Set score | Side | Tagged player | Tiebreak score | Tournament name | 1st return outcome | 1st return stroke | 1stReturnXY | 2nd return+1 outcome | 2nd return+1 position | 2nd return+1 situation | 2nd return+1 stroke | 2nd serve+1 outcome | 2nd serve+1 position | 2nd serve+1 situation | 2nd serve+1 stroke | 2ndReturn+1XY | 2ndReturnLocation | 2ndServe+1XY | Final hit | Final shot position | Final stroke | FinalShotXY | Returning player forehand | Serving player forehand | Type | 1st serve+1 outcome | 1st serve+1 position | 1st serve+1 situation | 1st serve+1 stroke | 1stServe+1XY | 1st return+1 outcome | 1st return+1 position | 1st return+1 situation | 1st return+1 stroke | 1stReturn+1XY | Tagged net approach | Returning player backhand | Serving player backhand | Opponent net approach |
+------------------+----------+----------+-------------------+-------------------+------------------+------------+--------------------+-------------------+-------------------+-------------+------------------+------------+------------+--------------------+------------+-----------------+--------------+--------------+-----------+-----------+-----------+---------------+----------------+-----------------+--------------------+-------------------+-------------+----------------------+-----------------------+------------------------+---------------------+---------------------+----------------------+-----------------------+--------------------+---------------+-------------------+--------------+-----------+---------------------+--------------+-------------+---------------------------+-------------------------+---------------+---------------------+----------------------+-----------------------+--------------------+--------------+----------------------+-----------------------+------------------------+---------------------+---------------+---------------------+---------------------------+-------------------------+-----------------------+
| 0-0 (1) | 329720 | 23520 | Error | Error net | Error net | 38;52 | Error | Forehand | In | 65;54 | Wide | 32;38 | 20/08/2011 | Forced error | 00:00 | Player 2 | 0-0 | Player | Serving | Set 1 | Deuce | Player 1 | 00:00 | Repton | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 15-0 (1) | 375000 | 4720 | In | Error long | Body | 60;32 | | | | | | | 20/08/2011 | Unforced error | 00:00 | Player 2 | 15-0 | Player | Serving | Set 1 | Advantage | Player 1 | 00:00 | Repton | Error | Backhand | 65;5 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 30-0 (1) | 393320 | 17440 | Error | | Error net | 44;51 | In | Forehand | In | 57;27 | Body | 42;34 | 20/08/2011 | Unforced error | 00:00 | Player 2 | 30-0 | Player | Serving | Set 1 | Deuce | Player 1 | 00:00 | Repton | | | | In | Middle baseline | Neutral | Backhand | In | Middle baseline | Neutral | Forehand | 59;28 | Middle | 61;27 | Player 1 | Middle baseline | Forehand | 39;28 | 1 | 1 | Ground stroke | | | | | | | | | | | | | | |
| 40-0 (1) | 428640 | 6360 | In | Middle | Wide | 66;36 | | | | | | | 20/08/2011 | | 00:00 | Player 2 | 40-0 | Player | Serving | Set 1 | Advantage | Player 1 | 00:00 | Repton | In | Backhand | 46;20 | | | | | | | | | | | | | | | | | | | Unforced error | Middle baseline | Neutral | Forehand | 48;29 | | | | | | | | | |
| 40-15 (1) | 450800 | 9840 | In | Middle | Wide | 34;34 | | | | | | | 20/08/2011 | Unforced error | 00:00 | Player 2 | 40-15 | Player | Serving | Set 1 | Deuce | Player 1 | 00:00 | Repton | In | Forehand | 55;28 | | | | | | | | | | | | Player 1 | Middle transition | Forehand | 69;50 | | 1 | Approach shot | In | Middle baseline | Neutral | Forehand | 57;28 | In | Middle baseline | Neutral | Backhand | 69;23 | Yes | | | |
| 40-30 (1) | 485280 | 6680 | In | Middle | Body | 60;33 | | | | | | | 20/08/2011 | | 00:00 | Player 2 | 40-30 | Player | Serving | Set 1 | Advantage | Player 1 | 00:00 | Repton | In | Backhand | 59;34 | | | | | | | | | | | | | | | | | | | Unforced error | Middle inside | Neutral | Forehand | 70;36 | | | | | | | | | |
| SD advantage (1) | 523800 | 4880 | In | Error long | Wide | 64;31 | | | | | | | 20/08/2011 | Unforced error | 00:00 | Player 2 | SD advantage | Player | Serving | Set 1 | Advantage | Player 1 | 00:00 | Repton | Error | Backhand | 48;8 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| 0-0 (2) | 577560 | 5520 | In | Middle | Wide | 33;30 | | | | | | | 20/08/2011 | | 01:00 | Player 2 | 0-0 | Player | Returning | Set 1 | Deuce | Player 1 | 00:00 | Repton | In | Forehand | 59;30 | | | | | | | | | | | | | | | | | | | Unforced error | Middle inside | Attacking | Backhand | 57;37 | | | | | | | | | |
| 0-15 (1) | 609040 | 11800 | In | Middle | Body | 61;30 | | | | | | | 20/08/2011 | Winner | 01:00 | Player 2 | 0-15 | Player | Returning | Set 1 | Advantage | Player 1 | 00:00 | Repton | In | Backhand | 57;29 | | | | | | | | | | | | Player 1 | Middle baseline | Forehand | 28;27 | 1 | 1 | Ground stroke | In | Advantage wide | Attacking | Forehand | 75;37 | In | Middle baseline | Neutral | Forehand | 42;27 | | | | |
+------------------+----------+----------+-------------------+-------------------+------------------+------------+--------------------+-------------------+-------------------+-------------+------------------+------------+------------+--------------------+------------+-----------------+--------------+--------------+-----------+-----------+-----------+---------------+----------------+-----------------+--------------------+-------------------+-------------+----------------------+-----------------------+------------------------+---------------------+---------------------+----------------------+-----------------------+--------------------+---------------+-------------------+--------------+-----------+---------------------+--------------+-------------+---------------------------+-------------------------+---------------+---------------------+----------------------+-----------------------+--------------------+--------------+----------------------+-----------------------+------------------------+---------------------+---------------+---------------------+---------------------------+-------------------------+-----------------------+
Sum Up Cells to Array
This is how I understand it at the moment. Try it and get back to me in the comments to fix possible issues.
The Code
Option Explicit
Sub sumShotsInRally()
'Set rawData sheet as active
Dim ws As Worksheet
Set ws = Sheets("Input")
'Find first column to sum
Dim sForeCol As Long
sForeCol = ws.Rows(1).Find(What:="Serving player forehand", _
Lookat:=xlWhole).Column
'Add Rally Count Column.
Dim rallyCountCol As Long
rallyCountCol = sForeCol + 1
ws.Columns(rallyCountCol).Insert
ws.Cells(1, rallyCountCol).Value = "Rally Count"
'Find remaining columns to sum
Dim sBackCol As Long
sBackCol = ws.Rows(1).Find(What:="Serving player backhand", _
Lookat:=xlWhole).Column
Dim rForeCol As Long
rForeCol = ws.Rows(1).Find(What:="Returning player forehand", _
Lookat:=xlWhole).Column
Dim rBackCol As Long
rBackCol = ws.Rows(1).Find(What:="Returning player backhand", _
Lookat:=xlWhole).Column
'Define the range to iterate over as the used range of the found column
Dim sFore As Range
Dim sBack As Range
Dim rFore As Range
Dim rBack As Range
Dim RallyCount As Range
'Define column ranges
With ws
Set sFore = .Range(.Cells(2, sForeCol), _
.Cells(.UsedRange.Rows.Count, sForeCol))
Set sBack = .Range(.Cells(2, sBackCol), _
.Cells(.UsedRange.Rows.Count, sBackCol))
Set rFore = .Range(.Cells(2, rForeCol), _
.Cells(.UsedRange.Rows.Count, rForeCol))
Set rBack = .Range(.Cells(2, rBackCol), _
.Cells(.UsedRange.Rows.Count, rBackCol))
Set RallyCount = .Range(.Cells(2, rallyCountCol), _
.Cells(.UsedRange.Rows.Count, rallyCountCol))
End With
'Define Results Array
Dim Results As Variant
'You redimension the results array to the number of entries in your table
ReDim Results(1 To sFore.Rows.Count, 1 To 1)
'You loop over your table and sum the values from count and restocked
For i = 1 To sFore.Rows.Count
Results(i, 1) = sFore(i, 1) + sBack(i, 1) + rFore(i, 1) + rBack(i, 1)
Next i
'You write the array to the range count and delete the values in restocjed
RallyCount.Value = Results
End Sub
I have a pivot chart which currently has the data source referring to my table.
Every week I run my code and a new row of data is appended to the bottom of my table.
The pivot does pick up this new data every week as it refers to the table, however, I want to take one less week each week So I have a years worth of data. So I want to include around rows.
Is there anyway to adjust my table to only include the years worth of rows?
Here is my sample data:
+----------+------------------+-----------------+
| week | stack | overflow |
+----------+------------------+-----------------+
| 12/20/17 | -142,335,432.00 | -41,641,109.88 |
| 12/27/17 | -105,428,220.20 | -47,448,990.63 |
| 1/3/18 | -88,520,154.56 | -24,858,774.97 |
| 1/10/18 | -42,033,431.10 | 14,573,779.35 |
| 1/17/18 | -66,101,748.16 | -8,670,735.22 |
| 1/24/18 | -75,871,649.12 | -18,000,154.21 |
| 1/31/18 | -77,027,686.63 | -11,784,198.64 |
| 2/7/18 | -96,720,126.71 | -52,219,288.98 |
| 2/14/18 | -119,118,554.60 | -34,743,350.28 |
| 2/21/18 | -116,529,554.70 | -20,774,072.93 |
| 2/28/18 | -86,871,998.53 | -25,993,521.20 |
| 3/7/18 | -90,351,387.27 | -21,259,727.05 |
| 3/14/18 | -77,968,076.28 | -51,609,924.29 |
| 3/21/18 | -120,805,352.60 | -40,338,490.97 |
| 3/28/18 | -92,247,583.62 | -14,525,648.04 |
| 4/4/18 | -70,821,451.36 | -35,866,864.46 |
| 4/11/18 | -82,694,486.66 | -59,009,729.82 |
| 4/18/18 | -79,034,094.39 | -64,231,312.42 |
| 4/25/18 | -63,415,815.16 | -28,612,265.37 |
| 5/2/18 | -80,372,191.96 | -53,375,611.61 |
| 5/9/18 | -72,619,415.73 | -50,642,469.19 |
| 5/16/18 | -109,654,240.70 | -45,762,784.43 |
| 5/23/18 | -100,407,366.50 | -39,577,966.11 |
| 5/30/18 | -105,794,095.80 | -65,071,199.59 |
| 6/6/18 | -83,630,201.98 | -60,981,969.88 |
| 6/13/18 | -104,644,821.50 | -63,754,760.71 |
| 6/20/18 | -75,229,424.33 | -55,803,681.24 |
| 6/27/18 | -65,237,135.62 | -54,693,832.65 |
| 7/4/18 | -60,025,672.33 | -44,367,918.60 |
| 7/11/18 | -30,172,175.09 | -28,392,163.28 |
| 7/18/18 | -20,687,864.39 | 24,300,285.63 |
| 7/25/18 | -40,476,447.03 | 4,850,881.09 |
| 8/1/18 | -31,211,625.05 | -67,887,918.30 |
| 8/8/18 | -29,736,938.87 | -32,905,703.80 |
| 8/15/18 | -74,934,647.91 | -65,611,884.73 |
| 8/22/18 | -25,220,747.20 | -7,019,746.86 |
| 8/29/18 | -24,608,552.13 | -8,065,633.97 |
| 9/5/18 | -30,119,599.95 | -26,225,633.08 |
| 9/12/18 | -29,836,379.12 | -10,045,560.95 |
| 9/19/18 | -61,281,567.61 | -58,427,878.27 |
| 9/26/18 | -47,418,209.59 | -33,451,409.22 |
| 10/3/18 | -41,321,336.46 | -25,112,764.44 |
| 10/10/18 | -1,241,932.51 | 21,814,274.35 |
| 10/17/18 | -19,791,273.66 | -12,199,449.75 |
| 10/24/18 | -20,501,406.84 | 1,225,387.11 |
| 10/31/18 | -64,116,464.30 | -5,308,628.21 |
| 11/7/18 | -83,657,672.02 | -19,922,992.91 |
| 11/14/18 | -112,704,007.53 | -32,939,535.69 |
| 11/21/18 | -71,969,954.54 | -51,335,709.79 |
| 11/28/18 | -79,668,484.56 | -67,887,918.30 |
| 12/5/18 | -44,134,343.99 | -32,905,703.80 |
| 12/12/18 | -71,700,079.84 | -65,611,884.73 |
| 12/19/18 | -82,238,011.30 | -74,725,620.20 |
| 12/26/18 | -59,385,932.41 | -54,947,256.94 |
| 1/2/19 | -42,717,830.26 | -31,110,199.14 |
| 1/9/19 | -11,029,444.63 | 7,309,440.90 |
+----------+------------------+-----------------+
Changing the source range for the pivot will be tricky as Excel does not allow non-contiguous cells to be used in pivot tables. Instead you can create the pivot by selecting entire column to account for all future entries.
Then the pivot can be manipulated to show a changing range as shown in the code below.
Hope that works for you.
EDIT
The code is updated below to include 50(can be changed) from the bottom.
Sub MovingPivot()
Dim ws As Worksheet
Dim dtTop As Date
Dim i As Integer, n As Long
Const NumWeeks = 50 'Change this to set weeks range
Set ws = ActiveSheet 'Set reference to your worksheet here
'reset the pivot filters
ws.PivotTables("Table1").PivotFields("Date").ClearAllFilters
'remove blank values
ws.PivotTables("Table1").PivotFields("Date").PivotItems("(blank)").Visible = False
'find the date entry in 50 places from bottom.
i = 0
For n = ws.PivotTables("Table1").RowRange.Count To 1 Step -1
If i = NumWeeks Then
dtTop = ws.PivotTables("Table1").RowRange.Cells(n).Value
Exit For
End If
i = i + 1
Next n
ws.PivotTables("Table1").PivotFields("Date").PivotFilters.Add2 Type:=xlAfterOrEqualTo, Value1:=Format(dtTop, "dd-mmm-yyyy")
End Sub
If you want to continue using a Pivot Chart, you can use the time line slicer to include/exclude data. You'll need to adjust the time line or filter manually after the data has refreshed. Or write VBA to set the filters.
A non-vba version that does not require slicers can also be achieved with a standard chart (not a pivot chart). Create named ranges with Offset functions that grab just the rows of data that you are interested in, then plug these range names into the standard chart. When new data is added to the table, the named ranges that feed the standard chart will also be updated.
If you need a step by step, take a look at https://peltiertech.com/Excel/Charts/DynamicLast12.html