62

我想这样做,但它不会编译:

Public MyVariable as Integer = 123

实现这一目标的最佳方法是什么?

4

9 回答 9

117

.NET 宠坏了我们 :) 您的声明对 VBA 无效。

只有常量才能在应用程序加载时被赋予一个值。你像这样声明它们:

Public Const APOSTROPHE_KEYCODE = 222

这是我的一个 vba 项目的示例声明:

VBA 常量图像

如果您正在寻找声明公共变量然后想要初始化它的值的东西,您需要创建一个 Workbook_Open 子并在那里进行初始化。例子:

Private Sub Workbook_Open()
  Dim iAnswer As Integer

  InitializeListSheetDataColumns_S
  HideAllMonths_S

  If sheetSetupInfo.Range("D6").Value = "Enter Facility Name" Then
    iAnswer = MsgBox("It appears you have not yet set up this workbook.  Would you like to do so now?", vbYesNo)
    If iAnswer = vbYes Then
      sheetSetupInfo.Activate
      sheetSetupInfo.Range("D6").Select
      Exit Sub
    End If
  End If

  Application.Calculation = xlCalculationAutomatic
  sheetGeneralInfo.Activate
  Load frmInfoSheet
  frmInfoSheet.Show


End Sub

确保在 Workbook 对象本身中声明 sub: 在此处输入图像描述

于 2011-05-05T13:48:47.120 回答
12

只为给你一个不同的角度——

我发现在函数调用之间维护公共变量不是一个好主意。您需要使用的任何变量都应存储在 Subs 和 Functions 中并作为参数传递。代码运行完成后,您不应期望 VBA 项目维护任何变量的值。

这样做的原因是,在使用工作簿时,有很多事情可能会无意中重置 VBA 项目。发生这种情况时,任何公共变量都会重置为 0。

如果您需要将值存储在 subs 和函数之外,我强烈建议您使用带有命名范围的隐藏工作表来存储任何需要保留的信息。

于 2011-05-05T14:04:15.567 回答
9

当然你知道,但如果它是一个常数,那么const MyVariable as Integer = 123你就不走运了;该变量必须在别处分配一个初始值。

你可以:

public property get myIntegerThing() as integer
    myIntegerThing= 123
end property

然后在 Class 模块中全局创建它;

public cMyStuff as new MyStuffClass

所以cMyStuff.myIntegerThing立即可用。

于 2011-05-05T12:53:25.777 回答
6

鲜为人知的事实:
命名范围可以引用一个而不是特定的单元格。

这可以用作“全局变量”,另外您可以引用 VBA工作表单元格中的值,并且在关闭和重新打开工作簿后分配的值甚至会持续存在!


  • 要“声明”名称 myVariable并为其分配一个值123

    ThisWorkbook.Names.Add "myVariable", 123
    
  • 要检索值(例如在 a 中显示值MsgBox):

      MsgBox [myVariable]
    
  • 或者,您可以使用字符串引用名称:(与方括号相同的结果)

    MsgBox Evaluate("myVariable")
    
  • 要在工作表上使用值,只需在公式中按原样使用它的名称:

    =myVariable
    
  • 事实上,你甚至可以存储函数表达式:(有点像在JavaScript中)
    (诚然,我实际上想不出这会是有益的情况——但我也不在 JS 中使用它们。)

    ThisWorkbook.Names.Add "myDay", "=if(isodd(day(today())),""on day"",""off day"")"
    

方括号只是Evaluate方法的快捷方式。我听说使用它们被认为是混乱或“hacky”,但我没有遇到任何问题, Microsoft支持它们在 Excel 中的使用。

可能还有一种方法可以使用该Range函数来引用这些名称,但我没有看到任何优势,所以我没有深入研究它。


更多信息:

于 2020-07-14T16:35:50.720 回答
4

如上所述,要声明全局可访问变量,您可以在以 public 关键字开头的函数之外进行。

而且,由于在程序之外不允许做作,例如,您可以创建一个名为 InitGlobals 的子程序来初始化您的公共变量,然后您只需在语句的开头调用此子程序

这是一个例子:

Public Coordinates(3) as Double
Public Heat as double
Public Weight as double

Sub InitGlobals()
    Coordinates(1)=10.5
    Coordinates(2)=22.54
    Coordinates(3)=-100.5
    Heat=25.5
    Weight=70
End Sub

Sub MyWorkSGoesHere()
    Call InitGlobals
    'Now you can do your work using your global variables initialized as you wanted them to be.
End Sub
于 2015-08-11T11:20:52.653 回答
2

当我需要初始化全局常量时,我​​会这样做:
1. 添加一个名为Globals
2. 的模块,将这样的属性添加到Globals模块中:

Property Get PSIStartRow() As Integer  
    PSIStartRow = Sheets("FOB Prices").Range("F1").Value  
End Property  
Property Get PSIStartCell() As String  
    PSIStartCell = "B" & PSIStartRow  
End Property
于 2016-07-11T12:15:26.973 回答
1

您可以在通用声明中定义变量,然后在您的环境中触发的第一个事件中对其进行初始化。

或者,您可以自己创建一个具有相关属性的类,并在 Initialise 方法中对其进行初始化

于 2011-05-05T12:55:44.397 回答
0

有一种方法可以正确解决您的问题。很长时间以来,我和你有同样的担忧。经过长时间的搜索和学习,我终于得到了这种问题的解决方案。

解决方案是不需要声明变量,不需要给变量赋值,甚至不需要VBA代码。只需要excel本身的“命名范围”。

例如,“A1”单元格内容为“hello, world”。我们给“A1”单元格定义一个名字为“hello”,也就是说,“A1”单元格现在有了一个名字,叫做“hello”。在VBA代码中,我们只需要使用[hello]这个方法,就可以得到“A1”的值。

Sub test()
msgbox [hello]
end sub

msgbox 将显示“Hello, word”。

这样,我们得到一个没有任何声明或赋值的全局变量。它可以在任何子或函数中使用。

我们可以在 excel 中定义许多命名范围,而在 VBA 代码中我们只需使用 [] 方法来获取范围值。

实际上,[hello] 是函数 Evaluate["Hell"] 的缩写,但它更短一些。

于 2022-02-17T06:49:53.813 回答
-1

已经有一段时间了,但这可能会让您满意:

Public MyVariable as Integer: MyVariable = 123

这有点难看,因为您必须重新输入变量名,但它在一行上。

于 2013-10-29T07:56:40.790 回答