MS Excel: macro inquiry for array - excel

lets say in column A:Row 2, I have a score of 45 and in column B, I have the amount of people that got that score. what i then want to do is on column D, output that score X amount of times. x=repitition.
in the exmaple 5 people got a score of 45 so in column D i want to insert 5 scores of 45. then I see in column A:Row2 3 people got a score of 46 then after the last 45, in column D I want to append 46 3 times.. and so on..
Could someone show me how to do this?

Here you go:
Sub test_scores_repitition()
'run with test scores sheet active
r = 1
dest_r = 1
Do While Not IsEmpty(Range("a" & r))
If IsEmpty(Range("b" & r)) Then Range("b" & r).Value = 0 'if there's no quantity listed for a score, it assumes zero
For i = 1 To Range("b" & r).Value
Range("d" & dest_r).Value = Range("a" & r).Value
dest_r = dest_r + 1
Next i
r = r + 1
Loop
End Sub

Macro answer:
Sub WriteIt()
Dim lrow As Long
Dim WriteRow As Long
Dim EachCount As Long
Dim ReadRow As Long
' find last in list of numbers
lrow = Range("A1").End(xlDown).Row
'start at 2 because of headers
WriteRow = 2
ReadRow = 2
While ReadRow <= lrow
For EachCount = 1 To Cells(ReadRow, 2)
'repeat the number of times in column B
Cells(WriteRow, 4) = Cells(ReadRow, 1)
'the number in column A
WriteRow = WriteRow + 1
Next
ReadRow = ReadRow + 1
'and move to the next row
Wend
'finish when we've written them all
End Sub
it is possible with a formula, just not really recommended as it looks auful, and would be difficult to explain. It uses a Microsoft formula to count the number of unique items in the data above, and once it counts the number it is supposed to write of the number above, it moves to the next number. The formula does not know where to stop, and will put 0 when it runs out of data.
in D2, put =A2
In D3, and copied down, put
=IF(COUNTIF($D$2:D2,OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0))<OFFSET($B$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0),OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1)),0),OFFSET($A$1,SUM(IF(FREQUENCY($D$2:D2,$D$2:D2)>0,1))+1,0))

Related

How to get average of a Column Based on dates

I'm still a newbie at this but I am trying to build a VB Macro to provide me with the Average Bet Value per session. Basically I have a list of Dates in Cell 'AD' and also a list of Bet Values in Cell 'AE'.
I am finding a difficulty in coding VB to calculate :
From Col 'AD' which contains the dates I need to loop through the dates and if there is a 10 minute difference between a date and an other, then both dates will be considered as a start and end date.
Following Step number 1. I need to get the Bet values which fall between the Start and End date and get the average of that session in Col 'AF'
Last but not least I need to do this process for all the dates in Col 'AD' - for every session identified we get the average bet value in col AF'
I have pasted the code on how I generated Col AD and Col AE and a snip of the data I am using.
I hope i explained myself well and would like to thank you all
Excel Sample Data
Public Sub GetDebitValue()
RowCounter = 1
Profile.Range("AE1").Value = "BET VALUE"
Profile.Range("AD1").Value = "BET TIME AND DATE"
Profile.Range("AF1").Value = "SESSION BET AVERAGE"
'Range Col 'H2' Contained the action types called Debit which are considered as bets - if value is debit take the bet amount from Col 'C'
If Profile.Range("H2").Value = "debit" Then
Profile.Range("C2" + CStr(RowCounter + 1)).Value = Profile.Range("C2" + CStr(RowCounter)).Value
'Set Date
Profile.Range("AD2").Value = Profile.Range("I2").Value
'Set Value
Profile.Range("AE2").Value = Profile.Range("C2").Value
End If
'Always start with debit
Do
Select Case Profile.Range("H" + CStr(RowCounter)).Value
Case "debit"
Profile.Range("AE" + CStr(RowCounter + 1)).Value = Profile.Range("C" + CStr(RowCounter)).Value
'Copy Date
Profile.Range("AD" + CStr(RowCounter + 1)).Value = Profile.Range("I" + CStr(RowCounter)).Value
Case Else
'Do Nothing
End Select
If Profile.Range("A" + CStr(RowCounter + 1)).Value = CStr("") Then
Exit Do
End If
'Call GamblingLength
RowCounter = RowCounter + 1
Loop Until RowCounter = 99999
End Sub
I knocked this up quickly, I didn't have time to recreate your exact conditions and figure out some bits of the code but I hope you can use this generic pattern to achieve the steps:
The data starts on row FOUR here (row 3 is the headers)
And the code to achieve this was:
Sub avgs()
Dim i As Long ' row counter
Dim c As Long ' average divisor counter
Dim cTot As Double ' cumulative value total
With Sheet2
c = 1 ' initiate count as 1
cTot = .Range("B4").Value2 ' initiate cumulative total as first row of data val
For i = 5 To .Cells(.Rows.Count, 1).End(xlUp).Row ' cycle through to end row
If .Range("A" & i).Value2 - .Range("A" & i - 1).Value2 < 0.00694 Then
' if less than ten minute gap on this row then add to both avg div and tot counter
c = c + 1
cTot = cTot + .Range("B" & i).Value2
Else
' else set the value in column c and reset the avg div and tot counter
.Range("C" & i - 1).Value2 = cTot / c
c = 1
cTot = .Range("B" & i).Value2
End If
Next i
End With
End Sub

Excel score sheet

So, I haven't figured out how to do this.
Basically, I want something like this:
P1 P2 P3 TOTAL SCORE
-- -- -- P1 P2 P3
21 / 13 1 2 0
/ 17 10
6 7 /
So, the three columns must compare to one-another (the "/" means that the player didn't play that game, but it doesn't have to be printed), the greatest among the three gets a +1 value in the TOTAL SCORE tab.
Plus, is there any easier way to do this than comparing one cell to another cell? I mean, is there a possibility to drag and mark all cells on all of the three columns and make sure that they only compare the cells in the three columns IN THE SAME ROW?
Let us assume that the data appears as in the picture in Sheet1 (Don't change the structure):
Open an Excel
Press ALT & F11 to open Visual Editor
Add a module from > Insert (in the Upper toolbar) - Module ( third option)
Paste the below codes & execute Sub Evaluation() (press F5 when your cursor is in Sub Evaluation)
To store lastrow in order to continue from the next record i use sheet2 range A1
Try:
Option Explicit
Public Sub Process_Data(ByVal I_Value As Long)
Dim LastRow As Long
Dim i As Long
Dim CA As Integer
Dim CB As Integer
Dim CC As Integer
With Sheet1
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = I_Value To LastRow '<= Lets say that the first score is at sheet1 column A row 3.LastRow represent the row of the last data in column A
CA = 0
CB = 0 '<= Every time that i change value we zero our variables to get the new value
CC = 0
If .Range("A" & i).Value = "/" Then '<= Check if there is a number or "/".if there is "/" we zero variable
CA = 0
Else
CA = .Range("A" & i).Value
End If
If .Range("B" & i).Value = "/" Then
CB = 0
Else
CB = .Range("B" & i).Value
End If
If .Range("C" & i).Value = "/" Then
CC = 0
Else
CC = .Range("C" & i).Value
End If
If CA > CB And CA > CC Then ' <= Check which number is bigger
.Range("E3").Value = .Range("E3").Value + 1 '<= At one point to each category
ElseIf CB > CA And CB > CC Then
.Range("F3").Value = .Range("F3").Value + 1
ElseIf CC > CA And CC > CB Then
.Range("G3").Value = .Range("G3").Value + 1
End If
Next i
End With
End Sub
Sub Evaluation()
Dim Value As Long
Dim LastRow As Long
LastRow = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
If (LastRow = 2) Or (LastRow = Sheet2.Range("A1").Value) Then '<= Check if the table has new data
Exit Sub
Else
If Sheet2.Range("A1").Value = "" Then '<=Check which value will adopt be i
Value = 3
Else
Value = Sheet2.Range("A1").Value + 1
End If
End If
Call Process_Data(I_Value:=Value)
Sheet2.Range("A1").Value = Sheet1.Range("A" & Rows.Count).End(xlUp).Row '<= Record the lastrow processed out
End Sub
Use the LARGE function to find the highest number for the individual games on the left. Then use an IF statement out to the right to check if the value of the LARGE function matches the player's game score. If it does match (TRUE), assign a value of 1. If it doesn't match (FALSE), assign a value of 0. Then SUM each player's modifiers that you've assigned with the IF function.
If ties are possible in the individual game scores, you'll also need to nest another IF function to handle that possibility.

Excel if value appears in any column, average the reference column

I need to find the average of a number found in column F if a particular value is found in any of the other columns in the sheet.
For instance: I have the following in a range...
A B C D E F
Red    Bill   Jack   Ruby   Bill   250
Blue  Ruby   Ivan   Raul   Ted   350
Green  Ted   James Rick   Ted   125
Red   Ted   Phil   Ruby   Bill   300
And in this worksheet, I want to find any instance of the name Bill and get the average of the number found in column F. In this case, the answer of 275 because Bill's name shows up in two rows. In the same respect, If I choose to look at Ted's numbers, the answer should be 258 because Ted's name shows up in three rows.
I would also appreciate if the formula would ignore any blank cells in the process of calculating the answer.
Thanks in advance!
I would use the function below, assuming that the data is placed in Sheet1.
Function my_average(strName As String) As Variant
Dim varArrayNames As Variant
Dim varValues As Variant
Dim dblInSum(1 To 4) As Double '~~> change to "1 To 40"
Dim lngCnt As Long
Dim strRow As String
Dim dblSum As Double
varArrayNames = Sheet1.Range("B1:E4").Value '~~> change to "B1:G40"
varValues = Sheet1.Range("F1:F4").Value '~~> change to "H1:H40"
For lngCnt = LBound(varArrayNames, 1) To UBound(varArrayNames, 1)
strRow = Join(WorksheetFunction.Index(varArrayNames, lngCnt, 0))
If InStr(strRow, strName) > 0 Then
dblInSum(lngCnt) = 1
End If
Next lngCnt
dblSum = WorksheetFunction.Sum(dblInSum)
If dblSum > 0 Then
my_average = WorksheetFunction.SumProduct(dblInSum, Application.Transpose(varValues)) / dblSum
Else
my_average = 0
End If
End Function
Testing:
Place =my_average("Bill") in any workbook (or a cell reference instead of "Bill").
Formulas:
Results:
Assuming the lookup value (Bill etc) is in cell C7, add the following formula in G1 then copy down for other rows.
=IF(ISERROR(MATCH($C$7,A1:E1,0)),"",F1)
Then do
=AVERAGE(G1:G4)
So if Bill is in any col a-e that number is taking into the ave... If so depending on your data size why not do this simply...:
Sub simplesearch()
cnt = 0
tot = 0
srchval = InputBox("What are we looking for?")
lr = Range("A1000000").End(xlUp).Row
For i = 1 To lr
For j = 1 To 5
If Cells(i, j).Value = srchval Then
tot = tot + Cells(i, 6).Value
cnt = cnt + 1
End If
Next j
Next i
If Not (cnt = 0) Then
MsgBox (tot / cnt)
Else
MsgBox ("0")
End If
End Sub

Update Column Range with the cell value

I have an input sheet called "Testfall-Input-Vorschlag where we have to choose a value from a dropdown in the cells of the first row from the 7th (J)column and when a value gets chosen for example "ARB13" I want to fill out the column where it is selected. The filling of the column is with random values. There is a Sheet called "Admin" which has values stored in the cells of columns from A:ZZ. Now I in the "Testfall-Input-Vorschlag" sheet I want to fill out the cells of the column sequentially. Which means for example for cell(11,7) i want to generate a random value from column A in "Admin" for cell (12,7) the value has to be from Column B in "Admin" for cell (13,7) the value is from column C in "Admin and so on. So I have been trying and I've come up with this code
Sub ARB13()
Dim col As Integer
For i = 11 To 382
For j = 7 To 1000
If Sheets("Testfall-Input_Vorschlag").Cells(1, j) = "ARB13" Then
col = 0
col = col + 1
LB = 2
UB = Sheets("Admin").Range("col" & Rows.Count).End(xlUp).Row
Cells(i, j).Select
ActiveCell.FormulaR1C1 = Sheets("Admin").Range("Y" & Int((UB - LB + 1) * Rnd + LB))
End If
Next j
Next i
End Sub
How can I update the col value for every i. Which means for every i I need col value to be increased by 1. Where am I going wrong?
Define col before you start your first loop, and don't put col = col + 1 in the For j = 7 to 1000 loop. Otherwise col will increment for every j instead of every i. Something like this:
Sub ARB13()
Dim col as Long
Dim i as Long
Dim j as Long
col = 0
For i = 11 To 382
For j = 7 to 1000
LB = 2
UB = Sheets("Admin").Cells(Rows.count, col).End(xlUp).row
Cells(i, j).Select
ActiveCell.FormulaR1C1 = Sheets("Admin").Range("Y" & Int((UB - LB + 1) * Rnd + LB))
Next j
col = col +1
Next i
End Sub

Check if any rows are duplicate and highlight

I have data in (Sheet4) columns A to I:
I'm trying to compare data for all rows (Only on column A and B) to see if any of the rows is duplicated, if it is: excel should highlight both rows.
Example:
A B C......I
s 1 x
s 3 w
e 5 q
s 1 o
Row 1 and 4 should be highlighted as values are the same for column A and B.
I shouldn't modify the sheet (no modification to the columns or rows should be done to the sheet), and the number of rows is not always known (not the same for all files).
Is there an easy way (using macros) to do this???
This is an attempt I have tried, but it is increasing my file to 7MB!!!!! I'm sure there should be an easier way to compare rows for an unknown number of rows and just highlight the dupllicates if they exist:
Public Sub duplicate()
Dim errorsCount As Integer
Dim lastrow As Integer
Dim lastrow10 As Integer
errorsCount = 0
lastrow = Sheet4.Cells(Rows.Count, "A").End(xlUp).Row 'is the row number of the last non-blank cell in the specified column
lastrow10 = lastrow
Sheet10.Range("B1:B" & lastrow10).Value = Sheet4.Range("A1:A" & lastrow).Value
Set compareRange = Sheet10.Range(column + "2:" & Sheet10.Range(column + "2").End(xlDown).Address)
For Each a In Sheet10.Range(column + "2:" & Sheet10.Range(column + "2").End(xlDown).Address)
c = a.Value
If c <> Null Or c <> "" Then
If name = "testing" Then
If WorksheetFunction.CountIf(compareRange, c) > 1 Then
a.Interior.ColorIndex = 3
errorsCount = errorsCount + 1
End If
End If
End If
Next a
If errorsCount > 0 Then
MsgBox "Found " + CStr(errorsCount) + " errors"
Else
MsgBox " No errors found."
End If
End Sub
Silly answer to you.
J1 or just duplicate sheet.
J1 =CONCATENATE(A1,"#",B1) > drag down > J:J > conditional format > highlight cells rules > duplicate values.
(* replace the # to any string which you think not possible in the original A:A and B:B.)
I do this all the time.
To collect all duplicates just SORT with color.

Resources