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

Workdays for a market open Mon, Wed, Friday?
Yes! Use "0101011" for the weekend argument in NETWORKDAYS.INTL or WORKDAY.INTL. The 7 digits start on Monday. 1 means it is a weekend.
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
Unfortunately this still seems to be producing a #REF! error... not sure why
 
Upvote 0
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
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

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
Well this is interesting... changing the name as suggested with my original code (including the specialcells ect.) didn't work and using 6String's suggested code didn't work, but when i changed the name of 6String's suggested code to F_COD it produces the correct value on an unfiltered range, but the incorrect value on the filtered range... interestingly it does produce a number rather than an error... i have no idea why, but unfortunately it's still not the right number.
 
Upvote 0
Well this is interesting... changing the name as suggested with my original code (including the specialcells ect.) didn't work and using 6String's suggested code didn't work, but when i changed the name of 6String's suggested code to F_COD it produces the correct value on an unfiltered range, but the incorrect value on the filtered range... interestingly it does produce a number rather than an error... i have no idea why, but unfortunately it's still not the right number.

Well this is interesting... changing the name as suggested with my original code (including the specialcells ect.) didn't work and using 6String's suggested code didn't work, but when i changed the name of 6String's suggested code to F_COD it produces the correct value on an unfiltered range, but the incorrect value on the filtered range... interestingly it does produce a number rather than an error... i have no idea why, but unfortunately it's still not the right number.
I think i figured out why it was calculating the wrong value on the filtered range, my Median calculation wasn't set up to exclude the filtered rows. i've tried changing from WorksheetFunction.Median to WorksheetFunction.Aggregate(12,3,UserRange) and i think that might have just done the trick!!! Still not sure how renaming the function from COD to F_COD makes a difference, but it seems to! If someone could explain that to me i'd appreciate it.
 
Upvote 0

Forum statistics

Threads
1,223,911
Messages
6,175,323
Members
452,635
Latest member
laura12345

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