Excel VBA Public 无法识别变量
Excel VBA Public Variables are not recognized
在 MS Excel
中,我试图声明一些 public 变量,以便在之后的几个模块中使用它们。但我收到此错误:
Ambiguous name detected: datebck
此错误对我声明的所有 public 个变量都有效。
模块是这样的:
Option Explicit
Public LastColumnBck As Long
Public wsbck As Worksheet
Public datebck As String
Public linebck As String
Public TargetRowBck1 As Integer
Public TargetRowBck2 As Integer
Public StationRowBck As Integer
Public Sub FindLastStationColumnBck()
Dim excelfilename As String
excelfilename = "ERTP-Construction Tracking Sheet " & "(" & datebck & ")" & ".xlsx"
Set wsbck = Workbooks(excelfilename).Worksheets(linebck)
TargetRowBck1 = wsbck.Application.WorksheetFunction.Match("Sand filling", wsbck.Range("A:A"), 0)
TargetRowBck2 = wsbck.Application.WorksheetFunction.Match("Asphalt", wsbck.Range("A:A"), 0) - 1
StationRowBck = wsbck.Application.WorksheetFunction.Match("Main Activity", wsbck.Range("A:A"), 0)
LastColumnBck = wsbck.Cells(StationRowBck, wsbck.Columns.Count).End(xlToLeft).Column
End Sub
用户表单代码:
Option Explicit
Private Sub CommandButton1_Click()
Unload UsrForm6
End Sub
Private Sub CommandButton2_Click()
datebck = TextBoxDateUsrForm6
linebck = ListBoxUsrForm6
Call Module20.Backfilling (*this is another module that should use public variables also*
End Sub
我之前尝试过这种类型的声明并且它们可以工作但是在这种情况下虽然代码结构完全相同但缺少什么?
所以错误基本上是说 datebck 是重复的。你在别处定义了吗?也许在您的代码中搜索 "datebck As",也许您在其他地方声明了它
这段经历应该可以帮助您理解为什么使用全局变量不是一个好主意。但是,如果您希望继续这样做,将您的全局变量放在 Class 中并将 Predeclared ID 设置为 true 是有意义的。
例如,如果您创建一个名为 Glb 的 Class,其中包含您的全局变量(并且仅包含这些变量),您将获得以下优势
你知道全局变量在哪里。
您可以轻松获得全局变量的智能感知。例如输入 'Glb.' 将调出全局变量列表,减少拼写错误和内存压力
如果您需要对分配给全局变量的值进行任何检查,这可以在 Glb Class.
中完成
我建议为 VBA 使用免费且出色的 Rubberduck 插件"'@PredeclaredId" 这使得设置 Class 的 Predeclared 属性几乎没有痛苦。
您可以仅使用变量声明
来启动全局 class
'@PredeclaredId
'@Exposed
Option Explicit
Public LastColumnBck As Long
Public wsbck As Worksheet
Public datebck As String
Public linebck As String
Public TargetRowBck1 As Integer
Public TargetRowBck2 As Integer
Public StationRowBck As Integer
当您需要开始添加验证代码时,您可以使用 Rubberduck 的字段封装重构将变量转换为属性
[![字段封装重构][1]][1]
这将为您提供以下 'free'
的代码
Option Explicit
Private Type TClass1
LastColumnBck As Long
Wsbck As Worksheet
Datebck As String
Linebck As String
TargetRowBck1 As Integer
TargetRowBck2 As Integer
StationRowBck As Integer
End Type
Private this As TClass1
Public Property Get LastColumnBck() As Long
LastColumnBck = this.LastColumnBck
End Property
Public Property Let LastColumnBck(ByVal RHS As Long)
this.LastColumnBck = RHS
End Property
Public Property Get Wsbck() As Worksheet
Set Wsbck = this.Wsbck
End Property
Public Property Set Wsbck(ByVal RHS As Worksheet)
Set this.Wsbck = RHS
End Property
Public Property Get Datebck() As String
Datebck = this.Datebck
End Property
Public Property Let Datebck(ByVal RHS As String)
this.Datebck = RHS
End Property
Public Property Get Linebck() As String
Linebck = this.Linebck
End Property
Public Property Let Linebck(ByVal RHS As String)
this.Linebck = RHS
End Property
Public Property Get TargetRowBck1() As Integer
TargetRowBck1 = this.TargetRowBck1
End Property
Public Property Let TargetRowBck1(ByVal RHS As Integer)
this.TargetRowBck1 = RHS
End Property
Public Property Get TargetRowBck2() As Integer
TargetRowBck2 = this.TargetRowBck2
End Property
Public Property Let TargetRowBck2(ByVal RHS As Integer)
this.TargetRowBck2 = RHS
End Property
Public Property Get StationRowBck() As Integer
StationRowBck = this.StationRowBck
End Property
Public Property Let StationRowBck(ByVal RHS As Integer)
this.StationRowBck = RHS
End Property
使用 'Predecalred' 属性意味着您可以获得 class 的默认实例,即您不必新建 Glb 对象。当然,通过将预先声明的属性设置为 true,您也承诺仅使用 Glb 实例而不创建实例。全局变量的多个实例保证让你头疼。
请注意,通过以这种方式使用 Class,您将迈出尝试性的第一步,在 VBA 中使用对象,而不是在模块中混合使用函数。
[1]: https://i.stack.imgur.com/WcSMM.jpg
在 MS Excel
中,我试图声明一些 public 变量,以便在之后的几个模块中使用它们。但我收到此错误:
Ambiguous name detected: datebck
此错误对我声明的所有 public 个变量都有效。
模块是这样的:
Option Explicit
Public LastColumnBck As Long
Public wsbck As Worksheet
Public datebck As String
Public linebck As String
Public TargetRowBck1 As Integer
Public TargetRowBck2 As Integer
Public StationRowBck As Integer
Public Sub FindLastStationColumnBck()
Dim excelfilename As String
excelfilename = "ERTP-Construction Tracking Sheet " & "(" & datebck & ")" & ".xlsx"
Set wsbck = Workbooks(excelfilename).Worksheets(linebck)
TargetRowBck1 = wsbck.Application.WorksheetFunction.Match("Sand filling", wsbck.Range("A:A"), 0)
TargetRowBck2 = wsbck.Application.WorksheetFunction.Match("Asphalt", wsbck.Range("A:A"), 0) - 1
StationRowBck = wsbck.Application.WorksheetFunction.Match("Main Activity", wsbck.Range("A:A"), 0)
LastColumnBck = wsbck.Cells(StationRowBck, wsbck.Columns.Count).End(xlToLeft).Column
End Sub
用户表单代码:
Option Explicit
Private Sub CommandButton1_Click()
Unload UsrForm6
End Sub
Private Sub CommandButton2_Click()
datebck = TextBoxDateUsrForm6
linebck = ListBoxUsrForm6
Call Module20.Backfilling (*this is another module that should use public variables also*
End Sub
我之前尝试过这种类型的声明并且它们可以工作但是在这种情况下虽然代码结构完全相同但缺少什么?
所以错误基本上是说 datebck 是重复的。你在别处定义了吗?也许在您的代码中搜索 "datebck As",也许您在其他地方声明了它
这段经历应该可以帮助您理解为什么使用全局变量不是一个好主意。但是,如果您希望继续这样做,将您的全局变量放在 Class 中并将 Predeclared ID 设置为 true 是有意义的。
例如,如果您创建一个名为 Glb 的 Class,其中包含您的全局变量(并且仅包含这些变量),您将获得以下优势
你知道全局变量在哪里。
您可以轻松获得全局变量的智能感知。例如输入 'Glb.' 将调出全局变量列表,减少拼写错误和内存压力
如果您需要对分配给全局变量的值进行任何检查,这可以在 Glb Class.
中完成
我建议为 VBA 使用免费且出色的 Rubberduck 插件"'@PredeclaredId" 这使得设置 Class 的 Predeclared 属性几乎没有痛苦。
您可以仅使用变量声明
来启动全局 class'@PredeclaredId
'@Exposed
Option Explicit
Public LastColumnBck As Long
Public wsbck As Worksheet
Public datebck As String
Public linebck As String
Public TargetRowBck1 As Integer
Public TargetRowBck2 As Integer
Public StationRowBck As Integer
当您需要开始添加验证代码时,您可以使用 Rubberduck 的字段封装重构将变量转换为属性
[![字段封装重构][1]][1]
这将为您提供以下 'free'
的代码Option Explicit
Private Type TClass1
LastColumnBck As Long
Wsbck As Worksheet
Datebck As String
Linebck As String
TargetRowBck1 As Integer
TargetRowBck2 As Integer
StationRowBck As Integer
End Type
Private this As TClass1
Public Property Get LastColumnBck() As Long
LastColumnBck = this.LastColumnBck
End Property
Public Property Let LastColumnBck(ByVal RHS As Long)
this.LastColumnBck = RHS
End Property
Public Property Get Wsbck() As Worksheet
Set Wsbck = this.Wsbck
End Property
Public Property Set Wsbck(ByVal RHS As Worksheet)
Set this.Wsbck = RHS
End Property
Public Property Get Datebck() As String
Datebck = this.Datebck
End Property
Public Property Let Datebck(ByVal RHS As String)
this.Datebck = RHS
End Property
Public Property Get Linebck() As String
Linebck = this.Linebck
End Property
Public Property Let Linebck(ByVal RHS As String)
this.Linebck = RHS
End Property
Public Property Get TargetRowBck1() As Integer
TargetRowBck1 = this.TargetRowBck1
End Property
Public Property Let TargetRowBck1(ByVal RHS As Integer)
this.TargetRowBck1 = RHS
End Property
Public Property Get TargetRowBck2() As Integer
TargetRowBck2 = this.TargetRowBck2
End Property
Public Property Let TargetRowBck2(ByVal RHS As Integer)
this.TargetRowBck2 = RHS
End Property
Public Property Get StationRowBck() As Integer
StationRowBck = this.StationRowBck
End Property
Public Property Let StationRowBck(ByVal RHS As Integer)
this.StationRowBck = RHS
End Property
使用 'Predecalred' 属性意味着您可以获得 class 的默认实例,即您不必新建 Glb 对象。当然,通过将预先声明的属性设置为 true,您也承诺仅使用 Glb 实例而不创建实例。全局变量的多个实例保证让你头疼。
请注意,通过以这种方式使用 Class,您将迈出尝试性的第一步,在 VBA 中使用对象,而不是在模块中混合使用函数。 [1]: https://i.stack.imgur.com/WcSMM.jpg