VBA Excel Loop to Delete Range Based on Value in Column C - vba

I am trying to delete a specific range based on whether or not column "C" meets specific criteria.
Currently I have the following:
If Range("C69") = "All values USD Millions." Then
Range("C69 : H69").Delete shift:=xlUp
Else Range("A3").Select
End If
I want to turn this into a loop that will search cells "C1" through "C100" for the words "All values USD Millions." and delete the corresponding C though H range. For example, if it found the value in "C15", it would delete Range("C15:H15").
Unfortunately, I am still learning and all the loops I try create an error.

You can use the filtering capability of Excel:
With Sheet1.Range("C1:H100")
.AutoFilter 1, "All values USD Millions."
.Offset(1).Delete
.AutoFilter
End With
However if you want to do a "classic" iteration and delete while iterating on the rows, remember always that in these cases you should iterate "backward":
Dim i as long
For i = Range("C999999").End(xlUp).Row to 1 Step -1
If Cells(i, "C").Value2 = "All values USD Millions." Then Rows(i).Delete
Next

Another fast way, without looping throughout the rows one by one, is using the Find function:
Option Explicit
Sub UseFindFunc()
Dim FindRng As Range
Dim Rng As Range
Dim LastRow As Long
Dim TexttoFind As String
TexttoFind = "All values USD Millions." ' <-- try to use variable, easy to modify later
With Sheet1
LastRow = .Cells(.Rows.Count, "C").End(xlUp).Row '<-- get last row with data in Column C
Set Rng = .Range("C1:H" & LastRow)
Set FindRng = Rng.Find(What:=TexttoFind, LookIn:=xlValues, LookAt:=xlWhole)
While Not FindRng Is Nothing '<-- find was successful
FindRng.Resize(, 5).Delete xlShiftUp '<-- delete column "C:H" in found row
Set FindRng = Rng.Find(What:=TexttoFind, LookIn:=xlValues, LookAt:=xlWhole)
Wend
End With
End Sub

If you don't want to delete cells from columns A and B, this works for me:
Sub test()
Dim i As Integer
For i = 1 To 100
If Range("C" & i) = "All values USD Millions." Then
Range("C" & i & ":H" & i).Delete
Else
Range("A3").Select
End If
Next
End Sub

If your data is not as static you could do the script till your last row or set i = 1 to 100 to stop at row 100
Sub test()
Dim lRow As Long
lRow = WorksheetFunction.Max(Range("C65536").End(xlUp).Row,
Range("D65536").End(xlUp).Row, Range("E65536").End(xlUp).Row)
With ActiveSheet
For i = lRow To 2 Step -1
If .Cells(i, "C").Value = "All values USD Millions." Then
Range("C" & i & ":H" & i).ClearContents
End If
Next i
End With
End Sub

Try using:
For i=1 to 100
If Cells (i, 3) = "All values USD Millions." Then
Rows (i).Delete
EndIf
Next

Related

copy lane from different sheet if the same value

I have 5 columns in sheet1, and the same in sheet 2.The name of the product is in A. But sometimes the caracteristics of the products (in B,C,D,E) can change in sheet 2. I want that it actualize the caracteristics in Sheet1.
I tried a Vlookup, but it works only zith one Cell
Sub test()
With Sheets("Feuil1")
.Range("B1").Value = WorksheetFunction.VLookup(.Range("A1").Value, Sheets("Feuil2").Range("A1:B100"), 2, False)
End With
End Sub
Moreover, I cant copy all the line because the colomn F should not changeā€¦ And products in sheet1 in column A are not tidy and get some duplicates...
You need a loop for this to update each row and you need to update each column as well.
I recommend to use WorksheetFunction.Match instead so you only need to match once per row to get the row number and then you can copy the desired values of that row.
Option Explicit
Public Sub UpdateData()
Dim WsDest As Worksheet 'destination workbook to write in
Set WsDest = ThisWorkbook.Worksheets("Feuil1")
Dim WsSrc As Worksheet 'source workbook to match with
Set WsSrc = ThisWorkbook.Worksheets("Feuil2")
Dim LastRow As Long 'last used row in workbook
LastRow = WsDest.Cells(WsDest.Rows.Count, "A").End(xlUp).Row
Dim iRow As Long, MatchedRow As Long
For iRow = 1 To LastRow 'loop through all rows from row 1 to last used row and update each row
MatchedRow = 0 'initialize
On Error Resume Next 'if no match found then ignore error
MatchedRow = WorksheetFunction.Match(WsDest.Cells(iRow, "A"), WsSrc.Columns("A"), 0) 'get the row number of the match
On Error GoTo 0 'reactivate error reporting
'if it didn't match then MatchedRow is still 0
If MatchedRow > 0 Then 'if a match was found then copy values
WsDest.Cells(iRow, "B").Value = WsSrc.Cells(MatchedRow, "B").Value
WsDest.Cells(iRow, "C").Value = WsSrc.Cells(MatchedRow, "C").Value
WsDest.Cells(iRow, "D").Value = WsSrc.Cells(MatchedRow, "D").Value
WsDest.Cells(iRow, "E").Value = WsSrc.Cells(MatchedRow, "E").Value
Else
'didn't find a match
'you can remove the Else part if you want to do nothing here
End If
Next iRow
End Sub
If the columns you want to copy are continous like B, C, D, E you can do it in one copy action which is faster than 4 copy actions (1 for each column):
WsDest.Range("B" & iRow & ":E" & iRow).Value = WsSrc.Range("B" & MatchedRow & ":E" & MatchedRow).Value

Looping and finding similar number in VBA

I am very new to VBA. Just started reading it up 2 days ago. I am wondering how could I write a VB codes assigned to a button to read through the whole column and search for similar numbers.
After that identifying similar numbers, it would need to move on to another column to check if the character in the column are same too.
If both of the logic = true . How can i change the cell of the value of another column?
Sample data
For the current example. The code should know that the first column had matching numbers. After that it will check for the name which is "a" in the example. After that it will automatically change the point to 1 and 0. If there are 3 same ones it will be 1,0,0 for the point
You may try recording whatever you want to do with record macros first, then filter out the codes that are not necessary. If you do not know how to record it using macros, click on the link below. You can learn from the recorded macros and slowly improvise your codes in the future from the experience you may gain.
Here's [a link] (http://www.dummies.com/software/microsoft-office/excel/how-to-record-a-macro-in-excel-2016/)
As per image attached in image I am assuming numbers are in Column A, column to check characters is Column J and result needs to be displayed in Column O then try following code.
Sub Demo()
Dim dict1 As Object
Dim ws As Worksheet
Dim cel As Range, fCell As Range
Dim lastRow As Long, temp As Long
Dim c1
Set dict1 = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet2 to your data sheet
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
c1 = .Range("A2:A" & lastRow)
For i = UBound(c1, 1) To 1 Step -1 'enter unique values with corresponding values in dict1
dict1(c1(i, 1)) = .Range("J" & i + 1) '+1 for Row 2
Next i
Set fCell = .Range("A2")
For Each cel In .Range("A2:A" & lastRow) 'loop through each cell in Column A
temp = WorksheetFunction.CountIf(.Range(fCell, cel.Address), cel) 'get count
If temp > 1 Then
If cel.Offset(0, 9) = dict1(cel.Value) Then
cel.Offset(0, 14).Value = 0
Else
cel.Offset(0, 14).Value = 1
End If
Else
cel.Offset(0, 14).Value = 1
End If
Next cel
End With
End Sub
EDIT
Sub Demo()
Dim ws As Worksheet
Dim lastRow As Long
Application.ScreenUpdating = False
Set ws = ThisWorkbook.Sheets("Sheet2") 'change Sheet3 to your data range
With ws
lastRow = .Cells(.Rows.count, "A").End(xlUp).Row 'last row with data in Column A
.Range("O2").Formula = "=IF(MOD(SUMPRODUCT(($A$2:$A2=A2)*($J$2:$J2=J2)),3)=1,1,0)" 'enter formula in Cell O2
.Range("O2").AutoFill Destination:=.Range("O2:O" & lastRow) 'drag formula down
.Range("O2:O" & lastRow).Value = .Range("O2:O" & lastRow).Value 'keep only values
End With
Application.ScreenUpdating = True
End Sub

Find non zero value in column G on sheet 1, return value of Column C in that row to sheet 2 (VBA)

My first sheet is set up like this:
I want to find the non zero values in column G. Then I want to read the corresponding name in column C. I, then, want to return the value of the name to a cell on Sheet 2.
At this point, it doesn't matter what cell it returns to in sheet 2. It sounds like a VLOOKUP or INDEXMATCH but my VBA isn't good enough to figure out the formatting of it. This is some code that I tried and I can get it to return the name. But I don't know how to do it for all non zeros or how to have it print to sheet 2. Need a loop or need to figure out look ups!
code:
For Each c In Range("G6").Cells
If c.Value > 0 Then
PlayerName = Range(Cells(Selection.Row, 3).Address).Value
End If
Exit For
Next c
The following code will find the first row which has a number greater than 0 in column G (starting at row 6), and write the value in column C of that row to cell X5 of Sheet2.
With Worksheets("Sheet1")
For Each c In .Range("G6", .Cells(.Rows.Count, "G").End(xlUp)).Cells
If c.Value > 0 Then
Worksheets("Sheet2").Cells(5, "X").Value = c.Offset(0, -4).Value
Exit For ' Moved this inside the `If`, otherwise it will exit as soon as
' the first cell in the range is processed, irrespective of whether
' it was greater than 0 or not
End If
Next c
End With
Iterative version:
Dim s2Row as Long
s2Row = 5
With Worksheets("Sheet1")
For Each c In .Range("G6", .Cells(.Rows.Count, "G").End(xlUp)).Cells
If c.Value > 0 Then
Worksheets("Sheet2").Cells(s2Row, "X").Value = c.Offset(0, -4).Value
s2Row = s2Row + 1
End If
Next c
End With
Here is the logic you'll need. Will you be able to build the macro with this logic? It will help you understand how to maneuver rows that are greater than zero. Then you copy the column on that row y9ou need and paste it to the other sheet.
Sub macro1()
Dim myRng As Range, lastRow As Long
lastRow = ActiveSheet.Range("G65536").End(xlUp).Row
Set myRng = Sheet1.Range("G1:G" & lastRow)
For Each Rng In myRng
If IsNumeric(Rng.Value) And Rng.Value > 0 Then
Debug.Print "Cell " & Rng.Address & " has the number " & Rng.Value & " in row " & Rng.Row
End If
Next Rng
End Sub
Yes, except "G" is a column, not a row. Replace the debug.print line with WorkSheets("sheet name to copy from here").Rows(rng.row).Copy Destination:=WorkSheets("sheet name to copy to here").Range("A" & rowCounterVariable). Of course, change the sheet names to your actual sheet names.
Here I set the first row at 2 on the page to copy to. If you need to set it to the first available row then you need to research how to find the last used row on that page. Put these exact terms into Google "VBA EXCEL HOW TO FIND LAST USED ROW". I have an example of finding the last used row for the activesheet inside the code. We could give you fish today, and teach you how to fish. But you need to catch your own. We're not here to write code for you.
Sub macro2()
Dim myRng As Range, lastRow As Long, rowCounterVariable as long
rowCounterVariable = 2
lastRow = ActiveSheet.Range("G65536").End(xlUp).Row
Set myRng = Sheet1.Range("G1:G" & lastRow)
For Each Rng In myRng
If IsNumeric(Rng.Value) And Rng.Value > 0 Then
WorkSheets("sheet name to copy from here").Rows(rng.row).Copy Destination:=WorkSheets("sheet name to copy to here").Range("A" & rowCounterVariable)
rowCounterVariable = rowCounterVariable + 1
End If
Next Rng
End Sub

Copy/Paste multiple rows in VBA

I am attempting to do a simple copy row, paste row within a workbook. I've searched threads and tried changing my code multiple times to no avail.
The one that comes closest to working is this but it only copies a single instance of matching criteria.
I am trying to create a loop that will copy all of the rows that has a match in one of the columns.
So, if 8 columns, each row with matching value in column 7 should copy to a named sheet.
Sub test()
Set MR = Sheets("Main").Range("H1:H1000")
Dim WOLastRow As Long, Iter As Long
For Each cell In MR
If cell.Value = "X" Then
cell.EntireRow.Copy
Sheets("X").Range("A" & Rows.Count).End(xlUp).PasteSpecial
End If
If cell.Value = "Y" Then
cell.EntireRow.Copy
Sheets("Y").Range("A" & Rows.Count).End(xlUp).PasteSpecial
End If
If cell.Value = "Z" Then
cell.EntireRow.Copy
Sheets("Z").Range("A" & Rows.Count).End(xlUp).PasteSpecial
End If
If cell.Value = "AB" Then
cell.EntireRow.Copy
Sheets("AB").Range("A" & Rows.Count).End(xlUp).PasteSpecial
End If
Application.CutCopyMode = False
Next
End Sub
I like this because I need to target multiple destination sheets with different criteria but I need all rows that match criteria to copy over.
EDITED CODE IN RESPONSE TO NEW REQUEST:
The code below will copy all of the rows in Sheet Main and paste them into the corresponding worksheets based on the value in Column 7.
Do note: If there is a value in Column 7 that does NOT match to an existing sheet name, the code will throw an error. Modify the code to handle that exception.
Let me know of any additional needed help.
Sub CopyStuff()
Dim wsMain As Worksheet
Dim wsPaste As Worksheet
Dim rngCopy As Range
Dim nLastRow As Long
Dim nPasteRow As Long
Dim rngCell As Range
Dim ws As Worksheet
Const COLUMN_TO_LOOP As Integer = 7
Application.ScreenUpdating = False
Set wsMain = Worksheets("Main")
nLastRow = wsMain.Cells(Rows.Count, 1).End(xlUp).Row
Set rngCopy = wsMain.Range("A2:H" & nLastRow)
For Each ws In ActiveWorkbook.Worksheets
If UCase(ws.Name) = "MAIN" Then
'Do Nothing for now
Else
Intersect(ws.UsedRange, ws.Columns("A:H")).ClearContents
End If
Next ws
For Each rngCell In Intersect(rngCopy, Columns(COLUMN_TO_LOOP))
On Error Resume Next
Set wsPaste = Worksheets(rngCell.Value)
On Error GoTo 0
If wsPaste Is Nothing Then
MsgBox ("Sheet name: " & rngCell.Value & " does not exist")
Else
nPasteRow = wsPaste.Cells(Rows.Count, 1).End(xlUp).Row + 1
wsMain.Range("A" & rngCell.Row).Resize(, 8).Copy wsPaste.Cells(nPasteRow, 1)
End If
Set wsPaste = Nothing
Next rngCell
Application.ScreenUpdating = True
End Sub
Your current code is pasting to the same row in each sheet over and over, to the last row with a value in column A. Range("A" & Rows.Count).End(xlUp) says, roughly "go to the very bottom of the spreadsheet in column A, and then jump up from there to the next lowest cell in column A with contents," which gets you back to the same cell each time.
Instead, you could use lines of the pattern:
Sheets("X").Range("A" & Sheets("X").UsedRange.Rows.Count + 1).PasteSpecial
Where UsedRange is a range containing all of the cells on the sheet with data in them. The + 1 puts you on the following row.
You could make this a little prettier using With:
With Sheets("X")
.Range("A" & .UsedRange.Rows.Count + 1).PasteSpecial
End With

create a macro to copy multiple rows of data from one sheet to another based on a criteria

I am trying to write a macro that will let me copy a range of data from one sheet to another sheet based on a criteria in the column before the column to be copied.
Column B is the criteria column. If there is a 1 in any row in this column then columns C thru AN will be copied from that row where there is a 1 and be pasted into another sheet starting at the top of that sheet.
I have the following code. It locates the first row that satisfies the criteria and copies this row to the second sheet, however the code does not loop thru to find other rows that satisfy the criteria. How can I adjust the code to loop and copy each instance where the criteria is satisfied?
Sub testIt()
Dim i As Integer
Application.ScreenUpdating = False
Sheets("DataDump").Activate
For i = 2 To Range("B2").End(xlDown).Row()
If Range("B" & i).Value = 1 Then
Range("C" & i, "AN" & i).Copy
Sheets("PriceData").Activate
ActiveSheet.Range("B2", "AM2").Select
ActiveSheet.Paste
End If
Next i
Application.ScreenUpdating = True
End Sub
Sub testIt()
Dim i As Long, shtSrc As Worksheet, rngDest As Range
Application.ScreenUpdating = False
Set shtSrc = Sheets("DataDump")
Set rngDest = Sheets("PriceData").Cells(Rows.Count, 2).End(xlUp).Offset(1, 0)
For i = 2 To shtSrc.Range("B2").End(xlDown).Row
If shtSrc.Range("B" & i).Value = 1 Then
shtSrc.Range("C" & i & ":AN" & i).Copy rngDest
Set rngDest = rngDest.Offset(1, 0)
End If
Next i
Application.ScreenUpdating = True
End Sub