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
Related
Hi Everyone I'm new to VBA Code & I'm Stuck with this one. I hope someone help me..
Step 1: compare the row with every SU headers. Here in row2, the value in SU_BS is 211. Once there is a value in SU , the column NAME2 should display the corresponding NAME (s1) with SU value (211). So NAME2 should display s1 211.
Step 2: Once NAME2 display the value, want to move to the next row without further checking SU headers.
Step 3: As per step 1 & 2 the column NAME2 in Next row will also display S1 211. But what i need is while filling the value, NAME2 column should check for the duplicate value. If duplicate value exist the control moves to next SU header. If the SU header has no value, move on to the next SU header if value exist NAME2 should display the value (S1 ZY) in row3.
Use an array to store each row and previous row in turn, compare elements until different.
Option Explicit
Sub macro()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim r As Long, c As Integer, n As Integer
Dim k As Integer, kLast As Integer
Dim ar(4, 1) As String
r = 2 ' start row
While Len(ws.Cells(r, 1)) > 0
' fill array
For n = 0 To 3
c = n * 2 + 4
ar(n, 1) = ws.Cells(r, c)
Next
k = 0
If r > 2 Then
' compare
While k <= kLast And ar(k, 1) = ar(k, 0)
k = k + 1
Wend
' skip pass any blanks
While Len(ar(k, 1)) = 0 And k <= 3
k = k + 1
Wend
End If
' output
ws.Cells(r, 3) = ws.Cells(r, 2) & " " & ar(k, 1)
' remember last row
For n = 0 To 3
ar(n, 0) = ar(n, 1)
Next
kLast = k
r = r + 1
Wend
MsgBox "Done"
End Sub
For the first 15 ranks, I want to manually enter the values in B2:P11. For ranks 16 to 30, I want to randomize these values using an Excel VBA button, with the following code:
Sub rand_group()
Dim i As Long
Dim j As Long
Dim myFlag(1 To num_man)
Dim s_group As Worksheet
Set s_group = Worksheets("group")
'óêêîånóÒÇèâä˙âª
Randomize
s_group.Cells.Clear
s_group.Range("A1") = "group_id"
For i = 1 To num_group
s_group.Cells(i + 1, 1) = i
Next i
For i = 1 To num_man
s_group.Cells(1, i + 1) = "m_rank" & i
Next i
For i = 1 To num_group
For j = 16 To num_man
myFlag(j) = False
Next j
For j = 16 To num_man
Do
'óêêî=Int((ç≈ëÂíl - ç≈è¨íl +1 ) * Rnd + ç≈è¨íl)
myNum = Int((num_man - 1 + 1) * Rnd + 1)
Loop Until myFlag(myNum) = False
s_group.Cells(i + 1, j + 1).Value = myNum
myFlag(myNum) = True
Next j
Next i
End Sub
However, these random values should neglect the manually entered values in B2:P11
How can I change the code to fix this?
Screenshot of the excel file is displayed below:
I want to manually fill values from B2 to P11
Thank you in advance for your response!
Michiel
To fill in the random section of the grid, the myFlag array is not needed. Just use the cell coordinates to set the random values. Also remove the Clear call since that clears the entire sheet.
To prevent duplicate numbers in a row, use the excel CountIf function in a loop until a unique random number is found.
Here is the updated code. It can be run multiple times without affecting the manual data.
Sub DoRand()
Dim i As Long
Dim j As Long
Dim s_group As Worksheet
Set s_group = Worksheets("group")
num_group = 10
num_man = 30
Randomize
's_group.Cells.Clear ' clear sheet
' build table
For i = 1 To num_group ' group id
s_group.Cells(i + 1, 1) = i
Next i
For i = 1 To num_man ' column names
s_group.Cells(1, i + 1) = "m_rank" & i
Next i
' fill in random numbers
For i = 1 To num_group 'row
For j = 16 To num_man 'column
Do While True
n = Int((num_man) * Rnd + 1) ' get random number
cnt = Application.WorksheetFunction.CountIf(Range(s_group.Cells(i + 1, 2), s_group.Cells(i + 1, j)), "=" & n) ' check if number in row
s_group.Cells(i + 1, j + 1).Value = n ' set cell value
If cnt = 0 Then Exit Do ' if unique in row, go to next cell
Loop ' not unique, try new random value
Next
Next
End Sub
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
The function is designed to take in input - variable pg - that is in a cell on the spreadsheet, go through the rows of data to see which row in a column 1 matches variable pg. Once the match is found, it then goes through the columns to see which of the columns has "VRP23" Or "VRP24" in the first row. When that is found, it takes the number of the matching row/column and performs the "step1" modification. The issue is that in the spreadsheet the error #VALUE! appears and I'm not sure why this is.
Function getECONpgdimscore1(pg As String) As Double
Dim row As Integer
row = 2
Dim c As Integer
c = 1
Dim econ As Double
econ = 0
Dim x As Integer
Dim NumRows As Integer
NumRows = Range("A2", Range("A2").End(xlDown)).rows.count
Cells(row, 1).Select
For x = 1 To NumRows
If Cells(row, 1).Value = pg Then
Do While c < 48
Cells(row, 7 + c).Select
If Cells(1, 7 + c).Value = ("VRP23" Or "VRP24") Then
econ = econ + step1(Cells(1, 7 + c), Cells(row, 7 + c))
End If
c = c + 1
Loop
End If
row = row + 1
Next x
getECONpgdimscore1 = (econ / 100) * 2.5
End Function
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))