I have a question regarding excel vba and the use of the "IF" function with the "For" cycle. I will try to be as clear as possible.
here is the code:
sub cicleFor()
For i= 1 to 2
Calculate
Range("E3").Select
Selection.Copy Sheets("Sheet2").Select Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Sheet1").Select
Range("C14").Select
Next
It is pretty simple! I take E3, copy paste into another cell (A2) for two times.
I use calculate at the start because the number in E3 will change each time
What I would like to have is the following:
to use an "IF" function that, if A2 is full, goes to A3 and so on, for i = 1 to 100.
since I have used a for function, i want A2,A3,A4,...A100 to be filled with the result of E3 of the sheet1.
I am not an expert as you can see!
if you have any hint, I will be grateful!
Thank you!
EDIT to add the case of multiple cells
maybe you're after this
Sub cicleFor()
For i = 1 To 100
Calculate
Sheets("Sheet2").Cells(1 + i, 1).Value = Sheets("Sheet1").Range("E3").Value
Next
End Sub
if you need to copy/paste the content of more than one cell then you want to use Resize(nRows, nColumns) property of Range object to properly adjust the "target" range size to fit the "source" one
for instance to copy/paste the content of range "E3:H3" (i.e. four columns) you want to use:
Sub cicleFor()
For i = 1 To 100
Calculate
Sheets("Sheet2").Cells(1 + i, 1).Resize(,4).Value = Sheets("Sheet1").Range("E3:H3").Value
Next
End Sub
Your code could be much shorter - no need for select/copy/paste if you only want to transfer the values. Use End(xlUp) to locate the last used cell.
Sub cicleFor()
For i= 1 to 2
Calculate
Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = _
Sheets("Sheet1").Range("E3").Value
Next
End Sub
Related
I have a vba script that uses a for loop to copy rows to columns, but this method is very slow when running. Is there a faster way of accomplishing this.
As you can see below, I have data in the 'my data' row and I need each of the rows copied and pasted to the next column to the right. For example, the 1 needs to be copied and pasted all the way to the columns to the right from range(X44:AY44) and so on.
Below is the script that works, but it is too slow for processing.
Sub CopyPasteSV4_SV30()
Dim r As Range, cell As Range
Dim i As Integer
i = 44
For Each cell In Range("X44:X63")
Range("X" & i).Select
Selection.Copy
Range("Y" & i, Range("AY" & i)).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
i = i + 1
Next cell
End Sub
There is no need to loop, use Select, or use .Copy/.PasteSpecial. Use value transfer.
Range("Y44:AY63").Value = Range("X44:X63").Value
I'm relatively new to VBA and have some code I wrote that seems like it should be straightforward but is not behaving as expected. I am trying to separate my primary WorkSheet (GAWi) into three other worksheets (LWi, WMi, & OTi) based on the first letter in column H. Basically if the first letter is "L" I want that row to be copied and pasted onto sheet LWi and then deleted from the original sheet. Then if it is W it goes onto WMi and if it is A it goes onto OTi. It is functioning properly for the first two If statements (placing items that begin with L & W onto the correct sheets), but for the last one items that begin with P and 0 are also being placed onto sheet OTi. I'm at a complete loss, it seems pretty easy and I can't figure out where I went wrong. Any advice would be much appreciated, also I'm sure this code is pretty unelegant by most standards so any tips on how to shorten it would also be welcomed-I've just started getting into VBA in the last couple weeks. Thank so much!
Sheets("GAWi").Select
Columns("H:H").Select
Dim lwr As Range
Set lwr = ActiveSheet.UsedRange
For i = lwr.Cells.Count To 1 Step -1
If Left(lwr.Item(i).Value, 1) = "L" Then
lwr.Item(i).EntireRow.copy
Sheets("LWi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If
If Left(lwr.Item(i).Value, 1) = "W" Then
lwr.Item(i).EntireRow.copy
Sheets("WMi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If
If Left(lwr.Item(i).Value, 1) = "A" Then
lwr.Item(i).EntireRow.copy
Sheets("OTi").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
ActiveCell.Offset(1, 0).Select
Sheets("GAWi").Select
lwr.Item(i).EntireRow.Delete
End If Next i
there's a main flaw in your logic: the use of UsedRange
despite being it a 2D range, its Item() property would act as if it were a 1D array with one row listed after another
so that were "A1:H10" (eight columns) the address of UsedRange, UsedRange.Item(1) would point to "A1", UsedRange.Item(8) would point to "H1" and UsedRange.Item(9) would point to "A2" …
so you have to loop through the cells of column H only
Then there's a coding flaw, which is the use of all those Select/Selection: get in the habit of always use explicit range reference qualified up to their parent worksheet and workbook
. This can be reached, for instance, with the use of With... End With construct
here's a possible code (explanations in comments):
Option Explicit
Sub TransferRows()
Dim i As Long
With Sheets("GAWi") ' reference "source" sheet
For i = .Cells(.Rows.Count, "H").End(xlUp).Row To 1 Step -1 ' loop backwards from referenced sheet column H last not empty cell row index to 1
Select Case UCase(.Cells(i, "H").Value) ' check for referenced sheet column H current row content
Case "L"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("LWi") ' pass referenced sheet current row "used" range and "LWi" destination sheet to the helper sub
Case "W"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("WMi") ' pass referenced sheet current row "used" range and "WMi" destination sheet to the helper sub
Case "A"
TransferRow Intersect(.UsedRange, .Rows(i)), Sheets("OTi") ' pass referenced sheet current row "used" range and "OTi" destination sheet to the helper sub
End Select
Next i
End With
End Sub
Sub TransferRow(sourceRng As Range, destSht As Worksheet)
With destSht
.Cells(.Rows.Count, 1).End(xlUp).Offset(1).Resize(, sourceRng.Columns.Count).Value = sourceRng.Value
End With
sourceRng.Delete xlUp
End Sub
As you see, other than the amendements due to the preface explanations I put in there:
the use of Select Case syntax instead of If Then End If
which I think is much clearer and would also correct a minor logic flaw of your orginal code: once a check is positive there's no need to run other ones (this you could have obtained by means of If - Then - ElseIf - Endif construct)
the use of a "helper" sub to demand the repetitive code to
which gives you much more control over your code and helps its maintenance
the use of Cells(Rows.Count, colIndex).End(xlUp) pattern
which is the most frequently used one to get the reference to the last not empty cell in some colIndex (be it a number or a letter) column
Thanks to HTH's great response I was able to clean up my code a bit and think I got it figured out. I opted to stick with the If Then Else If format since I am not too familiar with using Case yet. Here's the first section of it, I just repeated the copy, paste, delete row for each starting letter.
Set rng = Range("GAWi!H:H")
For k = rng.Cells.Count To 1 Step -1
If Left(rng.Item(k).Value, 1) = "W" Then
With rng.Item(k)
.EntireRow.copy
Sheets("WMi").Activate
ActiveCell.Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
.EntireRow.Delete
End With
ElseIf Left(rng.Item(k).Value, 1) = "L" Then....
This is running well for my purposes but if anyone has more suggestions they are much appreciated.
I am new to VBA and macros and want to learn it by automating parts of my "timesheet tracking" Excel.
The idea is that I always enter the new calendar week in a cell as a reminder (so this is done manually).
What the macro shall do:
1) copy the cell which sums up all my worked hours (so one specific cell). This value is in worksheet "Week Timesheet"
2) Go and take this value, look in another worksheet ("Year Overview") if this value (the calendar week number) is in a range (the range is a list of each calendar week, so 1 up to 52, it is column A) and if so paste the copied value in the column C.
Can you help me with that? Below the code I started to do.
Thanks for your help!
Sub
If Worksheets("Week Timesheet").Range("K6").Value = Worksheets("Year Overview").Range("A2:53").Value Then
Worksheets("Week Timesheet").Range("I37").Select
Selection.Copy
Sheets("Year Overview").Select
Range("C11").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
End Sub
I'm not sure if I understood right. You want to copy the week value everytime in Cell("C11")? So the value gets overwritten everytime. You better want the value to be summed up, right? I made two versions, hope it helps you:
Version (1): overwrite cell ("C11")
Version (2): summ up cell ("C11")
Sub insertworkinghours()
Dim i As Integer
For i = 1 To 52
If Worksheets("Week Timesheet").Range("K6").Value = Worksheets("YearOverview").Cells(1, 1 + i).Value Then
Worksheets("Year Overview").Range("C11").Value = Worksheets("Week Timesheet").Range("I37").Value '(Version 1)
Worksheets("Year Overview").Range("C11").Value = Worksheets("Year Overview").Range("C11").Value + Worksheets("Week Timesheet").Range("I37").Value '(Version 2)
End If
Next
End Sub
I'm making my first macro in order to save having to perform 2500 copy-pastes. I have a long and complicated worksheet that takes two variables as inputs and returns a single value, and another sheet with 2500 pairs of these variables.
To keep things in the same sheet, I've linked the formula sheet inputs to J2 and K2 on my variable sheet, and the output to L2. My goal is to populate a third column next to the first two with the results for that row, by copying the two values to J2 & K2, then copying from L2 to the appropriate cell in the third column. As my macro is currently, it returns to the same cell in the third column every time, based on an offset from L2 as the last active cell.
I've tried searching for help on how to either increment the last paste operation, or to keep the active cell referencing the start point of the macro in order to keep things in the same row, but was unsuccessful. Any help would be appreciated.
ActiveCell.Range("A1:B1").Select
Selection.copy
Range("J2:K2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("L2").Select
Application.CutCopyMode = False
Selection.copy
ActiveCell.Offset(43, -5).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sub TT()
Dim sht As Worksheet, c As Range
Set sht = ActiveSheet
For Each c In sht.Range("A1:A2500").Cells
sht.Range("J2").Value = c.Value
sht.Range("K2").Value = c.Offset(0, 1).Value
sht.Calculate
c.Offset(0, 2).Value = sht.Range("L2").Value
Next c
End Sub
Hello hope all is well :)
having trouble figuring out how to loop and select next cell
so when a cell in the range h3:z3 is empty it would stop :)
and what it is doing is selecting the value from h3 pasteing in b3 runs a another macro which gives an order number in e3 which is then copied and pasted in h4 then it would go to the next cell in I3 paste in b3 copy result from e3 and paste in I4 and do the same
thanks
For Each cell In Range("H3:Z3")
If IsEmpty(cell.Value) Then Exit For
'select ammount and place in lookup
Range("H3").Select
Selection.Copy
Range("B3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
' fill in order numbers
bulkON_Click
'select order and past under postcode
Range("E3").Select
Application.CutCopyMode = False
Application.CutCopyMode = False
Selection.Copy
Range("H4").Select
ActiveSheet.Paste
Loop
There's a lot that I would probably change in this code. This should get you started.
For starters, a For loop requires a Next statement, not a Loop (which is used for Do blocks. Also, you should avoid copying/pasting at all costs, in favor of writing values directly to the destination cell(s).
I assume that cells "B3" and "E3" are constant, and you are iterating over cells in H3:Z3 and computing some value to put in corresponding cell in H4:Z4.
For Each Cell In Range("H3:Z3")
If Cell.Value = vbNullString Then Exit For
'select ammount and place in lookup
Range("B3").Value = Cell.Value '<< no need to "copy & paste", just write the value directly
' fill in order numbers
bulkON_Click
'insert the value under postcode
' this OFFSET refers to the cell 1 row below the "Cell"
Cell.Offset(1, 0).Value = Range("E3").Value
Next