Excel VBA - Dynamic Range to use with For Each Statement - excel

I'm trying to dynamically define a range in row like ctrl+down or ctrl+shift+down (to next blank cell) to be used with "For Each itm In rng" statement.
Originally I had it static like this set rng = Range("A4:A10")
So I tried to change it to something like this
Dim rng As Range
Set rng = Range("A4").CurrentRegion.Rows.Count
For Each itm In rng
...
Next itm
I also tried something like this
Set StartCell = Range("A4")
rng = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
But the code doesn't seems to work with "For Each itm In rng" statement
Any help is very much appreciated.

You can use .xlDown, it's the equivalent of pressing ctrl+Shift+down.
Dim rng As Range
Dim lastRow As Long
lastRow = Range("A4").End(xlDown).Row
Set rng = Range("A4:A" & lastRow)
For Each itm In rng
'do something
Next itm

Try this if it helps:
Option Explicit
Sub Test()
Dim LastRow As Long 'to find the last row on your range
Dim MyRange As Range 'to reference the whole range
Dim C As Range 'to loop through your range
With ThisWorkbook.Sheets("MySheet") 'change MySheet for your sheet name
LastRow = .Cells(4, 1).End(xlDown).Row 'last row, how? You go down to the last row and then ctrl + up
Set MyRange = .Range("A4:A" & LastRow) 'dynamic range
For Each C In MyRange
'your code
Next C
End With
End Sub

Related

Function returns temporary sheet

is this possible to create a function that returns temporary sheet?
Let's say I have got Sub as follow
Sub My_Sub()
Dim harm As Worksheet
Set harm = Sheets("my_sheet")
Dim lastRow As Long, arr
lastRow = harm.Range("A" & harm.Rows.Count).End(xlUp).Row
arr = harm.Range("T2:V" & lastRow).Value
MsgBox arr(2,5)+1
End Sub
Right now I'm working on harm = Sheets("my_sheet") and it loads whole sheet. Now I want to select part of that sheet and do the same operations so I wanted to write a function that will create temporary sheet, return it so in My_Sub I would have Set harm = ReturnSheet().
Is it possible? I want to load pseudo sheet from function, so I don't need to change anything in My_Sub (I mean those Ranges with column letter indexes).
Function ReturnSheet() As Worksheet
Dim Rng As Range
Dim lastRow As Long
Dim lastCol As Long
Set Rng = Selection
lastRow = Selection.Rows.Count
lastCol = Selection.Columns.Count
ReturnSheet.Range("A2").Resize(lastRow, lastCol).Value = Rng
End Function
Right now I'm getting Object variable or with block variable not set at ReturnSheet.Range("A2").Resize(lastRow, lastCol).Value = Rng
Try using the next Function. It returns a range meaning the selected cells without their first row:
Function ReturnRange(Optional boolAllRange As Boolean = False) As Range
Dim rng As Range: Set rng = Selection
If rng.rows.count = 1 Then Exit Function
If boolAllRange Then
Set ReturnRange = rng
Else
Set ReturnRange = rng.Offset(1).Resize(rng.rows.count - 1, rng.Columns.count)
End If
End Function
You can test it using the next Sub:
Sub testReturnRange()
Dim rng As Range
Set rng = ReturnRange 'eliminating the header
If Not rng Is Nothing Then Debug.Print rng.Address
Set rng = ReturnRange(True) 'header inclusive...
If Not rng Is Nothing Then Debug.Print rng.Address
End Sub

Clear the cell content before the keyword

I'm trying to clear the data before the keyword TRUE including blank cells in between, and also I don't want to hardcode the range because the range will keep on change. can anyone please help me with this.
A
1
2
3
4
5
3
4
53
53
TRUE
I hope it is what you need.
Option Explicit
Sub clr()
Dim ws As Worksheet
Set ws = Sheet1 'The sheet where the data are
Dim rng As Range
Set rng = ws.Range("A:A") 'Range where the data are
Dim rngFind As Range
Set rngFind = rng.Find("TRUE") 'Find TRUE
Dim rngClear As Range
Set rngClear = Range("A1", rngFind.Offset(-1)) 'Set the range to clear
rngClear.Clear
End Sub
I assume that cell containing value "True" as the last value in the column "A". If that is the case below code will clear the content of all the cells above to it.
Sub ClearCells()
Dim lastRow As Integer
Dim actSheet As Worksheet
Set actSheet = ThisWorkbook.ActiveSheet
With actSheet
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:A" & lastRow - 1).Clear
End With
End Sub
Thanks,
KV Ramana

Trying to get values from Column A using Excel VBA

Sub iterateThroughAll()
ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
Dim rowRange As Range
Dim colRange As Range
Dim LastCol As Long
Dim LastRow As Long
LastRow = wks.Cells(wks.Rows.Count, "A").End(xlUp).Row
Set rowRange = wks.Range("A1:A" & LastRow)
'Loop through each row
For Each rrow In rowRange
'Find Last column in current row
LastCol = 1 'wks.Cells(rrow, wks.Columns.Count).End(xlToLeft).Column
Set colRange = wks.Range(wks.Cells(rrow, 1), wks.Cells(rrow, LastCol)) <-------------- I get a Run-time error 1004 Application defined or object defined error.
'Loop through all cells in row up to last col
For Each cell In colRange
'Do something to each cell
Debug.Print (cell.Value)
Next cell
Next rrow
ScreenUpdating = True
End Sub
I get an Application-defined or object-defined error. The code looks okay but not sure why its not working here.
I am trying to get all the used cells in Column A
Option Explicit
Sub iterateThroughAll()
Application.ScreenUpdating = False
Dim wks As Worksheet
Set wks = ActiveSheet
Dim rowRange As Range, rrow As Range
Dim colRange As Range, Cell As Range
Dim LastCol As Long
Dim LastRow As Long
LastRow = wks.Cells(wks.Rows.Count, "A").End(xlUp).Row
Set rowRange = wks.Range("A1:A" & LastRow)
'Loop through each row
For Each rrow In rowRange
'Find Last column in current row
LastCol = 1 'wks.Cells(rrow, wks.Columns.Count).End(xlToLeft).Column
Set colRange = wks.Range(wks.Cells(rrow.Row, 1), wks.Cells(rrow.Row, LastCol))
'Loop through all cells in row up to last col
For Each Cell In colRange
'Do something to each cell
Debug.Print (Cell.Value)
Next Cell
Next rrow
Application.ScreenUpdating = True
End Sub

Variable range in Visual Basic for Excel

I want to define a variable range in an Excel macro with VBA. The first cell is always A25, but the last cell is moving depending on the number of data collected. This can be E35, or E58, etc. Any idea how to do this?
There are 2 options:
Option 1: the Range you are looking to define is continuous (see screen-shot below):
the easy approach will do:
Option Explicit
Sub DefRange()
Dim Rng As Range
With Worksheets("Sheet1") '<-- modify "Sheet" to your sheet's name
Set Rng = .Range("A25").CurrentRegion
Debug.Print Rng.Address '<-- for debug: will show A25:E35
End With
End Sub
Option 2: the Range you are looking to define, has an empty line in the middle (screen-shot below):
then, the previous method will result with the wrong range
Option Explicit
Sub DefRange()
Dim Rng As Range
Dim LastRow As Long
Dim LastCol As Long
With Worksheets("Sheet1") '<-- modify "Sheet" to your sheet's name
Set Rng = .Range("A25").CurrentRegion
Debug.Print Rng.Address '<-- for debug: will show A25:E35 ***WRONG***
'Search for any entry, by searching backwards by Rows.
LastRow = .Cells.Find(What:="*", After:=.Range("A25"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'Search for any entry, by searching backwards by Columns.
LastCol = .Cells.Find(What:="*", After:=.Range("A25"), SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
Set Rng = .Range(.Cells(25, "A"), .Cells(LastRow, LastCol))
Debug.Print Rng.Address '<-- for debug: will show A25:F37 ***CORRECT***
End With
End Sub
You can define a range as its two limit cells. Let's say you are working in the worksheet "ws":
Dim rng As Range
Dim cl1 As Range: Set cl1 = ws.Range("A25")
Dim cl2 As Range
Set cl2 = ws.Range("E35") 'Or something else'
Set rng = ws.Range(cl1, cl2)
Just count the rows in Column E,
Sub Button1_Click()
Dim LstRw As Long
Dim Rng As Range, x
LstRw = Cells(Rows.Count, "E").End(xlUp).Row
x = IIf(LstRw > 25, LstRw, 25)
Set Rng = Range("A25:E" & x)
Rng.Select
End Sub

Excel: user selection to larger range copy

I would like to have a user select a subset of a range and use a macro to select the much larger range to the clipboard for copying to a different workbook.
User Input:
Range("A1:A5")
Copied Range:
Range("A1:DM5")
Now how about:
User Input:
Range("A1:C5")
Copied Range:
Range("A1:DM5")
Thanks for any advice in advance.
klaus2
Dim rng As Range
Set rng = Application.Intersect(Selection.EntireRow, Range("A:DM"))
If Not rng Is Nothing Then
rng.Copy
'etc etc
End If
Sorry, I have not been around for a few days.
I have come up with a solution that appears to give me what I want. I found the key through Googling.
Dim strSelection As String
Dim firstRow As Integer
Dim lastRow As Integer
Dim firstCell As String
Dim lastCell As String
Sub Macro3()
strSelection = Selection.Address(ReferenceStyle:=xlA1, _
RowAbsolute:=False, ColumnAbsolute:=False)
firstRow = Range(strSelection).Row
lastRow = Range(strSelection).Rows.Count + Range(strSelection).Row - 1
firstCell = "A" & firstRow 'will always be "A" + firstRow
lastCell = "I" & lastRow 'will always predetermined column + lastRow
Range(firstCell, lastCell).Select 'selects the range and ready for copying to another workbook
MsgBox firstCell 'testing
MsgBox lastCell 'testing
End Sub

Resources