So I have a column A where the cells from 143 to 179 can be filled in with data if required. The loop takes the data from A and removes cells that have not been filled in getting rid of all the spaces (apart from a few listed required for formatting) and puts them into column C.
So, problem is that the script copies from 143 to 179 even if only 4 of the cells were filled in which looks strange when copied onto our system as there is a massive space. Is there a way to have it so it just copies/selects what's filled in, ex C143:"C"&counter ?
For i = 143 To 179
If i = 163 Or i = 165 Or i = 174 Then counter = counter + 1
If Cells(i, 1).Value <> "" Then
Cells(counter + 143, 3).Value = Cells(i, 1).Value
counter = counter + 1
End If
Next i
Range("C143:C179").Select
Selection.Copy
Your question is a bit unclear, but if you just want to copy the cells that have values in column A, to column c, starting from cell C1, this could do the job. I am not sure why you wanted to skip some of the rows, but I commented that out, however if you really need that you can bring it back to the code.
Sub test()
Dim i As Integer
Dim WS As Worksheet
Set WS = ActiveSheet
counter = 1
For i = 143 To 179
'If i = 163 Or i = 165 Or i = 174 Then counter = counter + 1
If WS.Cells(i, 1).Value <> "" Then
WS.Cells(counter, 3).Value = WS.Cells(i, 1).Value
counter = counter + 1
End If
Next i
WS.Range("C1:C" & counter - 1).Select
Selection.Copy
End Sub
Set the value up as a variable. Something like this:
For i = 143 To 179
If i = 163 Or i = 165 Or i = 174 Then counter = counter + 1
If Cells(i, 1).Value <> "" Then
Cells(counter + 143, 3).Value = Cells(i, 1).Value
counter = counter + 1
End If
Next i
lastrow1 = Cells(Rows.Count, "A").End(xlUp).Row
Range("C143:C" & lastrow1).Select
Selection.Copy
Related
I would like to ask how to SUM the values quickly, when they are separated 30 rows from each other?
I would like to sum 9 values and input the result in different column as per the code below:
Sub sum()
Range("EG12").Formula = "=Sum(C12,C282, C552, C822,C1092,C1362,C1632,C1902,C2172,C2442)"
Range("EG42").Formula = "=Sum(C42,C312,C582, C852,C1122,C1392,C1662,C1932,C2202,C2472)"
Range("EG72").Formula = "=Sum(C72,C342,C612, C882,C1152,C1422,C1692,C1962,C2232,C2502)"
Range("EG102").Formula = "=Sum(C102,C372,C642,C912,C1182,C1452,C1722,C1992,C2262,C2532)"
End Sub
Where as you may have notice every destination cell is located exactly 30 rows between each other (inner rows are empty or contains different values) likewise copied cells, that are located exactly 270 rows between each other (see the image attached).
I was trying to do formula like this:
Sub sum2()
Dim lastrow As Long, i As Integer, total As Double, finalsum As Double
lastrow = Range("C2442").End(xlUp).Row
For i = 30 To lastrow
total = total + WorksheetFunction.sum(Range("C12" & i & "EG12" & i))
Next
finalsum = total
End Sub
...but I've got "Method 2Range of object2_Global failed.
Does somebody have some idea about this?
Thanks & regards,
I didn t make it that pretty with the 170 sum but you should understand the point like this:
Sub test2()
Dim lastrow As Long, i As Long, finalsum As Long
lastrow = Range("C2442").End(xlUp).Row
finalsum = 0
For i = 12 To lastrow Step 30
Range("E" & i).Value = WorksheetFunction.Sum(Cells(i, 3).Value, Cells(i + 170, 3).Value, Cells(i + 2 * 170, 3).Value, Cells(i + 3 * 170, 3).Value, Cells(i + 4 * 170, 3).Value, Cells(i + 5 * 170, 3).Value, Cells(i + 6 * 170, 3).Value, Cells(i + 7 * 170, 3).Value, Cells(i + 8 * 170, 3).Value, Cells(i + 9 * 170, 3).Value)
finalsum = finalsum + Range("E" & i).Value
Next i
End Sub
Try it with loops and unions.
Option Explicit
Sub sum30by270()
Dim i As Long, j As Long, lr as long
Dim r1 As Range, r2 As Range
With Worksheets("sheet2")
lr = .cells(.rows.count, "C").end(xlup).row
Set r1 = .Cells(12, "C")
For i = 282 To lr Step 270
Set r1 = Union(r1, .Cells(i, "C"))
Next i
'Debug.Print r1.Address(0, 0)
Set r2 = .Cells(12, "EG")
For j = 42 To 102 Step 30
Set r2 = Union(r2, .Cells(j, "EG"))
Next j
'Debug.Print r2.Address(0, 0)
r2.Formula = "=sum(" & r1.Address(0, 0) & ")"
End With
End Sub
Few remarks:
lastrow = Range("C2442").End(xlUp).Row
is not the right usage, you might want to change it to:
'going from specified cell down until empty cell is met
lastrow = Range("C2442").End(xlDown).Row
or
'going from last cell in C column up, until first non-empty cell is met
lastrow = Range(Rows.Count, 3).End(xlUp).Row
Second issue, if you want to loop every 30 rows, you should do it like this (also remember about proper indentation of your code!):
For i = 12 To lastrow Step 30
total = total + WorksheetFunction.Sum(Range(Cells(i, 1), Cells(i, 5)))
Next
finalsum = total
"C12" & i & "EG12" & i - & operator is a string concatenation, not addition, this is why you might get unexpected result.
Well, thank you all guys for our contribution. I would like to add final working formula for this issue:
Sub sum_1to10()
Dim i As Long, j As Long, lr As Long
Dim r1 As Range, r2 As Range
With Worksheets("13")
lr = .Cells(.rows.Count, "C").End(xlUp).Row
Set r1 = .Cells(12, "C") 'First cell with data in my worksheet - [![enter image description here][1]][1] C12
For i = 12 To 2442 Step 270 ' From 1st cell with data to 10th cell in this order C2442
'When put "lr" instead 2442 the values will be calculated as per all worksheet data included (in my case it was down to 8377
Set r1 = Union(r1, .Cells(i, "C"))
Next i
Set r2 = .Cells(12, "Eh")
For j = 12 To 1086 Step 30 'First subsequent cell with data with 30 rows step e.g C42, C72, etc
' Value 1086 correspond to the last row in label with sum
Set r2 = Union(r2, .Cells(j, "EG"))
Next j
r2.Formula = "=sum(" & r1.Address(0, 0) & ")"
End With
End Sub
Hopefully I have understood it well.
I decided to modify this formula in order to divide my calculation on 3 separate parts. I am making these bulk calculation for every month, and I have divided it for 3 decades.
I'm trying to implement a nested for and a nested if statement together. I have the following column below. It needs to look at the column if the range is between 500-1000 it should give recommendation a (i.e. write the recommendation in another column) if it is more than 1000 it should give another recommendation in the responding column.
Income Recommendation
550 a
1200 b
750 a
1400 b
600 a
Dim i As Integer
Dim j As Integer
For i = 2 To Range(i, 1).End(xlDown).Row
If Cells(i, 1).Value > 1000 Then
Cells(i, 10).Value = "b"
i = i + 1
Else
If Cells(i, 1).Value < 1000 Then
If Cells(i, 1).Valie > 500 Then
Cells(i, 10).Value = "a"
End If
End If
i = i + 1
End If
Next i
End Sub
Several errors:
Don't rely on i having a value while it is setting the start and end values of the For loop - there is a good chance that it is 0 while calculating Range(i, 1). (Edit: Tested and confirmed that it is still 0 at the point when the end value is being calculated.) Using Range(0, 1) will give a 1004 error.
Don't increment the loop counter within the loop (i.e. don't do i = i + 1) - it will almost certainly confuse things. If you really only want to process every second row, use Step 2 on the For statement.
.Valie should be .Value
Don't use Integer data types for rows - these days Excel can handle 1048576 rows, which is more than an Integer can cope with.
Range(1, 1) is invalid syntax. When passing two parameters to the Range property, they need to be cell references. Passing a row and column is what is used when using the Cells property. (So Range(1, 1) will need to be Cells(1, 1), or Range("A1").)
Refactoring your code would give:
Dim i As Long
For i = 2 To Cells(1, "A").End(xlDown).Row
If Cells(i, "A").Value > 1000 Then
Cells(i, "J").Value = "b"
ElseIf Cells(i, "A").Value > 500 Then
Cells(i, "J").Value = "a"
Else
Cells(i, "J").Value = ""
End If
Next i
End Sub
You can do it like this with Select Case:
Public Sub TestMe()
Dim i As Long
Dim j As Long
With ActiveSheet
For i = 2 To .Cells(1, 1).End(xlDown).Row
Select Case True
Case .Cells(i, 1) > 1000
.Cells(i, 10) = "b"
Case .Cells(i, 1) < 1000 And .Cells(i, 1) > 500
.Cells(i, 10).value = "a"
End Select
Next i
End With
End Sub
It is more visible and a bit more understandable. Also, make sure that you refer to the Worksheet (in this case with ActiveSheet), to avoid reference problems in the future.
I want to run loop on the same workbook, but it also give me nothing. But If I run this VBA directly on the workbook (CGDSOUSD), it works well. So I am wondering how to run VBA after let VBA open a new file.
Dim rownumber As Integer
Dim colnumber As Integer
Dim total As Double
colnumber = 1
For colnumber = 1 To 23
If Cells(8, colnumber) = "DELTA" Then
total = 0
rownumber = 9
Do Until Cells(rownumber, colnumber) = "" And Cells(rownumber + 1, colnumber) = "" And Cells(rownumber + 5, 1) = ""
If Cells(rownumber, 1) = "" And (Cells(rownumber, 7).Value = "DSO TROPS" Or Cells(rownumber, 8).Value = "DSO TROPS" Or Cells(rownumber, 6).Value = "DSO TROPS") Then
total = total + (Cells(rownumber, colnumber).Value)
Else
End If
rownumber = rownumber + 1
Loop
Else
End If
colnumber = colnumber + 1
Next colnumber
total = Round(total, 2) 'will be imputed into E20 in risk tools
MsgBox total
Maybe Do Until is False.
To iterate through cells I always determine the lastrow and use a for loop.
See basic example below.
ps: use ActiveCell and activate one.
'place a value in cell A1 to A4 for test.
Sub test()
Dim lastrow As Long
lastrow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastrow
If Cells(i, 1) <> "" Then
Cells(i, 2).Value = "not empty"
End If
Next i
End Sub
I am doing automation on matching Data form row Data1 to Data 2,
I was done by looping statement but the problem is take much time, when number of row increase
For that reason i planed do by vlookup, In vlookup only return first occurrence cell but i need to find all match cell and highlighted matched row ,which i show in figure.
Working with cells directly reduces the code performance. Try to set Data1 and Data2 to arrays and work with arrays.
Something like this:
With ActiveSheet
arr = .Range(.[A2], .Cells(.Rows.Count, "A").End(xlUp)).Value
arr2 = .Range(.[D2], .Cells(.Rows.Count, "D").End(xlUp)).Value
For i& = 1 To UBound(arr)
For j& = 1 To UBound(arr2)
If arr(i, 1) = arr2(j) Then
...
End If
Next j
Next i
End With
Hope you are looking for this
Sub testvlookup()
Dim lastrow, lastrowdata, incre, i, j As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
lastrowdata = Range("D" & Rows.Count).End(xlUp).Row
incre = 6
For i = 2 To lastrow
For j = 2 To lastrowdata
If Range("A" & i).Value = Range("D" & j).Value Then
Range("D" & j, "G" & j).Interior.ColorIndex = incre
End If
Next j
incre = incre + 1
Next i
End Sub
I don't see the point why it should be to slow for many rows, it would be good to have more informations about that.
I would do it like the others, takes ~1 sec with 100000 comparisons.
Dim i As Integer
Dim b As Integer
i = 1
While i < 20000
Range("A1:A5").Copy Range(Cells(i, 4), Cells(i + 5, 4))
i = i + 5
Wend
MsgBox ("hi")
i = 1
While i < 7
b = 3
While b < 20000
If Cells(i, 1).Value = Cells(b, 4).Value Then
Cells(b, 4).Interior.ColorIndex = i
End If
b = b + 1
Wend
i = i + 1
Wend
End Sub
I having a problem on the code below.
On row 130 i need to insert blank rows equal to the value in J.
The code now is inserting blank rows equal to J but is starting on row J. I need to start on row k and then insert blank rows of J. How do I define the starting row and the number of blank rows?
70 j = ws1.Cells(ws1.Rows.Count, "E").End(xlUp).Row
80 k = 2
90 x = 1
100 Do While x < j
110 With ws2
120 If j > 0 Then
'Insert J number of rows starting on row = k
130 .Rows(j).Resize(LastRow).Insert
140 For i = 2 To rngtocopy.Rows.Count
150 With ws2.Range("K" & k)
160 .Offset(0, 0).Value = rngtocopy(i, 1)
170 .Offset(0, 1).Value = rngtocopy(i, 2)
180 End With
190 k = k + 1
200 Next i
210 End If
220 End With
230 x = x + 1
240 Loop
I don't know if I understand your question correctly, but try this:
Set ws1 = Sheets("Calc")
Set ws2 = Sheets("Dealer Orders")
LastRow = ws1.Cells(ws1.Rows.Count, "E").End(xlUp).Row
Set rngtocopy = ws1.Range("E2", ws1.Cells(LastRow, "F"))
For i = 1 To rngtocopy.Rows.Count
With ws2.Range("K2")
.Resize(, 2).Insert xlDown
.Offset(-1, 0).Value = rngtocopy(i, 1)
.Offset(-1, 1).Value = rngtocopy(i, 2)
End With
Next
Is this somehow what you're trying? HTH.