How to modify this UDF for visible cells only?

jbaich

Board Regular
Joined
Nov 2, 2011
Messages
140
Hey everyone, I’ve got this user-defined function that I use to calculate a statistical measure for a range of cells. I’d like to modify it so that it only evaluates the visible cells within the range, but I’m not sure exactly how…

Here’s the current code:

VBA Code:
Function COD(r As Range) As Double
  Dim sAdr As String
  Dim sFrm As String
 
  sAdr = r.Address
  sFrm = "average(abs(" & sAdr & " - median(" & sAdr & ")))/median(" & sAdr & ")"
  COD = r.Worksheet.Evaluate(sFrm)
End Function

I think I need to modify with something like this, but this doesn’t seem to work so not sure… any ideas?

Code:
sAdr = r.SpecialCells(xlCellTypeVisible).Address

When you initially run the function, it prompts the user to select a range. I'd like to be able to select a table column for example, but have the function re-evaluate based on the visible cells only as the table gets filtered...

Thanks in advance!
Joe
 

Excel Facts

When they said...
When they said you are going to "Excel at life", they meant you "will be doing Excel your whole life".
The assignment to sAdr will work but it won't work in your formula because it will be a discontiguous range. The string will look something like this:

$A$1:$A$2,$A$7,$A$9:$A$11,$A$14:$A$16,$A$19:A$25

I think you are going to have to use a loop and do the math in VBA instead of Evaluate.
 
Upvote 0
Thanks 6String, so i think i've written a sub that will do the trick, but I can't seem to figure out how to convert it back into a function... any advice?

VBA Code:
Sub COD2()

    Dim myVar(1000) As Variant
    Dim i As Integer
    Dim visRange As Range, cll As Range
    Dim med As Double
    
    Set visRange = Selection.SpecialCells(xlCellTypeVisible)
    
        med = WorksheetFunction.Median(visRange)
    
    i = 0
    For Each cll In visRange
    myVar(i) = Abs(cll.Value - med) / med
    i = i + 1
    Next
    
    COD = WorksheetFunction.Average(myVar)
'    Debug.Print COD

End Sub

Thanks in advance,
Joe
 
Upvote 0
Rich (BB code):
Function COD2(UserRange As Range) As Double

    Dim myVar(1000) As Variant
    Dim i As Integer
    Dim visRange As Range, cll As Range
    Dim med As Double
   
    Set visRange = UserRange.SpecialCells(xlCellTypeVisible)
   
        med = WorksheetFunction.Median(visRange)
   
    i = 0
    For Each cll In visRange
       myVar(i) = Abs(cll.Value - med) / med
    i = i + 1
    Next
   
    COD2 = WorksheetFunction.Average(myVar)
'    Debug.Print COD

End Function
 
Upvote 0
Thanks 6String, I'd tried something like that and couldn't get it to work and i'm still getting a #REF! when i try to run it. I think i don't know how to pass the range to the Function.

In the previous version it was just the variable "r"... Function COD(r As Range) As Double

But for some reason, no matter what i try, this new function just keeps giving me an error, but the sub calculates correctly with no error, i can't figure out why...

Here's an example of how it's used just for clarity...

0.9
0.6
0.3
0.7
=COD2(A1:A4)

The function should produce a value of 0.269 and the original function does, as does the Sub, but this new version just gives me the #REF! error.

Any idea what might be going on?

Thanks,
Joe
 
Upvote 0
This should work but I haven't tested it.

Rich (BB code):
Function COD2(UserRange As Range) As Double

    Dim myVar(1000) As Variant
    Dim i As Integer
    Dim visRange As Range, cll As Range
    Dim med As Double
   
    Set visRange = UserRange.SpecialCells(xlCellTypeVisible)
   
        med = WorksheetFunction.Median(visRange)
   
    i = 0
    For Each cll In UserRange
       If Not cll.EntireRow.Hidden Then
          myVar(i) = Abs(cll.Value - med) / med
       End If
    i = i + 1
    Next
   
    COD2 = WorksheetFunction.Average(myVar)
'    Debug.Print COD

End Function
 
Upvote 0
Solution
Try to replace the function name "COD2" by other name like "F_COD".
ex:
VBA Code:
Function F_COD(UserRange As Range) As Double

    Dim myVar(1000) As Variant
    Dim i As Integer
    Dim visRange As Range, cll As Range
    Dim med As Double
  
    Set visRange = UserRange.SpecialCells(xlCellTypeVisible)
  
        med = WorksheetFunction.Median(visRange)
  
    i = 0
    For Each cll In visRange
       myVar(i) = Abs(cll.Value - med) / med
    i = i + 1
    Next
  
    F_COD= WorksheetFunction.Average(myVar)
'    Debug.Print COD

End Function
 
Upvote 0

Forum statistics

Threads
1,223,903
Messages
6,175,284
Members
452,630
Latest member
OdubiYouth

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top