There are two problems with the code: You don't require variable declaration and you your variables are scoped differently than you expect.
In the Visual Basic Editor, choose Tools - Options and check Require Variable Declaration. This will automatically include Option Explicit
at the top of any new modules. Unfortunately for existing modules, you'll have to type Option Explicit
at the top yourself.
If you require variable declaration, the compiler will tell you when you're using a variable that's not in scope. It would have told you (in your example) Variable not defined
and highlighted num
(because it's the first one). That will help you identify these types of problems in the future.
Clearly you intended to declare your variables, you just didn't declare them in the right place. Your variable can have three scopes: local, module, global. You always want to use the smallest scope that suits your code. So use local, unless you need to use module. And use module unless global is absolutely necessary. Here's how the scopes work out:
Local - Use Dim
inside a procedure (between Sub
and End Sub
or equivalent). Nothing outside of that procedure can see or change the variable.
Module - Use Private
(Dim
also works) at the top of the module, outside of any procedures. Now all the procedures in that module can see and use the variable. Procedures in other modules cannot.
Global - Use Public
(Global
also works) at the top of a standard module (not a class module, like ThisWorkbook, Sheet1, Userform1, or Class1). Every procedure in your project can see and set this variable.
For your case, you should use a module scoped variable. Your event subs are in the same module and they are the only subs using these variables. If a procedure outside of the module needs to use the variable, you may need to move it to a standard module and declare it with Public
. But do that as a last resort. There are other options, like passing variables as a arguments, that are better than using global scoped variables.
Two more things: If you use Application.InputBox()
you can specify a Type that will ensure the user enters a number. If you want to continue to use the InputBox()
function, then CInt
will error when the user types anything that can't be coerced to a number. In that case, consider using the Val
function.