'Excel VBA: create a nested loop and save output for each value in range
I am trying to create a nested loop to input the values in Range("E2:E6") into Cell ("B3") & values in range ("F2:F6") in cell ("B2"). And then record the results from Range("I2:j2") to Sheet2.
This answer (Excel VBA: How to create loop and save output for each value in range?) was a great help in first tackling the problem but I have become stuck as how how I may paste the 25 (5*5) possible resulting values of Range("I2:j2") to Sheet2
Any help much appreciated!
Sub Nested_Loop()
'
'
'
gg = 1
Dim myRange As Range
Dim myRange2 As Range
Dim i As Long, j As Long, h As Long
Worksheets("Sheet1").Activate
Set myRange = Range("E2:E6")
Set myRange2 = Range("F2:F6")
For h = 1 To myRange2.Rows.Count
For i = 1 To myRange.Rows.Count
For j = 1 To myRange.Columns.Count
myRange.Cells(i, j).Select
Selection.Copy
Range("B3").Select
ActiveSheet.Paste
myRange2.Cells(h, j).Select
Selection.Copy
Range("B2").Select
ActiveSheet.Paste
Range("I2:j2").Select
Application.CutCopyMode = False
Selection.Copy
Worksheets("Sheet2").Activate
Worksheets("Sheet2").Cells(i + 1, j + gg).Select 'I want to paste all 25 values (5 possible inputs for each variable(2)). Currently the loop only prints 5 results and then pastes over itself
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next j
Worksheets("Sheet1").Activate
Next i
Worksheets("Sheet1").Activate
Next h
End Sub
Solution 1:[1]
Try to avoid .Select & .Activate. Instead declare wb, ws and rng properly and we can do without copy/paste as well (if you're only interested in values, surely). For guidance, see: How to avoid using Select in Excel VBA. Use rng1.value = rng2.value. It is much faster.
I think that you got a bit confused about how many loops you need. I think you only need one for myRange and a nested one for myRange2 (both on the rows).
Finally, try to use "sensical" variable names; this helps your users (e.g. counter instead of gg).
Below code should hopefully work. (Perhaps a nice challenge to see if you can simply include the calculations that apparently go on in ws.Range("I2:J2") inside the code...)
Sub Nested_Loop()
Dim wb As Workbook
Dim ws As Worksheet, ws2 As Worksheet
Dim myRange As Range, myRange2 As Range, destRange As Range
Dim i As Long, j As Long, counter As Long
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet1")
Set ws2 = wb.Sheets("Sheet2")
Set myRange = ws.Range("E2:E6")
Set myRange2 = ws.Range("F2:F6")
'set destination range; "B2" as start inferred from original code
Set destRange = ws2.Range("B2").Resize(25, 2) 'i.e. .Resize(5*5=25rows,1+1=2cols)
counter = 0
'loop first range = 1 to 5
For i = 1 To myRange.Rows.Count
'nested -> 5*5
For j = 1 To myRange2.Rows.Count
'use .value = .value instead of copy/paste
ws.Range("B3").Value = myRange.Cells(i).Value
ws.Range("B2").Value = myRange2.Cells(j).Value
'with .value = .value we don't need to leave the activeworksheet
Range(destRange.Cells(1 + counter, 1), destRange.Cells(1 + counter, 2)).Value = ws.Range("I2:J2").Value
'increment counter to go to next row in destRange
counter = counter + 1
Next j
Next i
End Sub
Solution 2:[2]
Couple items that could work for you:
dim ws1 as worksheet
set ws1 = thisWorkbook.Sheets(1)
dim ws2 as worksheet
set ws2 = thisWorkbook.Sheets(2)
dim rowNum as long
for rowNum = 1 to 5
dim colNum as long
for colNum = 1 to 5
With ws1
.Cells(rowNum,colNum).Copy .Cells(2,2)
.Range(.Cells(2,9),.Cells(2,9+1)).Copy ws2.Range(ws2.Cells(rowNum,colNum*2),ws2.Cells(rowNum,colNum*2+1)
End With
next colNum
next rowNum
- Use variables that mean something; make it a habit now, so you're not correcting A, J, K, I, etc., down the road
- Qualify all of your ranges; note how much more complex the destination on
ws2is compared to myWith ws1 - I used multiplication on the column number in the paste destination range, which will prevent overwriting data
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ouroboros1 |
| Solution 2 | Cyril |
