1

I'm calling VBA function from an Excel worksheet. When I change a cell inside the code of the VBA function, Excel tries to re-execute that function again (and again in the second iteration and ...)

Example: if you have the code:

Function test() As Variant
    Range("A1") = 1
    test = "test"
End Function

When you use "=test()" anywhere, it will return #VALUE!. A debug will show that when you update A1, it will try to re-execute test().

Can you prevent Excel from doing this? E.g. saying 'don't update any of my numbers until I'm done with this function'? I've tried the Application.Calculation flag, or doing some external concurrency checks, but that doesn't seem to work ...

4
  • 5
    Don't attempt to change a worksheet cell from a UDF, only return a value thru its header. Commented Nov 6, 2013 at 23:35
  • 1
    @Gary'sStudent valid point. Generally, you cant modify OTHER cells than the one the function is being called from. Change it to a Sub then youll be fine Commented Nov 6, 2013 at 23:39
  • 2
    It's returning the error because of what @Gary'sStudent mentions. The UDF is not allowed to manipulate the worksheet, and the line Range("A1") = 1 causes it to terminate. A debug will show you that this line fails. Commented Nov 7, 2013 at 2:02
  • 1
    What Gary mentions above is the reason for your #Value error. A debug will show that when you update A1, it will try to re-execute test(). Now I am curious as to why your code is being reexecuted again. Do you have a Worksheet_Change Code in your workbook? Commented Nov 7, 2013 at 6:38

3 Answers 3

0

Try:

Function test() as Variant
test="test"
End Function
Sign up to request clarification or add additional context in comments.

1 Comment

The goal was not to return "test", that was just the easiest example I could think of to change a value inside a function.
0

As Gary's student says in his comment: UDF's should only change worksheet entries of the cells that call the function, and this value should be returned as a result of the function, not by changing a cell value of an explicit address.

In other words, this does not work:

Function test() As Variant
    Range("A1") = 1
    test = "test"
End Function

Instead call test() from cell A1 and do this:

Function test() As Variant
    test = 1
End Function

If the desired behaviour is to edit multiple cells (the return value of the function AND another cell), this should be implemented through a sub rather than a function.

Comments

-1

To answer your specific question of how to stop the Function re-executing when you change A1 or your function, and stop it returning #Value:
1. Use the Excel user interface (Formulas--> calculation options) to change calculation mode to manual
2. add some error trapping to your function like this.

Function test() As Variant
    On Error Resume Next
    Range("A1") = 1
    test = "test"
End Function

as has already been said the function will not change the value of A1

3 Comments

Like I said: I've tried the Application.Calculation flag, or doing some external concurrency checks (I guess that's what you mean with error trapping), but that doesn't seem to work. Do you have some working code that shows what you mean?
this won't work, the OP is attempting to implement code that is specifically prohibited from executing.
The OP's question was how to stop the function returning #Value and executing every time he changed the function or the cell it referred to. That is what I answered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.