Remove Duplicates in VBA excel - vba

I am trying to remove the duplicates at the end of a macro I wrote in vba. The macro runs but when it comes to the point to remove the duplicates it says that the object doesn't support the property or method when the object is Dimed as a range and set as a range as well. I am really confused on why this happening and I can't seem to spot what is causing this error. I have pasted the code below which causes the error and the point where I set the range object. Any help would be greatly appreciated.
Set WS = ThisWorkbook.ActiveSheet
With WS
Set Rng1 = .Range("B2:B" & .Range("B" & .Rows.Count).End(xlUp).Row)
Set rng2 = .Range("C1:D" & .Range("C" & .Rows.Count).End(xlUp).Row)
End With
If UBound(WrdArray2) < 0 Then
ActiveSheet.rng2.RemoveDuplicates
End
End If

Instead of
ActiveSheet.rng2.RemoveDuplicates
Just try the below:
rng2.RemoveDuplicates
What causing the error is you have already set range for object rng2 and rng2 does not include in Activesheet. That is, rng2 is separate object created by you and is not the property of Activesheet.

Related

Getting a compile error ('Object Required) even though I've made all the necessary declarations and set my variables

I'm applying the trim function to my column (B) via a simple loop. Here is my code (I've tried with and without option explicit- get the same error regardless):
I don't understand why I'm getting an object required error. There are no blank cells in the column.
Sub Trim()
Dim Cell As Long, SalesWs As Worksheet, LastRow As Long, Rng As Range
Set SalesWs = ThisWorkbook.Sheets("Sales")
Set LastRow = ThisWorkbook.Sheets("Sales").Range("B" & Rows.Count).End(xlUp).Row
Set Rng = ThisWorkbook.Sheets("Sales").Range("B2:B" & LastRow)
For Each Cell In Range("Rng")
Cell.Value = Trim(Cell.Value)
Next Cell
Exit Sub
End Sub

Static date in the last column

I am looking to do an IF THEN statement that will help me put a date into the U Column. However, I am not sure how to go about it.
Sub()
Dim rng1 As Range
Set rng1 = Selection.SpecialCells("U").xlBlanks
If Not rng1 Is Nothing Then rng1.Value = Format(Now(), "mm-dd-yyyy")
End Sub
When I run this code I receive a run-time error '1004'. Can someone help me with this?
First you want to find the range of cells that actually has data, because you don't want to check rows of column U where the entire row itself is empty. So assuming the last possible row of data can be found in column A, you can use this to set the search range.
With Worksheets("Sheet1") 'qualify sheet, change name as needed
Dim lRow as Long
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
Then, you can set the search range to be from Row 1 to lRow, assuming the data is in a contiguous range left-to-right, top-to-bottom starting in A1. (The On Error statements are necessary, since Excel will throw an error if blank cells do not exist in the range).
Dim rngSearch as Range
On Error Resume Next
Set rngSearch = .Range("U1:U" & lRow).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If the range is set then you can enter values into the entire range at once (which you had in your code above).
If Not rngSearch is Nothing Then rngSearch.Value = Format(Now(), "mm-dd-yyyy")
End With

"Extract range is not defined": advanced filter

I am trying to run this simple code in VBA but it keeps giving me "extract range is not defined" error:
Private Sub CommandButton1_Click()
'Dim rng As Range
Dim RowLast As Long
Dim perporig As Workbook
count = 0
Set perporig = Workbooks.Open("\\Etnfps02\vol1\DATA\Inventory\Daily tracking\perpetual.xlsx", , ReadOnly)
With perporig.Sheets("perpetual")
.AutoFilterMode = False
RowLast = .Cells(Rows.count, "A").End(xlUp).row
'Set rng = .Range("C4:C" & RowLast)
Range("A3:J" & RowLast).AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range("N1:N6"), Unique:=False 'have also tried Range("A3:J3"), doesn't work.
End With
ThisWorkbook.Sheets("myperpetual").Range("A5", "J5").PasteSpecial xlPasteValues
End Sub
I am trying to copy from a file with data starting from A4:J4 to some A16000:J16000. I have to filter the values in column C to a range I have specified in the worksheet in range N1:N6.
FYI: Table header A4 is empty, and B4:J4 have relevant headers in them.
Also please let me know if my copy-paste method is wrong, or for some reason wouldn't work as expected.
EDIT: I also tried adding a header in column A , i.e. cell A3. Still doesn't work.
My range N1:N6 is a list of numbers, but I am sure the mistake lies there. It doesn't specify which column to apply filter on.
Once you are inside the With perporig.Sheets("perpetual") ... End With block, preface all Range objects and Range.Cells property references with a period (aka . or full stop).
With perporig.Sheets("perpetual")
.AutoFilterMode = False
RowLast = .Cells(Rows.count, "A").End(xlUp).row
'Set rng = .Range("C4:C" & RowLast)
.Range("A3:J" & RowLast).AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=.Range("N1:N6"), Unique:=False
End With
Note .Range("C4:C"... and .Range("N1:N6") prefaced with a period. This indicates that the parent worksheet of the range(s) are defined by the worksheet named in the With ... End With statement. Without it, Excel is making a guess as to which worksheet the range belongs to; typically this would be the ActiveSheet property.

Copy and sort macro in vba

I am designing a macro that will copy and sort data by a key in vba. I have begun to write the code and it has worked well so far but for some reason I get an Object Required error at the line : Set rng1 = SourceData.Cells.Range("A2:A" & N). I am unsure why this is happening. Any help would be greatly appreciated.
Sub crossUpdate()
Dim rng1 As Range, rng1Row As Range
N = Cells(Rows.Count, "A").End(xlUp).row
Sheet1.Cells.Select
Selection.Copy
Sheets.Add.Name = "SourceData"
ActiveSheet.Paste
Range("A1").Select
Set rng1 = SourceData.Cells.Range("A2:A" & N)
Set rng1Row = rng1.EntireRow
rng1Row.Sort Key1:=Range("A1")
End Sub
You are getting an error because SourceData is not a thing. It looks like that is supposed to be a worksheet or a range or something, but you have not declared it, nor have you set it.
Update: SourceData is a sheet. To refer to a sheet by name you should use Sheets("Sheetname"). Furthermore, there is no need to refer to the cells of the sheet to get a specific range in the sheet, just go right to the range: Sheets("SourceData").Range("A2:A" & N)

Most efficient technique to check lots of cells contain an error?

I have a spreadsheet which contains lots of function calls to request data. I am writing a function (in VBA) to check whether any of the cells contains an error value "#VALUE" etc.
At the moment I am iterating row by row, column by column and first checking if the cell contains a formula, then if it does, checking instr for "#VALUE", "#N/A" etc.
However, I was wondering whether it would be quicker simulating clicking a whole column in excel and then "ctrl + f" for a value... in VBA.
What would be the most efficient way? I am checking a sheet 27 columns x 1200 rows large.
EDIT Ive just realised there are some cells which have "#N/A" and this is because they do not contain a particular formula. I need to only search in cells which contain a particular formula.... is this possible?
EDIT2 I effectively need to record a macro which returns the resutls, exactly like "find all". I have used "find" and i can get a boolean, but "find all" doesnt record any VBA code....
You can use SpecialCells to return only cells containing errors.
Sub Demo()
Dim sh As Worksheet
Dim rng As Range, cl As Range
For Each sh In ActiveWorkbook.Worksheets
Set rng = Nothing
On Error Resume Next
Set rng = sh.UsedRange.SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If rng Is Nothing Then
Debug.Print "No Errors"
Else
For Each cl In rng
If cl.Formula Like "*" Then ' <-- replace * with your criteria
Debug.Print cl.Address
End If
Next
End If
Next
End Sub
Given you wanted the most efficient method you could try this approach which avoids a slow range loop
Loops through SpecialCells formulae chichi contain errors (as per the other solution)
Uses Find to detect specific formulae rather than a simple loop through every cell in (1)
This code uses the R1C1 method to feed into the Find so the code changes this Application setting if necessary (and then back at the end)
I suggest you record the formula you wish to find to then enter this in. The big advantage of R1C1 notation is that it is agnostic of actual row and column location.
For example in A1 notation a formula of
=SUM(A1:A4) in A5 would require a different search for SUM(B1:B4) inB5`
in R1C1 this is =SUM(R[-4]C:R[-1]C) in both cases
code
Sub Demo()
Dim ws As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim strAddress As String
Dim bRefSTyle
If Application.ReferenceStyle = xlA1 Then
Application.ReferenceStyle = xlR1C1
bRefSTyle = True
End If
For Each ws In ActiveWorkbook.Worksheets
Set rng1 = Nothing
On Error Resume Next
Set rng1 = ws.UsedRange.SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If rng1 Is Nothing Then
Debug.Print ws.Name & ": No Formulae errors"
Else
'search errors for particular formula
'this sample looks for a formula which SUMS the four cells directly above it
Set rng2 = rng1.Find("=SUM(R[-4]C:R[-1]C)", , xlFormulas, xlWhole)
If Not rng2 Is Nothing Then
strAddress = rng2.Address
Set rng3 = rng2
Do
Set rng2 = rng1.Find("=SUM(R[-4]C:R[-1]C)", rng2, xlFormulas, xlWhole)
Set rng3 = Union(rng2, rng3)
Loop While strAddress <> rng2.Address
Debug.Print ws.Name & ": " & rng3.Address
Else
Debug.Print ws.Name & ": error cells, but no formulae match"
End If
End If
Next
'restore styles if necessary
If bRefSTyle Then Application.ReferenceStyle = xlA1
End Sub