简体   繁体   English

这个 VBA 代码有什么问题?

[英]What's wrong with this VBA code?

Sub variable()
Dim data As Integer
Dim square As Integer
Dim num As String
End Sub

Private Sub CommandButton1_Click()
num = InputBox("Give me the number!", "Your number")
data = CInt(num)
End Sub

Private Sub CommandButton2_Click()
square = (data ^ 2)
MsgBox ("The result: " & square)
End Sub

Could anyone help me?有人可以帮助我吗? Thanks.谢谢。 The result isn't the right number.结果不是正确的数字。 That is 0 all the time.那一直是0。

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.在 Visual Basic 编辑器中,选择工具 - 选项并选中需要变量声明。 This will automatically include Option Explicit at the top of any new modules.这将自动在任何新模块的顶部包含Option Explicit Unfortunately for existing modules, you'll have to type Option Explicit at the top yourself.不幸的是,对于现有模块,您必须自己在顶部键入Option Explicit

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).它会告诉您(在您的示例中) Variable not defined并突出显示num (因为它是第一个)。 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).本地- 在过程中使用Dim (在SubEnd Sub之间或等效的)。 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.模块- 在任何过程之外的模块顶部使用PrivateDim也可以使用)。 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). Global - 在标准模块(不是类模块,如 ThisWorkbook、Sheet1、Userform1 或 Class1)的顶部使用PublicGlobal也适用)。 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 .如果模块外部的过程需要使用该变量,您可能需要将其移动到标准模块并使用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.还有两件事:如果你使用Application.InputBox()你可以指定一个 Type 来确保用户输入一个数字。 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.如果您想继续使用InputBox()函数,那么当用户键入任何不能强制为数字的内容时, CInt将出错。 In that case, consider using the Val function.在这种情况下,请考虑使用Val函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM