I am new to VB and facing some issues to iterate through. below is my code and i want to iterate the if statement more than once.
Sub Refresh_Data()
On Error Resume Next
A = Worksheets("DATA").Cells(Rows.Count, 4).End(xlUp).Row
Dim x As String
x = 9550
For i = 1 To A
If Worksheets("DATA").Cells(i, 1).Value = x Then
Worksheets("DATA").Rows(i).Copy
Worksheets(x).Activate
B = Worksheets(x).Cells(Rows.Count, 4).End(xlUp).Row
Worksheets(x).Cells(B + 1, 1).Select
ActiveSheet.Paste
Worksheets("DATA").Activate
x = x + 50
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("DATA").Cells(1, 1).Select
End Sub
You are clearly making some rookie mistakes in your code, let me make some first corrections, and from there please tell us if you still have problems and in case yes, which ones:
Sub Refresh_Data()
' On Error Resume Next (do not use this, it is masking errors instead of solving them)
Dim A As Long
Dim B As Long ' not only A, also B
Dim x As Long ' x is not a string, but a number
Dim i As Long ' you forgot about i
A = Worksheets("DATA").Cells(Rows.Count, 4).End(xlUp).Row
x = 9550
For i = 1 To A
If Worksheets("DATA").Cells(i, 1).Value = x Then
Worksheets("DATA").Rows(i).Copy
Worksheets(x).Activate
B = Worksheets(x).Cells(Rows.Count, 4).End(xlUp).Row
Worksheets(x).Cells(B + 1, 1).Paste ' you can paste here directly, no reason to select first.
Worksheets("DATA").Activate
x = x + 50
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("DATA").Cells(1, 1).Select
End Sub
Related
I am trying to get this to work so that the variable sheet_number that is used for the for loop goes back to 1 every time the conditions are met in the if statement inside the for loop but I am unsure if this happens, as the program doesn't fill in all the sheets like I want it to do. Below is my code.
Sub Luka_Koper()
Dim i As Integer, j As Integer, imena As Integer, sheet_number As Integer, n As Integer, x As Integer, y As Integer
n = 8
For sheet_number = 1 To Application.Sheets.Count
If Sheets("ZBIR UR").Cells(n, 2).Value = Sheets(sheet_number).Cells(1, 1).Value Then
i = 3
j = 4
x = n + 1
y = n + 2
For j = 4 To 32
Worksheets("ZBIR UR").Cells(n, i).Copy
Worksheets(sheet_number).Cells(j, 2).PasteSpecial Paste:=xlPasteFormulas
Worksheets("ZBIR UR").Cells(x, i).Copy
Worksheets(sheet_number).Cells(j, 3).PasteSpecial Paste:=xlPasteFormulas
Worksheets("ZBIR UR").Cells(y, i).Copy
Worksheets(sheet_number).Cells(j, 4).PasteSpecial Paste:=xlPasteFormulas
i = i + 1
Next j
sheet_number = 1
n = n + 3
Else
If n > 500 Then
Exit Sub
End If
End If
Next sheet_number
End Sub
I'm not sure if this works, but I would heavily disadvise it: a for-loop is known as a kind of counter: you know where it starts, that it proceeds one by one (or step by step) until the last value is reached.
If you want to change that value inside the loop itself, I would advise a while-loop instead, something like:
sheet_number = 1
do while sheet_number <= Application.Sheets.Count
...
if <condition>
then sheet_number = 1 ' IMPORTANT: THIS MIGHT CAUSE AN INFINITE LOOP!!!
end if
...
sheet_number = sheet_number + 1
loop
I think you have your logic set up the wrong way around, sort of putting the cart before the horse. You aren't picking data from "ZBIR UR" to match each tab. Instead, you are distributing all data from "ZBIR UR" to designated sheets. Therefore you shouldn't loop through all the sheets in the workbook (not the Application) but through all the rows in "ZBIR UR". Of course, I have no good proof for my assumption but below is the what the code would look like if I were right. You may like to try it.
Sub Luka_Koper()
' 114
Dim Ws As Worksheet ' loop object: Worksheets
Dim LookFor As Variant ' Sheets("ZBIR UR").Cells(n, 2).Value
Dim Rl As Long ' last row in "ZBIR UR"
Dim R As Long ' loop counter: Rows
With Worksheets("ZBIR UR")
Rl = .Cells(.Rows.Count, 2).End(xlUp).Row
For R = 8 To Rl Step 3
LookFor = .Cells(R, 2).Value ' don't ref sheet multiple times
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> .Name Then ' all sheets except "ZBIR UR"
If Ws.Cells(1, 1).Value = LookFor Then
Range(.Cells(R, 3), .Cells(R + 2, 29)).Copy
Ws.Cells(4, 4).PasteSpecial Paste:=xlPasteFormulas
End If
End If
Next Ws
Next R
End With
End Sub
The question refers to "For...Next" loop that starts with loop var = 1
For i = 1 To n
If [condition] = True Then
i = 0 ' This will restart the loop at i = 1 from the next iteration
Else
..... ' Whatever you would normally execute
End if
Next
Adjust/modify this to your particular needs.
Range("A4:A29").Select
Selection.ClearContents
Range("A34:A59").Select
Selection.ClearContents
Range("A64:A89").Select
Selection.ClearContents
Range("A94:A119").Select
Selection.ClearContents
Range("A124:A149").Select
Selection.ClearContents
Range("A154:A179").Select
Selection.ClearContents
Range("A184:A209").Select
Selection.ClearContents
Range("A1").Select
I did the above coding to clear some boxes in excel, but it does not give me flexibility over range of boxes, what I want is to clear out any filled boxes in column A but if x mod 30 equals to zero to skip the next 3 and so on. I have used a similar code to fill up the boxes, see below:
With RegExp
.Pattern = "\bT[0-9A-Z\(\)\-]+"
.Global = True
.IgnoreCase = False
Set matches = .Execute(txt)
End With
For Each Match In matches
If x Mod 30 = 0 Then
x = x + 4
End If
Cells(x, 1) = Match
x = x + 1
Cells(x, 1) = Match
If x Mod 30 <> 0 Then
x = x + 1
End If
Next
If anyone could help me that would be great! Thanks
It's a bad idea (performance-wise) to first select the cell and then use Selection.ClearContents
Try this principle:
Range(Cells(x, 1), Cells(x + 29, 1)) = ""
This clears the contents of all Cells between x,1 and x+29,1
For your purpose it might be something like this (you might have to tweek the details because they are not clear from your post):
For x = 0 to 9 ' repeat however many times you want
startingRow = x * 33 + 1
Range(Cells(startingRow, 1), Cells(startingRow + 28, 1)) = ""
Next
I got it. Thanks #E.Villager
Private Sub CommandButton2_Click()
Dim lRow As Long
Dim lCol As Long
lRow = Cells(Rows.Count, 1).End(xlUp).Row
For x = 4 To lRow
If x Mod 30 = 0 Then
x = x + 4
End If
Cells(x, 1) = ""
Next
End Sub
This code is producing an "Object not found" error.
Sub Button86_Click()
Dim Y As Integer
Dim i As Integer
Dim LastRow As Long
Y = 2
Worksheets("Abnormal").Activate
With ActiveSheet
LastRow = .Range("A1").SpecialCells(xlCellTypeLastCell).Row
End With
Sheets("Abnormal").Rows(1).Copy Destination:=Sheets("Ab_IT").Rows(1)
For i = 2 To LastRow
If Abnormal.Cells(i, 11).Value = "IT" Then
Sheets("Abnormal").Rows(i).Copy Destination:=Sheets("Ab_IT").Rows(Y)
Y = Y + 1
End If
Next i
Worksheets("Ab_IT").Activate
With ActiveSheet.UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
Worksheets("Ab_IT").Columns("A:J").AutoFit
End Sub
** Error line - If Abnormal.Cells(i, 11).Value = "IT" Then
Details - There are two sheets. Abnormal and Ab_IT.
In Abnormal sheet, there is one column(11),which sometimes contain "IT"
I am trying to copy all the rows, which contain IT to another sheet Ab_IT.
But getting an error object not defined.
I don't see the variable 'Abnormal' defined prior to this line:
If Abnormal.Cells(i, 11).Value = "IT" Then
Maybe you meant:
If Sheets("Abnormal").Cells(i, 11).Value = "IT" Then
I've one workbook with 170K rows, I will delete all rows when the result between cells is 0,
For those operation, normally I use the code below, but with 170K (the rows will be deleted are 90K) the code run very slowly.
Someone know another way more performance.
Thank
Last = Cells(Rows.Count, "K").End(xlUp).Row
For i = Last To 2 Step -1
If (Cells(i, "K").Value + Cells(i, "L").Value) < 1 Then
Cells(i, "A").EntireRow.Delete
End If
Next i
As long as your fine putting the data on a new tab, the code below will do everything you need in 1.5 seconds.
Sub ExtractRows()
Dim vDataTable As Variant
Dim vNewDataTable As Variant
Dim vHeaders As Variant
Dim lastRow As Long
Dim i As Long, j As Long
Dim Counter1 As Long, Counter2 As Long
With Worksheets(1)
lastRow = .Cells(Rows.Count, "K").End(xlUp).row
vHeaders = .Range("A1:L1").Value2
vDataTable = .Range("A2:L" & lastRow).Value2
End With
For i = 1 To UBound(vDataTable)
If vDataTable(i, 11) + vDataTable(i, 12) > 0 Then
Counter1 = Counter1 + 1
End If
Next
ReDim vNewDataTable(1 To Counter1, 1 To 12)
For i = 1 To UBound(vDataTable)
If vDataTable(i, 11) + vDataTable(i, 12) > 0 Then
Counter2 = Counter2 + 1
For j = 1 To 12
vNewDataTable(Counter2, j) = vDataTable(i, j)
Next j
End If
Next
Worksheets.Add After:=Worksheets(1)
With Worksheets(2)
.Range("A1:L1") = vHeaders
.Range("A2:L" & Counter1 + 1) = vNewDataTable
End With
End Sub
Here, my approach for your problem according to rwilson's idea.
I already tested it. It very very reduce executing time. Try it.
Sub deleteRow()
Dim newSheet As Worksheet
Dim lastRow, newRow As Long
Dim sheetname As String
Dim startTime As Double
sheetname = "sheetname"
With Sheets(sheetname)
Set newSheet = ThisWorkbook.Worksheets.Add(After:=Sheets(.Name))
'Firstly copy header
newSheet.Rows(1).EntireRow.Value = .Rows(1).EntireRow.Value
lastRow = .Cells(.Rows.Count, "K").End(xlUp).row
newRow = 2
For row = 2 To lastRow Step 1
If (.Cells(row, "K").Value + .Cells(row, "L").Value) >= 1 Then
newSheet.Rows(newRow).EntireRow.Value = .Rows(row).EntireRow.Value
newRow = newRow + 1
End If
Next row
End With
Application.DisplayAlerts = False
Sheets(sheetname).Delete
Application.DisplayAlerts = True
newSheet.Name = sheetname
End Sub
Here is a non-VBA option you can try:
In column M compute the sum of columns K and L
Highlight column M and the click Find and select > Find
Type in 0 in the Find what box and also select values in the Look in box
Select Find all and in the box that shows the found items select all entires (click in the box and press CTRL + A)
On the ribbon select Delete and then Delete sheet rows
Now manually delete column M
I haven't tried this with 170k+ rows but maybe worth assessing performance versus the VBA loop.
thank at all for your ideas but the really fast code is: use an array tu populate whit the correct date and replare all table of the end sort the table:
Sub Macro13(control As IRibbonControl)
Dim avvio As Date
Dim arresto As Date
Dim tempo As Date
Application.ScreenUpdating = False
Application.Calculation = xlManual
avvio = Now()
Dim sh As Worksheet
Dim arng As Variant
Dim arrdb As Variant
Dim UR As Long, x As Long, y As Long
Dim MyCol As Integer
Set sh = Sheets("Rol_db")
MyCol = 1
sh.Select
UR = sh.Cells(Rows.Count, MyCol).End(xlUp).Row
ReDim arrdb(2 To UR, 1 To 12) As Variant
For x = 2 To UR
If Cells(x, 11) + Cells(x, 12) > 0 Then
For y = 1 To 12
arrdb(x, y) = Cells(x, y)
Next y
Else
For y = 1 To 12
arrdb(x, y) = ""
Next y
End If
Next x
sh.Range("A2:L" & UR) = arrdb
arresto = Now()
tempo = arresto - avvio
Debug.Print "Delete empty rows " & tempo
Range("A2:L" & UR).Sort key1:=Range("A2:L" & UR), _
order1:=xlAscending, Header:=xlNo
Range("A4").Select
ActiveWindow.FreezePanes = True
conclusioni:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
time for my sheet 170K 00:00:07.
as soon as I have a minute I feel a loop of the columns
well I have the following code
Sub test()
Dim i As Integer
Dim j As Integer
Dim k As Integer
For i = 1 To 52
For j = 2 To 53
For k = 5 To 57
If Sheets("sheet1").Range("b2").Value <> Sheets("sheet2").Range("b2").Value Then Exit Sub
If Sheets("Sheet1").Range("b2").Value = i Then Range("A2:D2").Select
Selection.Cut
Sheets(k).Select
Range("a1").End(xlDown).Offset(1, 0).Select
ActiveSheet.Paste
Sheets(k).Range("d16").Select
ActiveCell.FormulaR1C1 = "=SUM(R[-13]c:R[-1]C)"
Range("d16").Select
Selection.Cut
Sheets("Sheet1").Select
Cells(j, 2).Select
ActiveSheet.Paste
i = i + 1
j = j + 1
k = k + 1
Next k
Next j
Next i
End Sub
I a trying to create a loop that ignores carrying out a routine if the value of a cell is not of a specific value
the problem is that of course if i<>the value then I leave the for next without the value of i,j and k increasing. Is there anyway of re-entering the code just before the i = i+1, j=j+1 and k=k+1 then going onto the next value of i,j and k. It has been doing my head in for a couple of hours. I tried using an error handler but I think that is useful to skip lines of code anyone help please!
I think you can try this..
Sheets("Sheet" & trim(str(k))).Range("d16").Select
I hope this will work...