Is it possible to define a range in VBA based on a value given in a cell?
For example, I have a dataset with four columns and a constantly changing number of rows. I have the number of rows in cell F2. Suppose cell F2 indicates the number of rows is 385, then I be able to Range("A1:D385").Select, but I want the selection of the last cell to be dependent on cell F2.
So if I change F2 to 50, that the next time I run the macro, A1:D50 will be selected, but since I'm new to VBA I can't figure it out.
The most proper way to do this would be like this
Sub getRng()
Dim Cval As Variant
Dim Rng1 As Range
Cval = ActiveSheet.Range("F2").Value
Set Rng1 = ActiveSheet.Range("A1:D" & Cval)
End Sub
this sets Rng1 as an object that you can use later on in another function
such as
Rng1.Select
or
Rng1.Copy
This is what you are looking for:
Dim lastRow As Integer
With ThisWorkbook.Sheets(1)
lastRow = .Cells(.Rows.Count, "F").End(xlUp).row
.range("A1:D" & lastRow).Select
End With
The code looks for the first non-empty cell in column F, from bottom to top. Similar to selecting the last cell in column F and pressing Ctrl + up-arrow.
Related
I am hoping someone can help, I need to clear cells when then value of is less that a value in another cell. I did use conditional formatting but this messes up calculations further into the sheet.
I used a guide and was able to remove cells when I inputted the fixed integer into the module but am unsure how I adapt this to refer to a cell instead of a fixed number.
Thank you.
Ed
I believe this is what you are looking for below, this will take a value from cell B1 and compare against values in Column A, and if the values are less than the value in B1, it will clear the contents of that cell:
Sub ClearLowerThan()
Dim c As Range, Rng As Range
Dim LastRow As Long
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare you worksheet, amend as required
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A
CompareVal = ws.Range("B1").Value
'get the value to compare against, in this case from cell B1
Set Rng = ws.Range("A1:A" & LastRow)
'set the range to compare against the value from B1
For Each c In Rng 'for each cell in the given range
If c.Value < CompareVal Then c.ClearContents
'if value of cell is less than the value to compare against, clear the cell contents.
Next
End Sub
I am trying to have a VBA clean up and format data every time a table is refreshed. There are two columns that I want to look at. one is Job #, and the next one is Top level Job #. I would like the vba to look at column E, and if E5 = D5, then delete the contents in E5. If they are not the same, keep the content in E5. I would like it to do that for however many rows in Column E there are, as this will constantly change. If more information is needed let me know.
Try this..
Private Sub test()
Dim rng As Range
Dim cell As Range
Dim LastRow As Long
With ActiveSheet
LastRow = .Range("D1").SpecialCells(xlCellTypeLastCell).Row
End With
Set rng = Range("E2:E" & LastRow)
MsgBox rng.Address
For Each cell In rng
If LCase(cell.Value) = LCase(cell.Offset(0, -1)) Then
cell.ClearContents
End If
Next cell
End Sub
I am trying to find the number of rows of a filtered range on a sheet. LstRow2 is the variable I am trying to find. With this code I am getting the unfiltered number of rows.
CSht.Range(CSht.Cells(1, 1), CSht.Cells(LstRow1, LstCol1)).AutoFilter Field:=2, Criteria1:="RA"
With CSht
LstRow2 = .UsedRange.SpecialCells(xlCellTypeLastCell).Row
End With
You'll need to work with the visible cells only, since it's filtered.
Try this:
With CSht
'load filter cells into Range object
Dim rngFilter as Range
Set rngFilter = Intersect(.UsedRange,.UsedRange.Offset(1)).SpecialCells(xlCellTypeVisible)
'find the max number of elements split by $ in the range address
'needs to be dynamic because of areas
Dim lUpper as Long
lUpper = UBound(Split(rngFilter.Address,"$"))
'the last element will be the last row in the filtered range
'the last number in the rngFilter.Address
Dim LstRow2 as Long
LstRow2 = Split(rngFilter.Address,"$")(lUpper)
End With
Why don't you replace this line
LstRow2 = .UsedRange.SpecialCells(xlCellTypeLastCell).Row
With
LstRow2 = .Cells(.rows.count, 1).end(xlup).row
There may be several areas after filtering so you need to use Areas. Great explanation here https://stackoverflow.com/a/17287558/3733214. This should work:
Dim Line as Range
For Each Line In CSht.UsedRange.SpecialCells(xlCellTypeVisible).Areas
LstRow2 = LstRow2 + Line.Rows.Count
Next
Credits: https://www.mrexcel.com/board/threads/vba-code-to-count-visible-rows-after-autofiltering-a-table.602866/post-2988416
This formula lastRow = Worksheets("Sheet1").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row has given me the the correct last visible row of a filtered range.
Current region will do it for you in a single line
LastRow = sht.Range("A1").CurrentRegion.Rows.Count
This problem uses the following data, which would be manually adaptive over a fixed cell range--with each cell in the B column range containing a formula. It aims to find the last data cell from the underlying formula cells.
I would like to find the last formula cell with data within the formula range B2:B11, and create a dynamic median from this last cell with the four cells above it. The median should be output to cell F6--result of 9. This is a dynamic exercise. Any thoughts on how to do this most efficiently, given the code below?
Sub OutputMedian()
Dim FunctionRange As Range
'Represents a fixed range with function in B2:B11
Set FunctionRange = Worksheets("Sheet1").Range("B2:B11")
'Must start median calc from B9, as it's the last cell with function output data
'Must store Median from last data cell, using 5 cell offset (see output from cell F2)
'Must output the Final (e.g., median output of 9 here) to cell F6
End Sub
See: Excel VBA: Get Last Cell Containing Data within Selected Range
My modified answer by #brettdj from above question (referred by #varocarbas). Thanks!
Got it to work!! Outputs the correct dynamic median, with five periods set from -4 Offset below.
Sub OutputMedian()
Dim WS As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Set WS = Sheets("Sheet1")
Set rng1 = WS.Columns("B:B").Find("*", Range("B1"), xlValues, , xlByRows, xlPrevious)
Set rng2 = rng1.Offset(-4, 0)
Dim FirstCell As String
Dim LastCell As String
FirstCell = rng2.Address(0, 0)
LastCell = rng1.Address(0, 0)
Dim CellResponse As String
CellResponse = Evaluate("=median(" & FirstCell & ":" & LastCell & ")")
Range("F6").Value = CellResponse
End Sub
Better way to use objects (e.g., R1C1, Cells) in creating dynamic functions--i.e, without passing function into Evaluate as concatenated strings?
I am trying to paste a formula next to range of cells, but only the one's that contains a value, the script must loop until the next cell in the range is empty. For instance Sheet 1 Column A contains date until row 12, then I would like to paste a formula in column D2:D12 Regards
Like this?
Option Explicit
Sub Sample()
Dim lastRow As Long, i As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet1")
lastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
With ws
For i = 1 To lastRow
If Len(Trim(.Range("A" & i).Value)) <> 0 Then _
.Range("D" & i).Formula = "YOUR FORMULA"
Next i
End With
End Sub
As you are looking down to the first blank cell then you can avoid a loop and use
The code includes a test to make sure that the code doesn't proceed if all of column A is blank - ie if the range from A1 down extends to the bottom of the sheet and A1 is blank
This code adds a sample formula linking each cell in column D to the respective row in column B
Sub FillData()
Dim rng1 As Range
Set rng1 = Range([a1], [a1].End(xlDown))
If Not (rng1.Rows.Count = Rows.Count And Len([a1].Value) = 0) Then rng1.Offset(0, 3).FormulaR1C1 = "=RC2"
End Sub
I like Sid's beginning, but once you have the range of rows, you can insert the formula into column D all at once, without looping, several ways, here's one:
Option Explicit
Sub AddFormula()
Dim LR As Long
LR = Range("A" & Row.Count).End(xlUp).Row
Range("D2:D12").Formula = "=A2 + 7" 'just an example of a formula
End Sub
Try this:
Range("A:A").SpecialCells(2).Areas(1).Offset(, 3).Formula = "MyFormula"
This is a simple solution that is built into Excel, as long as you don't want to copy to the first blank, jump over the blank, then continue copying:
Enter the formula in the first cell of your range, and as long as it is in the column directly to the right or left of your range of filled cells, simply double-click the black box handler in the bottom right-hand corner of the cell. That will automatically copy your formula down to the last non-empty cell of the range.