Recently I was helped with a code that fill down randomnly the cells based on Row#1 values. Answered_Post. (Thanks to #JvdV and #Scott Craner for assist me before.)
What I need to do now is almost the same, but the code will fill the cells leaping the columns as per random value (x) in a total of 10 rows. The repeatable values remain on Row#1.
Below the code provided on that post to fill down rows. I need now, as per picture, fill the columns.
Dim x As Long, y As Long, z As Long
With Sheet1 'Change accordingly
For y = 1 To 15
z = 0
Do While z < 4
x = Int((7 - 2 + 1) * Rnd + 2)
If .Cells(x, y) <> .Cells(1, y) Then
.Cells(x, y) = .Cells(1, y)
z = z + 1
End If
Loop
Next y
End With
Table_With_Sample_Values
Sub FillColumns01()
For y = 1 To 15
z = 0
j = 1
Do While z < 4
x = Int((7 - 2 + 1) * Rnd + 2)
If Cells(x, y) <> Cells(1, y) Then
Cells(y + 1, j) = Cells(1, y)
z = z + 1
j = j + 1
End If
Loop
Next y
End Sub
Sub FillColumns02()
'Using a 3rd Loop
Dim x As Integer, y As Integer, z As Integer, j As Integer
For y = 1 To 10
z = 0
Do While z < 4
For j = 1 To 15
x = Int((7 - 2 + 1) * Rnd + 2)
If Cells(x, y) <> Cells(1, y) Then
Cells(j, x) = Cells(1, y)
z = z + 1
End If
Next j
Loop
Next y
End Sub
Related
This code is working fine but it has minor defect. I was hoping to get some help here.
This code needs to compare 2 values and divide the value in equal parts and place it in next cell.
First 2 conditions are working fine. The third condition is working fine but has 2 issues mentioned below which I need help with.
For example if X = 2 and Y = 8, it should divide Y in 4 equal parts as per X value but it is only placing 3 values of 2 in offset cells
Also, if Y = 7 then it should place values as 2 2 2 1 in corresponding cells
While it is doing the work for first cell having Y > X, it is putting incorrect value in farther cell for next Y > X value
Please advise on what needs to be changed.
Sub Calc()
Dim ws As Worksheet
Dim i, j, x, y As Variant
Dim lrow As Long
lrow = Worksheets("AB").Cells(Rows.Count, 1).End(xlUp).Row
Set ws = Workbooks("BC.xlsm").Worksheets("AB")
j = 9
With ws
.Activate
For i = 2 To lrow
x = Cells(i, 7).Value
y = Cells(i, 8).Value
If y < 0 Then
Cells(i, 8).Offset(0, 1) = y
ElseIf y <= x Then
Cells(i, 8).Offset(0, 1) = y
ElseIf y > x Then
Do Until y <= x
Cells(i, j) = x
y = y - x
j = j + 1
Loop
End If
Next i
End With
End Sub
Your variables i, j, x are not being assigned Data type, only y is being assigned as variant.
If you are planning to use With construct then it should connect to its child objects via a . as demonstrated below.
Your first two conditions have the same action associated so they can be joined by OR.
Sub Calc()
Dim ws As Worksheet
Dim i, j, x, y
Dim lrow As Long
Set ws = Workbooks("BC.xlsm").Worksheets("AB")
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
With ws
For i = 2 To lrow
x = .Cells(i, 7).Value
y = .Cells(i, 8).Value
j = 9
If y < 0 Or y <= x Then
.Cells(i, j) = y
ElseIf y > x Then
Do Until y <= x
.Cells(i, j) = x
.Cells(i, j + 1) = y - x
y = y - x
j = j + 1
Loop
End If
Next i
End With
End Sub
I would use a for loop and some if logic inside:
Sub Calc()
Dim ws As Worksheet
Dim i As Long, j As Long, x as double, y as double
Dim lrow As Long
Set ws = Workbooks("BC.xlsm").Worksheets("AB")
j = 9
With ws
lrow = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lrow
x = .Cells(i, 7).Value
y = .Cells(i, 8).Value
If y < 0 Then
.Cells(i, j) = y
ElseIf y <= x Then
.Cells(i, j) = y
ElseIf y > x Then
For j = 9 To 8 + Application.RoundUp(y / x, 0)
If y >= x Then
.Cells(i, j) = x
y = y - x
Else
.Cells(i, j) = y
End If
Next j
End If
Next i
End With
End Sub
using excel VBA i have to generate a table of numbers counting anti clock wise with one in the middle and highlight prime numbers in red in the process the following image is an example of the out put i should have .
Thanks to you guys i have used the above code to come up with this code which works perfectly.
Option Explicit
Private Function GetPrime(MaxToCheck As Long) As Collection
Dim c As New Collection, isUnDivided As Boolean, i As Long, v
c.Add Key:="2", Item:=2
For i = 3 To MaxToCheck
isUnDivided = True
For Each v In c
If i Mod v = 0 Then isUnDivided = False: Exit For
Next v
If isUnDivided Then c.Add Key:=CStr(i), Item:=i
Next i
Set GetPrime = c
End Function
Sub prime()
Dim a, c As New Collection, i As Long, j As Long, r As Range, v
With Range("A1").CurrentRegion
a = .Value
Set c = GetPrime(Application.Max(a))
For i = 1 To UBound(a, 1)
For j = 1 To UBound(a, 2)
On Error Resume Next
v = c(CStr(a(i, j)))
If Err.Number = 0 Then
If Not r Is Nothing Then Set r = Union(r, .Cells(i, j)) Else
Set r = .Cells(i, j)
End If
On Error GoTo 0
Next j
Next i
End With
If Not r Is Nothing Then r.Font.Color = vbRed
End Sub
Here is a sample code for you to start with,
Sub primeNum()
Dim i As Long, j As Long, k As Long, x As Long, y As Long, z As Long
Dim l As Long
j = 50
x = 20
y = 20
k = 1
i = 1
Cells(x, y) = 1
Loops:
For z = 1 To 4
If z = 3 Then
k = k + 1
End If
For l = 1 To k
i = i + 1
Select Case (z)
Case "1":
y = y + 1
Cells(x, y) = i
Case "2":
x = x - 1
Cells(x, y) = i
Case "3":
y = y - 1
Cells(x, y) = i
Case "4":
x = x + 1
Cells(x, y) = i
End Select
Next l
Next z
k = k + 1
If i <= j Then
GoTo Loops
End If
End Sub
I leave the part of checking prime numbers for you to google and find,
Looking to loop using columns, relatively new to looping and have some existing code which is incredibly cumbersome:
Sub AdvanceWeek2()
Application.ScreenUpdating = False
' Victor
' Week1
Range("V24:V124").Copy
Range("U24").PasteSpecial xlPasteValues
Range("V134:V234").Copy
Range("U134").PasteSpecial xlPasteValues
Range("V244:V334").Copy
Range("U244").PasteSpecial xlPasteValues
' Week2
Range("W24:W124").Copy
Range("V24").PasteSpecial xlPasteValues
Range("W134:W234").Copy
Range("V134").PasteSpecial xlPasteValues
Range("W244:W334").Copy
Range("V244").PasteSpecial xlPasteValues
' Week3
Range("W24:W124").ClearContents
Range("W134:W234").ClearContents
Range("W244:W334").ClearContents
' Nick
' Week1
Range("Z24:Z124").Copy
Range("Y24").PasteSpecial xlPasteValues
Range("Z134:Z234").Copy
Range("Y134").PasteSpecial xlPasteValues
Range("Z244:Z334").Copy
Range("Y244").PasteSpecial xlPasteValues
' Week2
Range("AA24:AA124").Copy
Range("Z24").PasteSpecial xlPasteValues
Range("AA134:AA234").Copy
Range("Z134").PasteSpecial xlPasteValues
Range("AA244:AA334").Copy
Range("Z244").PasteSpecial xlPasteValues
' Week3
Range("AA24:AA124").ClearContents
Range("AA134:AA234").ClearContents
Range("AA244:AA334").ClearContents
This then gets repeated for another 11 people, so you can see how cumbersome this gets. How would I go about automating this into a loop to shorten the code and make it easier to edit in the future if small changes needed to be made?
Try this
Sub AdvanceWeek2()
Application.ScreenUpdating = False
Dim var1 As Long, var2 As Long, cnt As Long
Dim rng As Range
var1 = 22 'for Column V
var2 = 100 'random max number
cnt = 13 'no of people
For i = var1 To var2
Range(Cells(24, i), Cells(124, i)).Copy Cells(24, i - 1)
Range(Cells(134, i), Cells(234, i)).Copy Cells(134, i - 1)
Range(Cells(244, i), Cells(334, i)).Copy Cells(244, i - 1)
If i Mod 2 = 1 Then
Union(Range(Cells(24, i), Cells(124, i)), Range(Cells(134, i), Cells(234, i)), Range(Cells(244, i), Cells(334, i))).ClearContents
i = i + 2
cnt = cnt - 1
If cnt = 0 Then Exit For
End If
Next i
Application.ScreenUpdating = True
End Sub
You'll have to start thinking in column numbers rather than column letters.
Column U is column 21 (U being the 21st letter in the alphabet).
You can reference U24 by either using Range("U24") or Cells(24,21) (row 24, column 21).
You reference a range of cells by giving it the first and last cells in the range, so Range(Cells(24,21),Cells(124,21)) will reference U24:U124 and is the same as writing Range("U24:U124").
Now for the looping bit. You want to reference column 21 for Victor, column 25 for Nick, column 29 for the next person, etc. So you'll increase this loop in steps of 4. You also need to reference different columns in each of these loops - moving column 2 to column 1, column 3 to column 2 and clearing column 3.
This bit of code will show how the loop works by printing the values to the immediate window. It will return 21 0, 21 1, 25 0, 25 1, 29 0, 29 1
Sub Test()
Dim x As Long, y As Long
With ThisWorkbook.Worksheets("Sheet1")
For x = 21 To 29 Step 4
For y = 0 To 1
Debug.Print x; y
Next y
Next x
End With
End Sub
These x and y values need to be used in your column references and seeing as you just want the values we can make one range of cells equal the other rather than copy/pastespecial.
Sub Test()
Dim x As Long, y As Long
With ThisWorkbook.Worksheets("Sheet1")
For x = 21 To 29 Step 4
For y = 0 To 1
.Range(.Cells(24, x + y), .Cells(124, x + y)).Value = .Range(.Cells(24, x + y + 1), .Cells(124, x + y + 1)).Value
.Range(.Cells(134, x + y), .Cells(234, x + y)).Value = .Range(.Cells(134, x + y + 1), .Cells(234, x + y + 1)).Value
.Range(.Cells(244, x + y), .Cells(334, x + y)).Value = .Range(.Cells(244, x + y + 1), .Cells(334, x + y + 1)).Value
Next y
.Range(.Cells(24, x + y), .Cells(124, x + y)).ClearContents
.Range(.Cells(134, x + y), .Cells(234, x + y)).ClearContents
.Range(.Cells(244, x + y), .Cells(334, x + y)).ClearContents
Next x
End With
End Sub
Add a watch for the values of X & Y and step through the code using F8. You'll see the values increase to reference the correct columns.
Note I've used the With..End With keywords. This means that each range that starts with a . is referencing Sheet1 of the workbook containing the code (ThisWorkbook).
Edit:
If you want to copy the cells (including formatting, formula, etc) then you can use:
Sub Test()
Dim x As Long, y As Long
With ThisWorkbook.Worksheets("Sheet1")
For x = 21 To 29 Step 4
For y = 0 To 1
.Range(.Cells(24, x + y + 1), .Cells(124, x + y + 1)).Copy Destination:=.Range(.Cells(24, x + y), .Cells(124, x + y))
.Range(.Cells(134, x + y + 1), .Cells(234, x + y + 1)).Copy Destination:=.Range(.Cells(134, x + y), .Cells(234, x + y))
.Range(.Cells(244, x + y + 1), .Cells(334, x + y + 1)).Copy Destination:=.Range(.Cells(244, x + y), .Cells(334, x + y))
Next y
Union(.Range(.Cells(24, x + y), .Cells(124, x + y)), _
.Range(.Cells(134, x + y), .Cells(234, x + y)), _
.Range(.Cells(244, x + y), .Cells(334, x + y))).ClearContents
Next x
End With
End Sub
(that union line could be used in the first example as well).
From your code it doesn't look like the username is important, just the fact there are 12 users.
12 users, 3 weeks...
A quick and minimal code approach is to:
Loop through your code 12 times (once for each user).
Have a nested loop for the 3 weeks per user, applying an offset to a base (or starting) column for each copy and paste operation.
Sub AdvanceWeek2()
Application.ScreenUpdating = False
Dim intLoopUser As Integer
Dim intLoopWeek As Integer
Dim rngBase As Range
Set rngBase = ActiveSheet.Range("V24:V124")
For intLoopUser = 0 To 35 Step 3 '12 Users, change the Step as required, looked like 3 from your code, maybe 4
For intLoopWeek = 0 To 2 '3 weeks
Select Case intLoopWeek
Case 0 'Week 1
rngBase.Offset(0, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(0, intLoopUser + intLoopWeek).Value
rngBase.Offset(110, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(110, intLoopUser + intLoopWeek).Value
rngBase.Offset(210, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(210, intLoopUser + intLoopWeek).Value
Case 1 'Week 2
rngBase.Offset(0, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(0, intLoopUser + intLoopWeek).Value
rngBase.Offset(110, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(110, intLoopUser + intLoopWeek).Value
rngBase.Offset(210, (intLoopUser + intLoopWeek) - 1).Value = rngBase.Offset(210, intLoopUser + intLoopWeek).Value
Case 2 'Week 3
rngBase.Offset(0, (intLoopUser + intLoopWeek) - 1).ClearContents
rngBase.Offset(110, (intLoopUser + intLoopWeek) - 1).ClearContents
rngBase.Offset(210, (intLoopUser + intLoopWeek) - 1).ClearContents
End Select
Next intLoopWeek
Next intLoopUser
Application.ScreenUpdating = True
End Sub
Trying to solve an equation using excel-vba,
Equation:
xy = 5(x+y)
I use the below vba code to determine the values of x and y and print it in cell A1
Sub equation()
Dim x As Long, y As Long
For x = 1 To 9
For y = 1 To 9
If ((x * y) = (5 * (x + y))) Then
Range("A1") = x & "," & y
End If
Next y
Next x
End Sub
However this code is not working. I guess I am missing something in the IF condition.
I tried the below and this works perfectly,
Sub equation()
Dim x As Long, y As Long
For x = 1 To 9
For y = 1 To 9
If 5 * (x + y) = 45 Then
Range("A1") = x & "," & y
End If
Next y
Next x
End Sub
I even tried with 2 temp variables, but doesn't works,
Sub equation()
Dim x As Long, y As Long, temp1 As Long, temp2 As Long
For x = 1 To 9
For y = 1 To 9
temp1 = x * y
temp2 = 5 * (x + y)
If temp1 = temp2 Then
Range("A1") = x & "," & y
End If
Next y
Next x
End Sub
Can someone tell me what I am doing wrong with the IF condition.
Consider:
xy = 5(x+y)
xy = 5x+5y
xy-5y = 5x
y(x-5) = 5x
y = 5x/(x-5)
Then just plug in values for x and solve for y
Sub qwerty()
Dim x As Long, y As Long
For x = 6 To 13
y = 5 * x / (x - 5)
Cells(x, 1) = x
Cells(x, 2) = y
Next x
End Sub
Pick any values for x, just avoid x = 5.Declare y as Double if you require the fractional part:
Please help me to fix this,
Requirement:
Pasting data from sheet 1 to sheet x and skip to next page.
Problem:
I am unable to run the loop between 2 integers at a time.
I want to run the loop between x and y every time.But the written code is finishing x first and the going to y.
Please check below code and help me with u r ideas. Thank you.
Sub sbCopyValueToAnotherSheet()
Dim x As Integer
Dim y As Integer
For y = 2 To 11
For x = 2 To 50
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("F6")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("P6")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("P7")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("F8")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("P8")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("F9")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy Destination:=ActiveSheet.Range("P9")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy
Destination:=ActiveSheet.Range("F10")
y = y + 1
Sheets("Sheet1").Cells(x, y).Copy
Destination:=ActiveSheet.Range("P10")
y = y + 1
ActiveSheet.Next.Select
Next x
Next y
End Sub
If you are trying to copy 50 rows from Sheet1 into the same cells on 50 different sheets, try this:
Option Explicit
Public Sub sbCopyValueToAnotherSheet()
Dim x As Long, wsM As Worksheet, wsCount As Long
wsCount = ThisWorkbook.Worksheets.Count
Set wsM = ThisWorkbook.Worksheets("Sheet1")
For x = 2 To 50
With ThisWorkbook.Worksheets(x)
.Range("F6") = wsM.Cells(x, 2)
.Range("F7") = wsM.Cells(x, 3)
.Range("F8") = wsM.Cells(x, 4)
.Range("F9") = wsM.Cells(x, 5)
.Range("F10") = wsM.Cells(x, 6)
.Range("P6") = wsM.Cells(x, 7)
.Range("P7") = wsM.Cells(x, 8)
.Range("P8") = wsM.Cells(x, 9)
.Range("P9") = wsM.Cells(x, 10)
.Range("P10") = wsM.Cells(x, 11)
End With
If x = wsCount Then Exit Sub
Next
End Sub