vba AutoFill method of range class failed - excel

I am trying to find month of a date in column A and paste the result to column B. They both have headers, column A’s is Date and column B’s is Month. I would like to have vba codes simply calculating the month of column A.
Here are my codes so far,
Sub Month()
Dim ws As Worksheet
Dim lastrow As Long
Set ws = Worksheets("Sheet1")
ws.Cells(2, "B") = "=Month(A2)"
lastrow = Range("A" & Rows.Count).End(xlUp).Row
Range("B2").AutoFill Destination:=Range("B2:B" & lastrow), Type:=xlFillDefault
End Sub
But I keep getting AutoFill method of range class failed error and I tried to change the AutoFill type but it won’t work. If you guys know a faster way to do it, let me know, too. (not excel functions, plz)
Thank you,

This code will fail if the value of lastrow is 2. You need to add some logic to account for that. Also revised to use better method of finding "last row"
Sub month()
Dim ws As Worksheet
Dim lastrow As Long
Dim startCell As Range
Set ws = Worksheets("sheet1")
With ws
Set startCell = .Cells(2, 2) ' or .Range("B2")
lastrow = startCell.EntireColumn.Find("*", AFter:=startCell, SearchDirection:=xlPrevious).Row
If lastrow = startCell.Row Then lastrow = lastrow + 1
startCell.Formula = "=Month(A2)"
startCell.AutoFill Range(startCell, startCell.Cells(lastrow)), xlFillDefault
End With
End Sub

"The destination must include the source range". Refer the link. So please select the cell. If you want to apply formula to cell use .Formula = "=Month(A2)"
Sub Month()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
ws.Cells(2, "B") = "=Month(A2)"
ws.Cells(2, "B").Select
Selection.AutoFill Destination:=Range("B2:B" & Cells(Rows.Count, "B").End(xlUp).Row), Type:=xlFillDefault
End Sub

Related

Looking for a way to Autofill Using a Variable Range

I'm looking for a way to autofill my formula down to the last row in the dataset (which is variable) using a range which is also variable. I have highlighted my issue below at the bottom.
Here is the code that I have now:
Sub MissingData()
Dim LastRow As Long
Dim LastCol As Long
Set ws = Worksheets("Insert Data")
With ws
Last Row = .Cells(.Rows.Count, 1).End(xlUp).Row
Last Col = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Inserting Column Header next to the last column in the data set in row 1"
.Cells(1, LastCol + 1).Value = "Header"
'Inserting Formula next ot the last column in the data set in row 2"
.Cells(2, LastCol + 1).Formula = "=iferror(AJ2,""YES"")"
End With
Dim FoundCell As Range
'Looking for the Last Row in the Dataset"
'Column A:A will always be populated with data and will be the driver
'for how many rows are in the data set"
LR = Worksheets("Insert Data").Range("A:A").End(xlDown).Row
With ws
'I set this and then called it using select because my range above
'and the location of this cell could be variable"
Set FoundCell = .Cells(2, LastCol + 1)
FoundCell.Select
'Here lies my issue. Using this syntax the formula is filled all the way
'to the last row available in Excel which is like 1 million something.
'I just need it filled to the last now that i set above"
Selection.AutoFill Destination:=Range(ActiveCell, ActiveCell.End(xlDown))
End With
End Sub
A better alternative to AutoFill is to enter the formula in the entire range in one go. Is this what you are trying?
Option Explicit
Sub MissingData()
Dim LastRow As Long
Dim LastCol As Long
Dim ws As Worksheet
Dim LastColName As String
Set ws = Worksheets("Insert Data")
With ws
'~~> Find last row
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
'~~> Find last column and add 1 to it
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column + 1
'~~> Get Column name from column number
' https://stackoverflow.com/questions/10106465/excel-column-number-from-column-name
LastColName = Split(.Cells(, LastCol).Address, "$")(1)
'~~> Add header
.Range(LastColName & 1).Value = "Header"
'~~> Add the formula in the entire range in ONE GO
' Example: Range("D2:D" & LastRow).Formula = "=IFERROR(AJ2,""YES"")"
.Range(LastColName & 2 & ":" & LastColName & LastRow).Formula = "=IFERROR(AJ2,""YES"")"
End With
End Sub

apply formula and FillDown on each sheet

I am trying to apply a formula to an entire column (B) in all sheets but just as far down as there is data in column A. I was trying the Filldown formula and am running into:
Related to Error 1004:
Range("B1:B" & LastRow).FillDown
Full Macro:
Dim sht As Worksheet
For Each sht In ThisWorkbook.Worksheets
Range("B1") = "=IF(A1=EOMONTH(TODAY(),-1),TRUE,FALSE)": Range("B1:B" & LastRow).FillDown
Next sht
As the comment stated, LastRow is not declared or given a value.
Also the FillDown is not needed, and neither is the IF part of the formula:
Dim sht As Worksheet
For Each sht In ThisWorkbook.Worksheets
Dim LastRow As Long
LastRow = sht.Cells(sht.Rows.Count, 1).End(xlUp).Row
sht.Range("B1:B" & LastRow) = "=A1=EOMONTH(TODAY(),-1)"
Next sht

How to specify a sheet to determine 'lastrow'?

I am trying to determine 'lastrow' of the sheet that the macro is being run on.
I am working with two sheets. Sheet1 has about 150 rows of data and Sheet 2 only has two.
I expected that when I selected Sheet2 and assigned lastrow that it would take the count of rows from Sheet2, instead it is storing the row count from sheet1.
sub row_count()
dim lastrow as long
lastrow = Range("A" & Rows.Count).End(xlUp).row
if lastrow = 150 then
with sheets("sheet2")
.select
lastrow = Range("A" & Rows.Count).End(xlUp).row
msgbox lastrow '<----- Always returns the value of sheet1 instead of sheet2.
end with
end sub
You're using a With block, which means the program sees anything between 'With' and 'End With' as being prefixed by whatever you put after the keyword 'With', so to modify your code in place for sheet2 only:
Sub row_count()
Dim lastrow As Long
lastrow = Sheets("sheet2").Range("A" & Rows.Count).End(xlUp).Row
If lastrow = 150 Then
With Sheets("sheet2")
' .Select = Sheets("sheet2").Select
.Select
' .Range = Sheets("sheet2").Range
lastrow = .Range("A" & Rows.Count).End(xlUp).Row
MsgBox lastrow
End With
End Sub
If you want the code to run on the currently visible sheet you should change it to use the ActiveSheet property:
Sub row_count()
Dim lastrow As Long
lastrow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
If lastrow = 150 Then
With ActiveSheet ' use the currently visible sheet
.Select
lastrow = .Range("A" & Rows.Count).End(xlUp).Row
MsgBox lastrow
End With
End Sub
However, there are some ways to improve this code: for flexibility you could pass the worksheet as a parameter. Also, your End function might return the first used row if there is already data in the last used row (it's the same as clicking in the last row and pressing Ctrl & the up arrow, so you should start in a cell below that). Lastly, you do not need to select the sheet to get the last row:
Sub GetRowCounts()
row_count Sheets("sheet1")
row_count Sheets("sheet2")
End Sub
Sub row_count(ws As Worksheet)
Dim lastrow As Long
lastrow = ws.Range("A1000000").End(xlUp).Row
MsgBox lastrow
End Sub
I think these examples are the easiest to follow.
Sub FindingLastRow()
'PURPOSE: Different ways to find the last row number of a range
'SOURCE: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Using UsedRange
sht.UsedRange 'Refresh UsedRange
LastRow = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Row
'Using Table Range
LastRow = sht.ListObjects("Table1").Range.Rows.Count
'Using Named Range
LastRow = sht.Range("MyNamedRange").Rows.Count
'Ctrl + Shift + Down (Range should be first cell in data set)
LastRow = sht.Range("A1").CurrentRegion.Rows.Count
End Sub
https://www.thespreadsheetguru.com/blog/2014/7/7/5-different-ways-to-find-the-last-row-or-last-column-using-vba
Keep an open mind though, there are lots of ways to do this same kind of thing.
If this statement...
lastrow = Range("A" & Rows.Count).End(xlUp).row
... really always returns the last row of Sheet1 instead of last row of Sheet2, then that is because you are looking at your Workbook open at Sheet1 all the time.
Whenever you have a Range or Cells statement like the above ( Range(...) ) without an explicit reference to a Worksheet, then ActiveSheet is what it is referenced to.
So to avoid that, this is what you do:
Dim Sht_1 as Worksheet
Dim Sht_2 as Worksheet
Dim Sht_1_Lastrow as Long
Dim Sht_2_Lastrow as Long
Set Sht_1 = ActiveWorkbook.Worksheets(1)
Set Sht_2 = ActiveWorkbook.Worksheets(2)
Sht_1_Lastrow = Sht_1.Range("A" & Sht_1.Rows.Count).End(xlUp).Row
Sht_2_Lastrow = Sht_2.Range("A" & Sht_2.Rows.Count).End(xlUp).Row
or
Sht_1_Lastrow = Sht_1.Cells(Sht_1.Rows.Count, "A").End(xlUp).Row
Sht_2_Lastrow = Sht_2.Cells(Sht_2.Rows.Count, "A").End(xlUp).Row
Above code block highlights the difference that makes a LastRow Variable explicitly tied to a certain Worksheet...
This way your problem cannot happen...

1004 Application-Defined or Object Defined error

The error appears on the line before end sub, what is the correct way to select the range with the last row calculated?
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
End With
ActiveSheet.Range(Cells(LastRow, Columns("D:AH"))).Select
End Sub
The code below select all cells in the LastRow only , from Column "D" to Column "AH".
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
.Range(.Range("D" & LastRow), .Range("AH" & LastRow)).Select
End With
End Sub
If you wanted to select all rows (from row 1 to LastRow), from Column "D" to Column "AH".
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
.Range(.Range("D1"), .Range("AH" & LastRow)).Select
End With
End Sub
Note: not sure why you want to Select this range ? You can set this Range to a variable of type Range, and later to Copy or whatever you want to do with it. There's hardly a reason to ever use Select.

How to delete rows if my range does not equal today's date?

I'm a complete beginner attempting a macro for the first time. I want to remove entire rows of a sheet if the date in column K does not equal today's date. Outside of the code having some sort of syntax error that I can't remedy, I believe the data dump's Column K is not formatted as a date to capture the code I'm trying to run.
Here is the code I have so far. Please be gentle on someone who is trying to self teach using online resources :)
Sub GetTodaysPopulation()
Dim MySheet As Worksheet, MyRange As Range
Dim LastRow As Long, LastCol As Long
Application.DisplayAlerts = False
Set MySheet = ThisWorkbook.Worksheets("TradeExData")
ThisWorkbook.Worksheets("TradeExData").Activate
With MySheet
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
LastCol = .Range("A" & .Columns.Count).End(xlToLeft).Column
Set MyRange = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
End With
With MyRange
.AutoFilter([Field:=11], [Criteria1: <> Date])
.SpecialCells(xlCellTypeVisible).Offset(1, 0).Resize(.Rows.Count).Rows.Delete
End With
With MySheet
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
End Sub

Resources