Offsetting a range that is found manually - excel

I have a situation where I am using these equations
=CELL("address",INDEX(J61:W61,MATCH(LARGE((J61:W61),1),J61:W61,0)))
To find the cell address of the largest value cell in that range.
For example, it gives me this as a result. $T$61 (which contains the highest value).
I now want to use that information and offset it upwards 51 rows to extract the title for this column. How can I use this information and a formula, or VBA to find the content of $T$10 in this case?

Obtaining the cell address in this case is not necessary. What's more, CELL is a volatile function, and so should be avoided if possible.
Simply:
=INDEX(J10:W10,MATCH(MAX(J61:W61),J61:W61,0))
Regards

I ended up finding a way to use vba to do what I need
Sub Top_3_Problems()
First_Address = Range("D62")
Second_Address = Range("D63")
Third_Address = Range("D64")
First_problem = Range(First_Address).Offset(-51)
Second_problem = Range(Second_Address).Offset(-51)
Third_problem = Range(Third_Address).Offset(-51)
Range("B40") = First_problem
Range("B41") = Second_problem
Range("B42") = Third_problem
End Sub

Quick example of how to do this in VBA
This is just a simple example. If implemented, objects need to be properly qualifed with a worksheet and the Find method needs to have options added
Option Explicit
Sub MaxHeader()
Dim Found As Range, SearchRange As Range
Set SearchRange = Range("J61:W61")
Set Found = SearchRange.Find(WorksheetFunction.Max(SearchRange))
If Not Found Is Nothing Then MsgBox Cells(10, Found.Column)
End Sub

Related

VBA how to change a range variable using something like offset

I'd think that the following code should produce a diagonal of numbers, and I am wondering why this code doesn't work as intended:
Sub RangeExample()
Dim a As Range
Set a = Sheets(1).Range("a1")
a.Value = 0
Dim i As Integer
For i = 1 To 100
a = a.Offset(1, 1)
a.Value = i
Next i
End Sub
I understand there are many ways of producing a diagonal of numbers, I'm not asking how to do that.
What I'm asking is how I would change my range variable a to become a different range, and do that iteratively. It seems to me that as a.offset(1,1) returns a range object that's one over and one down, I should be able to reassign a as this new range, assign a value, and move on.
Your current issue is that you're missing a Set:
Set a = a.Offset(1, 1)
Note that you could also just use i and not reSet:
a.Offset(i, i).Value = i
Another option is to use Cells, e.g.
Sheets(1).Cells(i + 1, i + 1).Value = i
There's more than one way to skin a cat - pick whatever is easiest and most intuitive to future you.
Thanks for the answer, I didn't know set was required in this case. The specific answer I was looking for I have now found at:
What does the keyword Set actually do in VBA?
Specifically, the following answer by LeppyR64. "Set is used for setting object references, as opposed to assigning a value."
I didn't know that equality alone only impacted the value of the range object a. To actually change the range a was referencing, I needed set because a is supposed to refer to a new range object.
the issue has already been addressed by #BigBen
but you could avoid re-setting the range at every iteration by means of With...End With block
Option Explicit
Sub RangeExample()
Dim i As Long
With Sheets(1).Range("a1") ' reference topleftmost cell
.Value = 0 ' write referenced cell value
For i = 1 To 100
.Offset(i, i).Value = i 'write referenced cell current offset value
Next
End With
End Sub

Using a variable for a range

I am writing a macro and am having issues with using a range variable. I think I am setting the range properly, but I cannot do anything with the range. Pseudocode below:
Dim rng As Range
Set rng = Report(1) 'A function which will be defined below
trackWkbk.Sheets(strFY).rng = 10 <--'THIS IS WHERE I am getting the error.
'trackWbkb is a workbook that is defined properly; I use it elsewhere with no errors.
'strFY is defined and working properly, I use it to call sheets in trackWbkb elsewhere with no errors.
The sub function code is:
Function Report(a) As Range
Select Case intMonth
Case intMonth = 7
Select Case a
Case a = 1
Set Report = Range("B2")
End Select
End Select
End Function
I know my select case statements are gonna get pretty convoluted (this is just a testing sample), but I don't think the issue is there.
Let me know if I should include more code. My code compiles. I think this is something simple that I am missing, but I have been looking online for the past half hour and can't seem to find anything that will resolve this. Does anyone know how to resolve this? Thanks
Your function already returns a Range object. It's not clear to me whether you're trying to obtain a range on another worksheet that is at the same address as a range on the active worksheet. However, you could directly obtain the desired range if you passed the worksheet reference to your function:
Function Report(ByVal poParentWorksheet As Excel.Worksheet, ByVal a As Integer) As Range
Select Case intMonth
Case intMonth = 7
Select Case a
Case a = 1
Set Report = poParentWorksheet.Range("B2")
End Select
End Select
End Function
Then you could use:
Set rng = Report(trackWkbk.Sheets(strFY), 1)
rng.Value = 10
When you set a range variable you are creating a pointer in memory to a specific range in a specific sheet. It's not storing a cell address, so you can't write
trackWkbk.Sheets(strFY).rng
Either adopt Excelosaurus's solution, or change your function to return a cell address as a string and then use
trackWkbk.Sheets(strFY).range(rng)

Performing named cell additions in EXCEL VBA

I have a cell that is named DATA_FIELD_NAME and I would like to use it in the following way:
Private Sub LockCells(iNumberOfDataColumns As Long)
ActiveSheet.Unprotect
ActiveSheet.Cells.Locked = False
ActiveSheet.Range("DATA_FIELD_NAME:DATA_FIELD_NAME+iNumberOfDataColumns").Locked = True
ActiveSheet.Protect Contents:=True
End Sub
Essentially I would like to lock the range of cells starting from the DATA_FIELD_NAME cell horizontally to DATA_FIELD_NAME + n.
However this doesn't work. Could someone please tell me the correct syntax or an alternate method?
I'd try this:
ActiveSheet.Range("DATA_FIELD_NAME").Resize(1, iNumberOfDataColumns).Locked = True
Here is a reference on Range.Resize Basically it changes the amount of cells you are dealing with based upon the current range. In what I gave you, it changes to 1 row, and iNumberOfDataColumns columns.
I just wrote this in SO, not tested in XL, so it might contain typos, but this should work:
With ActiveSheet
Range(.Range("DATA_FIELD_NAME"), .Range("DATA_FIELD_NAME").Offset(0,iNumberOfDataColumns)
End With
The idea is to combine Offset(rows, cols) with to use the Range(range1, range2) syntax.
Alternatively, you could be a dynamic range name as explained here.

Excel VBA - Performing function to each cells in range

Let's say I have a range called rng1
Set rng1 = Worksheets("Sheet1").Range("A1","A5")
Is there a quick and easy way to perform a mathematical function, lets say divide all those cell values by 2, for all the cells in rng1?
Any help is appreciated!
It's very easy, but the final code will depend on where you want to store the new values. For example, if you want to store the values divided by 2 in the next column:
Sub test()
Dim cell As Range
For Each cell In Range("A1:A5")
cell.Offset(, 1).Value = cell.Value / 2
Next
End Sub
Mind you there are more efficient ways to do this than using offset if your range is large, but for a smaller range, this is totally acceptable and fast.
If you want to overwrite the values, you can simply use cell.Value in place of cell.Offset(,1).Value
Another Way
Sub Main()
[B1:B5] = [INDEX((A1:A5/2),)]
End Sub
How it works is well explained here.

How to retrieve cell addresses which call specific function

I need to find out cell addresses which have called a specific function.
If my function is MyFunction (arg1, arg2),
I should be able to find the cell addreses using name "MyFunction".
Please help me to find out what would be the most efficient way to do this.
Thank You
I asked the same question, but worded differently so I didn't find this one when I searched.
The interesting point is that the answer I got is, I think, better than the looping one for two reasons:
Faster - no looping. Just use Application.Caller
Works if your function is called from more than one cell
You can loop through a range of cells, looking for that particular function:
Dim name as String
Dim searchRange as Range
Dim row as Integer
Dim col as Integer
name = "MyFunction" ''// for example
Set searchRange = Range("A1:P:50") ''// for example
For row = 1 to searchRange.Rows.Count
For col = 1 to searchRange.Columns.Count
If Left(searchRange.Cells(row, col).Formula, Len(name)) = name Then
''// do something with this cell
End If
Next col
Next row

Resources