Cannot store selected range into variable - vba

I have the following code that selects all used cells starting from the cell specified.
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim ranged_select As Range
Set sht = Worksheets("Worksheet1")
Set StartCell = Range("C2")
'Find Last Row and Column
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column
'Select Range
sht.Range(StartCell, sht.Cells(LastRow, LastColumn)).Select
But how come for the last line
sht.Range(StartCell, sht.Cells(LastRow, LastColumn)).Select
I cannot assign it to a variable? I want the variable to be a range. I have tried assigning this variable Dim used_ranged as Range but it gives me 'Run-time error '91':'
Here is the data and what it looks like when I run the code which just selects the data starting from C2.

Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim range_select As Range
Set sht = Worksheets("Worksheet1")
Set StartCell = sht.Range("C2") '<< always be explicit about the parent sheet
'Find Last Row and Column
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column
'drop the .Select
Set range_select = sht.Range(StartCell, sht.Cells(LastRow, LastColumn))

Related

How to dynamically select a range VBA

My question is very similar to the following:
Excel VBA code to select non empty cells
However, I have some empty cells in between. In particular, I'm trying to define a range where the first row needs to be excluded, since it's a header. I also have to exclude the empty cells that follow. I was trying something like
Dim wb as workbook, ws as worksheet
Dim myrange as range
'Defined reference wb and ws
myrange=ws.range("B2",range("B2"),end(xldown))
But this only works if there are not empty cells in between. So, is there a fast and simple way to dynamically select a range that includes non-empty cells, excepted the header?
Try this
'Defined reference wb and ws
Set myrange = ws.range("B2", ws.Range("B" & Rows.Count).End(xlUp))
Don't forget to use the Set keyword
Try the next way, please:
Sub testDefineRange()
Dim ws As Worksheet, lastRow As Long, myrange As Range
Set ws = ActiveSheet 'use here what you need
lastRow = ws.Range("B" & ws.rows.count).End(xlUp).row
'Defined reference ws
Set myrange = ws.Range("B2:B" & lastRow)
myrange.Select
End Sub
I have found this link to be very useful on MANY occasions.
https://www.thespreadsheetguru.com/blog/2014/7/7/5-different-ways-to-find-the-last-row-or-last-column-using-vba
Ways To Find The Last Row
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 = ActiveSheet
'Using Find Function (Provided by Bob Ulmas)
LastRow = sht.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
'Using SpecialCells Function
LastRow = sht.Cells.SpecialCells(xlCellTypeLastCell).Row
'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
Ways To Find The Last Column
Sub FindingLastColumn()
'PURPOSE: Different ways to find the last column number of a range
'SOURCE: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim LastColumn As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LastColumn = sht.Cells(7, sht.Columns.Count).End(xlToLeft).Column
'Using UsedRange
sht.UsedRange 'Refresh UsedRange
LastColumn = sht.UsedRange.Columns(sht.UsedRange.Columns.Count).Column
'Using Table Range
LastColumn = sht.ListObjects("Table1").Range.Columns.Count
'Using Named Range
LastColumn = sht.Range("MyNamedRange").Columns.Count
'Ctrl + Shift + Right (Range should be first cell in data set)
LastColumn = sht.Range("A1").CurrentRegion.Columns.Count
End Sub
If it suits your case, I like to use CurrentRegion with Intersect to eliminate the title row.
with ws.range("b2")
set myRange = intersect(.currentregion, .currentregion.offset(1,0))
end with
debug.print myRange.address

VBA - Copy Cells from Column A and B and Paste in New Sheet

Follow up question from this previous post:
VBA - Compare Column on Previous Report With New Report to Find New Entries
The solution below compares a report generated last week with a report generated this week and it finds the differences between the two, in column A. Then it copies the differences from column A to a new sheet into column A. However, the scope has changed slightly in that I need to copy from the original sheet the difference in column A and the adjacent cell in column B.
For example:
Column A contains User ID's and Column B contains Employee Names
The comparison is done on the User ID, and when a difference is found, that specific User ID is copied to the new sheet. However, I need the User ID as well as the Employee Name copied to the new sheet, not just the User ID.
I cannot copy the entire row because there is other information in the other columns that are not necessary for the report summary.
Here is the code provided by Vityata:
Public Sub FindDifferences()
Dim firstRange As Range
Dim secondRange As Range
Dim wks1 As Worksheet: Set wks1 = Worksheets(1)
Dim wks2 As Worksheet: Set wks2 = Worksheets(2)
Dim wks3 As Worksheet: Set wks3 = Worksheets(3)
Set firstRange = wks1.UsedRange
Set secondRange = wks2.UsedRange
Dim myCell As Range
For Each myCell In firstRange
If myCell <> secondRange.Range(myCell.Address) Then
wks3.Range(myCell.Address) = myCell
End If
Next myCell
End Sub
Here is the current code I have:
Public Sub FindDifferences()
Dim firstRange As Range
Dim secondRange As Range
Dim myCell As Range
Dim wks1 As Worksheet, wks2 As Worksheet, wks3 As Worksheet
'Find Removed Wintel Servers
Set wks1 = ActiveWorkbook.Sheets("sh1")
Set wks2 = ActiveWorkbook.Sheets("sh2")
Set wks3 = ActiveWorkbook.Sheets("sh3")
Set firstRange = Range(wks1.Range("A1"), wks1.Range("A" & Rows.Count).End(xlUp))
Set secondRange = Range(wks2.Range("A1"), wks2.Range("A" & Rows.Count).End(xlUp))
For Each myCell In secondRange
If WorksheetFunction.CountIf(firstRange, myCell) = 0 Then
myCell.Copy
wks3.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
wks3.Cells(Rows.Count, 1).End(xlUp).PasteSpecial xlPasteFormats
End If
Next myCell
wks3.Range("A1").Select
End Sub
This is probably not the easiest way to do it, but it works for me. Let me know if you need me to explain the different variables.
The code presumes you have headers in the first row on every sheet.
Sub FindDifferences()
Dim LastRow As Integer
Dim LastRow2 As Integer
Dim rng As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rng4 As Range
Dim Counter As Integer
Dim Counter2 As Integer
Dim wks1 As Worksheet: Set wks1 = Worksheets(1)
Dim wks2 As Worksheet: Set wks2 = Worksheets(2)
Dim wks3 As Worksheet: Set wks3 = Worksheets(3)
LastRow = wks1.Cells(Rows.Count, "A").End(xlUp).Row
LastRow2 = wks2.Cells(Rows.Count, "A").End(xlUp).Row
Set rng = wks1.Range("A2")
Set rng2 = wks1.Range("A2:B2")
Set rng3 = wks2.Range("A2:A" & LastRow2)
Set rng4 = wks3.Range("A2:B2")
Counter = 2
Counter2 = 2
For x = 1 To LastRow
Set ValueCheck = rng3.Find(rng.Value, LookIn:=xlValues)
If ValueCheck Is Nothing Then
rng2.Copy _
Destination:=rng4
Counter2 = Counter2 + 1
End If
Counter = Counter + 1
Set rng = wks1.Range("A" & Counter)
Set rng2 = wks1.Range("A" & Counter & ":B" & Counter)
Set rng4 = wks3.Range("A" & Counter2 & ":B" & Counter2)
Next x
End Sub
In your current code you can replace your line
myCell.Copy
With this:
.Range(myCell.Address & ":" & myCell.Offset(0,1).Address).Copy
I believe this would work ok, I haven't tested properly, if you get an error let me know I'll trial it

Finding a value and then copying a column in which it occurs

I am trying to write a macro which will find a value "Spot price" in a header of a table2 and then take the whole column where that value is to copy and paste it (as values and not formulas). I need to do it because in that column I have a reference to external workbook and I need to share this worksheet without sharing the other workbook. This is what I wrote
Sub row()
Dim firstrow As Range
Dim ColumnToPaste As Range
Dim copy As Range
Set firstrow = Worksheets("Raw Data").ListObjects("Table2").HeaderRowRange
Set ColumnToPaste = firstrow.Find("Spot price", , xlValues, xlWhole).Columns(1)
With Worksheets("Raw Data").Range(ColumnToPaste)
.PasteSpecial Paste:=xlPasteValues
End With
End Sub
The error occurs on this line (Application-defined or object-defined error):
With Worksheets("Raw Data").Range(ColumnToPaste)
I think I'm using wrong range argument but not sure how to write it properly.
How about the following, instead of copying the full column, specify the range:
Sub row2()
Dim ws As Worksheet: Set ws = Sheets("Raw Data")
'declare and set your worksheet, amend as required
Dim firstrow As Range
Dim ColumnToPaste As Range
Dim LastRow As Long
Set firstrow = ws.ListObjects("Table2").HeaderRowRange
Set ColumnToPaste = firstrow.Find("Spot price", , xlValues, xlWhole).Columns
col = ColumnToPaste.Column
LastRow = ws.Cells(ws.Rows.Count, col).End(xlUp).Row
'get the last row with data on Column A
With ws
.Range(.Cells(1, col), .Cells(LastRow, col)).Copy
.Range(.Cells(1, col), .Cells(LastRow, col)).PasteSpecial xlPasteValues
End With
End Sub

VBA: object doesn't support this property or method

I wrote a very simple macro, that opens another workbook and select range of data from this workbook.
However, I keep receiving this warning: object doesn't support this property or method
What is wrong?
Sub data()
Dim wb As Workbook
Dim ws As Worksheet
Dim filename As String
Dim lastrow As Integer
Dim lastcolumn As Integer
Dim range_to_copy As Range
'open workbook
filename = "C:\Users\mk\Desktop\sales report\Sales Report.xls"
Set wb = Workbooks.Open(filename)
Set ws = wb.Sheets("data")
lastcolumn = wb.ws.Cells(1, wb.ws.Columns.Count).End(xlToLeft).Column
lastrow = wb.ws.Cells(wb.ws.Roows.Count, 1).End(xlToLeft).Row
range_to_copy = Range("Cells(1,1):Cells(lastrow,lastcolumn)")
End sub
A number of things wrong.
Edit:
Dim lastrow As Integer
Dim lastcolumn As Integer
An Integer can store numbers up to 32,767. This won't be a problem for columns, but will throw an overflow error on the row number. It's better to use the Long data type - numbers up to 2,147,486,647.
The ws variable already references the workbook so you just need:
lastcolumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lastrow = wb.ws.Cells(wb.ws.Roows.Count, 1).End(xlToLeft).Row
Rows only has one o in it.
Edit: xlToLeft looks at the right most cell and works to the left. As you're looking for rows you need to use xlUp which looks at the last cell and works up.
range_to_copy = Range("Cells(1,1):Cells(lastrow,lastcolumn)")
This is an object so you must Set it. The cells references are separated by a comma and should not be held as a string.
Sub data()
Dim wb As Workbook
Dim ws As Worksheet
Dim filename As String
Dim lastrow As Long
Dim lastcolumn As Long
Dim range_to_copy As Range
'open workbook
filename = "C:\Users\mk\Desktop\sales report\Sales Report.xls"
Set wb = Workbooks.Open(filename)
Set ws = wb.Sheets("data")
lastcolumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lastrow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Set range_to_copy = ws.Range(ws.Cells(1, 1), ws.Cells(lastrow, lastcolumn))
End Sub
Note: Every range reference is preceded by the worksheet reference. Without this it will always look at the currently active sheet so if you aren't on the data sheet the following will fail as the second cell reference will look at the activesheet.
ws.Range(ws.Cells(1, 1), Cells(lastrow, lastcolumn))
It might be worth checking out the With....End With code block.
There are several errors in your code.
Try
lastcolumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Set range_to_copy = Range(ws.Cells(1, 1), ws.Cells(lastRow, lastcolumn))
Once you defined and set your ws worksheet object, you don't need to refer to the wb object anymore, since your ws worksheet object is fully quallified with Sheets("data") in wb workbook.
Now, all you need to do is use the With statement, like in the code below:
Set ws = wb.Sheets("data")
With ws
lastcolumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set range_to_copy = .Range(.Cells(1, 1), .Cells(lastrow, lastcolumn))
End With

VBA: Range method failure

I was writing a code to select all the data entries of a Workbook which I 'Open' in a range, but the compiler gives error at the very last line (set up the Range rng)
Dim wb As Workbook
Set wb = Workbooks.Open(Range("C2") & Range("C3"))
'here Range("C2") & Range("C3") contains the location of the file's path
Dim ws As Worksheet
Set ws = wb.ActiveSheet
Dim frow As Long
frow = ws.Range("A" & Rows.count).End(xlUp).Row
Dim rng As Range
Dim frow1 As Long
frow1 = ws.Cells(1, Columns.count).End(xlToLeft).Column
Set rng = wb.ActiveSheet.Range(Cells(1, 1), Cells(frow, frow1))
Try:
Dim frow As Long
frow = ws.Range("A" & ws.Rows.count).End(xlUp).Row
Dim rng As Range
Dim fcol As Long
fcol = ws.Cells(1, ws.Columns.count).End(xlToLeft).Column
Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(frow, fcol))
Remember that if you are using a set worksheet u have to reference it in all range objects