How to transpose repeating groups in excel? - excel

I have an excel sheet with the following data structure
+-------------+-------------------------------+--+
| title | Dr. | |
| first_name | Adam | |
| last_name | Meyer | |
| email | adam.meyer#my-company.com | |
| phone | +49 (0)931-32187-0 | |
| fax | | |
| room | | |
| position | Direktor | |
| title | | |
| first_name | Judith | |
| last_name | Schmidt | |
| email | judith.schmidt#my-company.com | |
| phone | +49 (0)444-32131-1 | |
| fax | | |
| room | | |
| position | | |
| title | | |
| first_name | Claus | |
| last_name | Niemes | |
| email | claus.niemes#my-company.com | |
| phone | +49 (0)444-32131-2 | |
| fax | | |
| room | | |
| position | Verkäufer | |
| bio | xxxxxxxxxx | |
| title | Dr. | |
| first_name | András | |
| last_name | Cloon | |
| email | andrás.cloon#my-company.de | |
| phone | +49 (0)444-32131-1 | |
+-------------+-------------------------------+--+
Not all 450 Persons have values for all rows. Sometimes is missing the first row with the title for example.
I want to import these data into a mysql database.
I need this result:
I'm not an excel expert that's why I'm happy about every hint how to ease the preparation of the data for the import.
I know how to do the import.

Oh I see what you want now
Sub SortItOUt()
Dim t As Range
Dim r As Range
Set t = Sheets(2).Range("a2") 'I assume a blank second sheet to collect the data
Set r = Sheets(1).Range("a1") 'assume data starts in sheet 1
Do
Dim x As Long
For x = 0 To 7
r.Offset(x, 1).Copy t.Offset(0, x) 'copy and transpose
Next x
Set t = t.Offset(1, 0)
Set r = r.Offset(8, 0)
Loop Until r = ""
End Sub

Related

Trying to sum values in a row using VBA and can't solve a bug in code

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

Pandas sort not sorting data properly

I am trying to sort the results of sklearn.ensemble.RandomForestRegressor's feature_importances_
I have the following function:
def get_feature_importances(cols, importances):
feats = {}
for feature, importance in zip(cols, importances):
feats[feature] = importance
importances = pd.DataFrame.from_dict(feats, orient='index').rename(columns={0: 'Gini-importance'})
importances.sort_values(by='Gini-importance')
return importances
I use it like so:
importances = get_feature_importances(X_test.columns, rf.feature_importances_)
print()
print(importances)
And I get the following results:
| PART | 0.035034 |
| MONTH1 | 0.02507 |
| YEAR1 | 0.020075 |
| MONTH2 | 0.02321 |
| YEAR2 | 0.017861 |
| MONTH3 | 0.042606 |
| YEAR3 | 0.028508 |
| DAYS | 0.047603 |
| MEDIANDIFF | 0.037696 |
| F2 | 0.008783 |
| F1 | 0.015764 |
| F6 | 0.017933 |
| F4 | 0.017511 |
| F5 | 0.017799 |
| SS22 | 0.010521 |
| SS21 | 0.003896 |
| SS19 | 0.003894 |
| SS23 | 0.005249 |
| SS20 | 0.005127 |
| RR | 0.021626 |
| HI_HOURS | 0.067584 |
| OI_HOURS | 0.054369 |
| MI_HOURS | 0.062121 |
| PERFORMANCE_FACTOR | 0.033572 |
| PERFORMANCE_INDEX | 0.073884 |
| NUMPA | 0.022445 |
| BUMPA | 0.024192 |
| ELOH | 0.04386 |
| FFX1 | 0.128367 |
| FFX2 | 0.083839 |
I thought the line importances.sort_values(by='Gini-importance') would sort them. But it is not. Why is this not performing correctly?
importances.sort_values(by='Gini-importance') returns the sorted dataframe, which is overlooked by your function.
You want return importances.sort_values(by='Gini-importance').
Or you could make sort_values inplace:
importances.sort_values(by='Gini-importance', inplace=True)
return importances

Pivot, dynamic data source

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

VBA, Pivot formula to include last 52 weeks of data

I have a pivot that gets data from up to 2 years. I select all columns like Sheet!$A:$F.
How can I alter the formula to only include the previous 52 weeks from today?
Sample Data:
+-------------+
| 1-Jan-2019 |
| 2-Jan-2019 |
| 3-Jan-2019 |
| 4-Jan-2019 |
| 7-Jan-2019 |
| 8-Jan-2019 |
| 9-Jan-2019 |
| 10-Jan-2019 |
| 11-Jan-2019 |
| 14-Jan-2019 |
| 15-Jan-2019 |
| 16-Jan-2019 |
| 17-Jan-2019 |
| 18-Jan-2019 |
| 21-Jan-2019 |
| 22-Jan-2019 |
| 23-Jan-2019 |
| 24-Jan-2019 |
| 25-Jan-2019 |
| 28-Jan-2019 |
| 29-Jan-2019 |
| 30-Jan-2019 |
| 31-Jan-2019 |
| 1-Feb-2019 |
| 4-Feb-2019 |
| 5-Feb-2019 |
| 6-Feb-2019 |
| 7-Feb-2019 |
| 8-Feb-2019 |
| 11-Feb-2019 |
| 12-Feb-2019 |
| 13-Feb-2019 |
+-------------+
You can add a date filter to your PivotField.
With the DateSerial function you can subtract from today, e. g. 1 year (or 52 * 7 days or whatever).
With ActiveWorkbook.Worksheets("WSname").PivotTables("PTname").PivotFields("PFname")
.ClearAllFilters
.PivotFilters.Add2 _
Type:=xlDateBetween, _
Value1:=CStr(DateSerial(Year(Date) - 1, Month(Date), Day(Date))), _
Value2:=CStr(Date), _
WholeDayFilter:=True
End With

Calculating frequecy (Min/Max/Average) of order placement in Excel

I need to analyze Weekly order frequencies over last 1 year period to find out what is the min/max/average frequencies of orders for each product.
whether it is new or old,system should calculate the first occurrence of the order in the year as the starting week of the order. Min order frequency is difference between successive ordering weeks. If the first order is in wk 3 and the second order is in wk6, implies the order frequency is 3 weeks (=>6-3). Orders can be at any week in the past 52 weeks. Average order frequency = (52 - First order week) / no of weeks that have orders.
Attaching the excel for better understanding the issue.
Original image
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+----------------+-------------------------+-----+-----------------------------------+--+
| Product | wk1 | wk2 | wk3 | wk4 | wk5 | wk6 | wk7 | wk8 | wk9 | wk10 | wk11 | wk12 | wk13 | wk14 | wk15 | wk16 | wk17 | wk18 | wk19 | wk20 | wk21 | wk22 | wk23 | wk24 | wk25 | wk26 | wk27 | wk28 | wk29 | wk30 | wk31 | wk32 | wk33 | wk34 | wk35 | wk36 | wk37 | wk38 | wk39 | wk40 | wk41 | wk42 | wk43 | wk44 | wk45 | wk46 | wk47 | wk48 | wk49 | wk50 | wk51 | wk52 | Order start wk | Order frequency (Weeks) | | | |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+----------------+-------------------------+-----+-----------------------------------+--+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Min | Max | Average | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (End wk - Start week)/No of times | |
| SKU 1 | | | | | | | | | y | | y | | y | | y | | y | | y | | y | | y | y | | | y | | y | | y | | y | | | | | | y | | y | | y | | y | | y | | y | | y | | 9 | 1 | 6 | 2.15 | |
| SKU 2 | | | | | | | y | | | | | | y | | | | | | y | | | | | | y | | | | | | y | | | | | | y | | | | | | y | | | | | | y | | | | 1 | 0 | 0 | 7.29 | |
| SKU 3 | | | | | | | | | | | | | | | y | | | | | | | | | | | | | | | | y | | | | | | | | y | | | | | | | | y | | | | | | 15 | 8 | 15 | 9.25 | |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-----+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+----------------+-------------------------+-----+-----------------------------------+--+
So as mentioned #Barry Houdini solves the problem of finding the longest sequence of zeroes separated by ones elegantly here
You only have to change it slightly to check for repeated blank cells separated by 'y'. The only thing is that you don't want to include cells before the first 'y', and (although this isn't clear) may not want to include blank cells after the last 'y'.
The formula for MIN becomes
=MIN(IF((ROW(A$1:INDEX(A:A,COUNTA(B4:BA4)+1))>1)*(ROW(A$1:INDEX(A:A,COUNTA(B4:BA4)+1))<COUNTA(B4:BA4)+1),FREQUENCY(IF(B4:BA4="",COLUMN(B4:BA4)),IF(B4:BA4="y",COLUMN(B4:BA4)))))+1
and the formula for MAX becomes (the same)
=MAX(IF((ROW(A$1:INDEX(A:A,COUNTA(B4:BA4)+1))>1)*(ROW(A$1:INDEX(A:A,COUNTA(B4:BA4)+1))<COUNTA(B4:BA4)+1),FREQUENCY(IF(B4:BA4="",COLUMN(B4:BA4)),IF(B4:BA4="y",COLUMN(B4:BA4)))))+1
where you need to add 1 to make the results agree with the question because #Barry's formula counts numbers of blanks but OP wants interval between two successive y's. An array of ny+1 elements is generated where ny is the number of y's. This is because the FREQUENCY function returns an array with n+1 elements where n is the number of cut points (bins_array in documentation and because the column numbers of cells containing y are used as cut points so there are ny of them.
These are both array formulas and need to be entered with CtrlShiftEnter
The formula for the average is just
=(COLUMNS(B4:BA4)-MATCH("y",B4:BA4,0))/COUNTA(B4:BA4)

Resources