+ Reply to Thread
Results 1 to 12 of 12

Volatile Functions causing issues

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    03-27-2012
    Location
    England
    MS-Off Ver
    Excel 2007
    Posts
    290

    Volatile Functions causing issues

    Hello all,

    I have a user defined function that essentially does a bunch of "count if's" and returns and answer.
    When I alt:tab between spreadsheets I have noticed all the values that were viewable changed to display "#Value!".

    Nothing within the spreadsheet has changed and vba code also hasnt changed.

    so... to try to fix this I created a refresh macro "Refresh" which is just a simple...
    Sub Refresh()
    Dim r As Integer
    
    r = 1
    
    Do While r < 80
        Range("A" & r).Calculate
        r = r + 5
    Loop
    
    End Sub
    and this fixed it!.... once. If i want to get this to run a second time, I have to modify the VBA (even if it means just deleting the 5 and adding it back in....)

    Is there a refresh button that I can use that would actually correct this every time?
    Is there a way I can prevent the function being so volatile and easy to turn to "#Value!"?

    Kind Regards,
    Penfold

  2. #2
    Forum Guru Kaper's Avatar
    Join Date
    12-14-2013
    Location
    Warsaw, Poland
    MS-Off Ver
    most often: Office 365 in Windows environment
    Posts
    8,650

    Re: Volatile Functions causing issues

    How about short macro in Thisworksheet code:
    Private Sub Workbook_Activate()
    Application.Calculate 'or you can recalculate only specific sheet
    End Sub
    Best Regards,

    Kaper

  3. #3
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,643

    Re: Volatile Functions causing issues

    Try adding...
    Application.Volatile
    ...to the top of your UDF procedure.

    Otherwise, can you post the UDF code here?


    Application.Volatile Method
    Surround your VBA code with CODE tags e.g.;
    [CODE]your VBA code here[/CODE]
    The # button in the forum editor will apply CODE tags around your selected text.

  4. #4
    Forum Contributor
    Join Date
    03-27-2012
    Location
    England
    MS-Off Ver
    Excel 2007
    Posts
    290

    Re: Volatile Functions causing issues

    I have two UDF's both cause the problem...
    Function Plan_Target(MCA_Value As String, CalcType As String, Optional Given_Month As String, Optional Given_Year As Integer) As Single
    Application.Volatile
    Dim RAW As ListObject
        Set RAW = Sheets("Data").ListObjects("Table_awur_1")
    
    If CalcType = "T" Then
        'Target
            Dim Prio(6) As Integer, x As Integer  ' Create an array to store numbers
            Prio(0) = 0         ' Not used, we do not have a priority 0
    
            'Count the number of priority 1 - 5
            For x = 1 To 5
                Prio(x) = WorksheetFunction.CountIfs(Range("Planning_Sht[[#Data],[MCA]]"), MCA_Value, Range("Planning_Sht[[#Data],[Priority]]"), x)
            Next x
    
            'Calculate and Return Target
            Plan_Target = ((Prio(1) * 9) + (Prio(2) * 6) + (Prio(3) * 3) + _
                            (Prio(4) * 2) + Prio(5)) / 6
    
    Else
        'Ensuring all criteria are met.
        If Given_Month = "" Or IsNull(Given_Year) = True Then
            Plan_Target = CVErr(xlErrValue)
        End If
        
        Dim This_Month As Date, Next_Month As Date
            This_Month = Format(Given_Month & "/1/" & Given_Year, "mm/dd/yyyy")
        If This_Month = "12/1/" & Given_Year Then
            Next_Month = "1/1/" & Given_Year + 1
        Else
            Next_Month = DateAdd("d", 1, This_Month)
        End If
        
        'Preparation for calculation
            If CalcType = "P" Then
                'Planned
                x = 7
            ElseIf CalcType = "A" Then
                'Achieved
                x = 9
            Else
                'Cause an error if Plan_Target does not have a calculation type.
                Plan_Target = CVErr(xlErrValue)
            End If
            
        'Calculation
            Plan_Target = WorksheetFunction.CountIfs( _
                RAW.ListColumns(3).Range, "NIEB", _
                RAW.ListColumns(4).Range, "RED", _
                RAW.ListColumns(5).Range, "=" & MCA_Value, _
                RAW.ListColumns(x).Range, ">=" & This_Month, _
                RAW.ListColumns(x).Range, "<" & Next_Month)
    End If
    
    End Function
    and

    Function PCM_Checker(SIG As String, WP As String, Given_Month As String, Given_Year As Integer, Optional MCA As String) As Integer
    Application.Volatile
    Dim RAW As ListObject
        Set RAW = Sheets("Data").ListObjects("Table_awur_1")
        
    Dim This_Month As Date, Next_Month As Date
        This_Month = Format(Given_Month & "/1/" & Given_Year, "mm/dd/yyyy")
        
    If This_Month = "12/1/" & Given_Year Then
        Next_Month = "1/1/" & Given_Year + 1
    Else
        Next_Month = DateAdd("d", 1, This_Month)
    End If
    
    ' If the SIG is "ACTIVE" then the MCA must be given
    If SIG <> "* ACTIVE" Then
        PCM_Checker = WorksheetFunction.SumIfs(RAW.ListColumns(10).Range, _
                RAW.ListColumns(3).Range, "NIEB", _
                RAW.ListColumns(4).Range, "RED", _
                RAW.ListColumns(6).Range, SIG & " - " & WP, _
                RAW.ListColumns(7).Range, ">=" & This_Month, _
                RAW.ListColumns(7).Range, "<" & Next_Month)
    ElseIf MCA <> "" Then
        PCM_Checker = WorksheetFunction.SumIfs(RAW.ListColumns(10).Range, _
                RAW.ListColumns(3).Range, "NIEB", _
                RAW.ListColumns(4).Range, "RED", _
                RAW.ListColumns(6).Range, SIG & " - " & WP, _
                RAW.ListColumns(5).Range, "=" & MCA, _
                RAW.ListColumns(7).Range, ">=" & This_Month, _
                RAW.ListColumns(7).Range, "<" & Next_Month)
    Else
        PCM_Checker = CVErr(xlErrValue)
    End If
    
    End Function

  5. #5
    Forum Guru
    Join Date
    04-13-2005
    Location
    North America
    MS-Off Ver
    2002/XP and 2007
    Posts
    15,871

    Re: Volatile Functions causing issues

    Your first function is suffering from the same error discussed here: http://www.excelforum.com/excel-prog...ml#post3839103 You are using an unqualified reference to a range -- which usually means activesheet.range(...). When you step away from the sheet containing the UDF to another sheet, activesheet obviously changes, and the data in activesheet is likely incompatible with what the function wants -- causing the error.

    As before, I would suggest that you pass all information needed by the UDF to the UDF through the argument list. This should alleviate the errors you are getting, and will it also avoid any need to make the function volatile, because Excel will be able to fit the function into its calculation tree.
    Quote Originally Posted by shg
    Mathematics is the native language of the natural world. Just trying to become literate.

  6. #6
    Forum Contributor
    Join Date
    03-27-2012
    Location
    England
    MS-Off Ver
    Excel 2007
    Posts
    290

    Re: Volatile Functions causing issues

    is there any other way I can get around that? The range will always be constant to the workbook and macro.
    Is it possible to do something like...
    Dim RAW As ListObject
        Set RAW = ThisWorkbook.Sheets("Data").ListObjects("Table_owssvr_1")
    would that work better or no different?
    (I assume you are talking about the "ListObject" table.)

  7. #7
    Forum Guru
    Join Date
    04-13-2005
    Location
    North America
    MS-Off Ver
    2002/XP and 2007
    Posts
    15,871

    Re: Volatile Functions causing issues

    Quote Originally Posted by penfold1992 View Post
    is there any other way I can get around that? The range will always be constant to the workbook and macro.
    Is it possible to do something like...
    Dim RAW As ListObject
        Set RAW = ThisWorkbook.Sheets("Data").ListObjects("Table_owssvr_1")
    would that work better or no different?
    (I assume you are talking about the "ListObject" table.)
    Yes it is possible and it is syntactically correct. Only you can know if the data and reference are truly static. I find that, when I have done this sort of thing in the past thinking that it would always be static, when I come back to it, I tend to wish that I had coded it as an argument rather than hard coding it into the body of the function. Maybe think of it as a useful "best practices rule" (for which there will occasionally be exceptions). Many of us on here believe that passing data through the argument list is the best way to do it -- if you think your situation warrants an exception to this "rule", then you can certainly do it the way you are proposing.

    One way or another, it seems that the solution to your problem is to make sure that Excel/VBA cannot accidentally pull data from somewhere other than the intended range.

  8. #8
    Forum Contributor
    Join Date
    03-27-2012
    Location
    England
    MS-Off Ver
    Excel 2007
    Posts
    290

    Re: Volatile Functions causing issues

    Quote Originally Posted by MrShorty View Post
    One way or another, it seems that the solution to your problem is to make sure that Excel/VBA cannot accidentally pull data from somewhere other than the intended range.
    unfortunately I am still unable to get this to work as I want it to...
    I am returning to see if you can offer any further insight.

    Current Code:
    Function Plan_Target(SIG_Value As String, CalcType As String, Optional Given_Month As String, Optional Given_Year As Integer) As Single
    Dim Dta_WS As Worksheet, RED_WS As Worksheet
        Set Dta_WS = ThisWorkbook.Sheets("Data")
        Set RED_WS = ThisWorkbook.Sheets("RED Planning")
        
    Dim RAW As ListObject
        Set RAW = Dta_WS.ListObjects("Table_owssvr_1")
    
    If CalcType = "T" Then
        'Target
            Dim Prio(6) As Integer, x As Integer  ' Create an array to store numbers
            Prio(0) = 0         ' Not used, we do not have a priority 0
    
            'Count the number of priority 1 - 5
            For x = 1 To 5
                Prio(x) = WorksheetFunction.CountIfs(RED_WS.Range("RED_Planning[[#Data],[SIG]]"), SIG_Value, RED_WS.Range("RED_Planning[[#Data],[Priority]]"), x)
            Next x
    
            'Calculate and Return Target
            Plan_Target = ((Prio(1) * 9) + (Prio(2) * 6) + (Prio(3) * 3) + _
                            (Prio(4) * 2) + Prio(5)) / 6
    
    Else
        'Ensuring all criteria are met.
        If Given_Month = "" Or IsNull(Given_Year) = True Then
            Plan_Target = CVErr(xlErrValue)
        End If
        
        Dim This_Month As Date, Next_Month As Date
            This_Month = Format(Given_Month & "/1/" & Given_Year, "mm/dd/yyyy")
        If This_Month = "12/1/" & Given_Year Then
            Next_Month = "1/1/" & Given_Year + 1
        Else
            Next_Month = DateAdd("d", 1, This_Month)
        End If
        
        'Preparation for calculation
            If CalcType = "P" Then
                'Planned
                x = 7
            ElseIf CalcType = "A" Then
                'Achieved
                x = 9
            Else
                'Cause an error if Plan_Target does not have a calculation type.
                Plan_Target = CVErr(xlErrValue)
            End If
            
        'Calculation
            Plan_Target = WorksheetFunction.CountIfs( _
                RAW.ListColumns(3).Range, "RED", _
                RAW.ListColumns(4).Range, "NEIB", _
                RAW.ListColumns(5).Range, "=" & SIG_Value, _
                RAW.ListColumns(x).Range, ">=" & This_Month, _
                RAW.ListColumns(x).Range, "<" & Next_Month)
    End If
    The only area of issue I can potentially see is with the WorksheetFunction call.
    Otherwise, I have no clue where the additional errors are coming from.

    Kind Regards,
    Penfold

  9. #9
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,289

    Re: Volatile Functions causing issues

    Not just that - all the Range statements need qualifying too - like this one:
    Range("Planning_Sht[[#Data],[MCA]]")
    Remember what the dormouse said
    Feed your head

  10. #10
    Forum Contributor
    Join Date
    03-27-2012
    Location
    England
    MS-Off Ver
    Excel 2007
    Posts
    290

    Re: Volatile Functions causing issues

    ok I am still getting this issue occassionally... I will repost my code.

    Function Plan_Target(MCA_Value As String, CalcType As String, Optional Given_Month As String, Optional Given_Year As Integer) As Single
    Dim Dta_WS As Worksheet, PCM_WS As Worksheet
        Set Dta_WS = ThisWorkbook.Sheets("Data")
        Set PCM_WS = ThisWorkbook.Sheets("PCM Planning")
        
    Dim RAW As ListObject
        Set RAW = Dta_WS.ListObjects("Table_awur_1")
    
    If CalcType = "T" Then
        'Target
            Dim Prio(6) As Integer, x As Integer  ' Create an array to store numbers
            Prio(0) = 0         ' Not used, we do not have a priority 0
    
            'Count the number of priority 1 - 5
            For x = 1 To 5
                Prio(x) = WorksheetFunction.CountIfs(PCM_WS.Range("PCM_Planning[[#Data],[MCA]]"), MCA_Value, PCM_WS.Range("PCM_Planning[[#Data],[Priority]]"), x)
            Next x
    
            'Calculate and Return Target
            Plan_Target = ((Prio(1) * 9) + (Prio(2) * 6) + (Prio(3) * 3) + _
                            (Prio(4) * 2) + Prio(5)) / 6
    
    Else
        'Ensuring all criteria are met.
        If Given_Month = "" Or IsNull(Given_Year) = True Then
            Plan_Target = CVErr(xlErrValue)
        End If
        
        Dim This_Month As Date, Next_Month As Date
            This_Month = Format(Given_Month & "/1/" & Given_Year, "mm/dd/yyyy")
        If This_Month = "12/1/" & Given_Year Then
            Next_Month = "1/1/" & Given_Year + 1
        Else
            Next_Month = DateAdd("d", 1, This_Month)
        End If
        
        'Preparation for calculation
            If CalcType = "P" Then
                'Planned
                x = 7
            ElseIf CalcType = "A" Then
                'Achieved
                x = 9
            Else
                'Cause an error if Plan_Target does not have a calculation type.
                Plan_Target = CVErr(xlErrValue)
            End If
            
        'Calculation
            Plan_Target = WorksheetFunction.CountIfs( _
                RAW.ListColumns(3).Range, "NIEB", _
                RAW.ListColumns(4).Range, "RED", _
                RAW.ListColumns(5).Range, "=" & MCA_Value, _
                RAW.ListColumns(x).Range, ">=" & This_Month, _
                RAW.ListColumns(x).Range, "<" & Next_Month)
    End If
    
    End Function
    Do I still not have alll the ranges covered?

  11. #11
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,289

    Re: Volatile Functions causing issues

    I strongly suggest you go back to the original suggestion of passing the ranges to the function as arguments.

  12. #12
    Forum Guru
    Join Date
    04-13-2005
    Location
    North America
    MS-Off Ver
    2002/XP and 2007
    Posts
    15,871

    Re: Volatile Functions causing issues

    IMO, "Here's my code, it doesn't work" is one of the least useful "error statements" a debugger or an OP can give. What do you mean by "doesn't work"? Does it hang up? Does it give an error message? Does it run to completion, but the results are incorrect?

    I don't offhand see anything syntactically wrong with the worksheetfunction.countifs() call, so if there is an error here, it is related to the data in those ranges. You will need to look at the data in those ranges and the parameters sent to the countif function to see if there is some "incompatibility" that is causing an error/incorrect result.

    I know that one of the most used debugging strategies that I use is to set a breakpoint early in the function and step through the code one line at a time: http://www.cpearson.com/excel/DebuggingVBA.aspx If a statement errors, I will know which statement causes the error and can focus my debugging on that statement (through the locals window and various watches). If I am getting incorrect results, I can follow the values of the different variables to identify where in the calculation an unexpected result is occurring. It sounds like you have an added difficulty in that the error only occurs some of the time, which can mean looking at different contexts to understand when the errors are occurring.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Volatile Functions needed for Roulette
    By Nickmsi in forum Excel Programming / VBA / Macros
    Replies: 7
    Last Post: 04-06-2013, 07:57 PM
  2. External Links Causing Issues
    By kushalb in forum Excel General
    Replies: 4
    Last Post: 05-23-2011, 06:27 AM
  3. Volatile functions across books
    By jcarlosd in forum Excel Programming / VBA / Macros
    Replies: 0
    Last Post: 11-30-2008, 05:46 AM
  4. Negative value causing issues
    By Speedbird1 in forum Excel Formulas & Functions
    Replies: 2
    Last Post: 09-01-2008, 10:24 AM
  5. [SOLVED] If then statement causing value issues in Macros
    By ssciarrino in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 11-29-2005, 02:10 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1