【问题标题】:Excel VBA Public Variables are not recognizedExcel VBA 公共变量无法识别
【发布时间】:2021-03-27 00:53:09
【问题描述】:

MS Excel 中,我试图声明一些公共变量以在之后的几个模块中使用它们。但是我收到了这个错误:

检测到不明确的名称:datebck

此错误对我声明的所有公共变量均有效。

模块如下:

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”也许你在其他地方声明了它
  • 是的,问题是由于将同一变量多次声明为公共变量而发生的。当我删除重复的定义时,一切正常。
  • 请将我的答案标记为可接受的解决方案,以便其他访问者也能找到它

标签: excel vba variables public ambiguous


【解决方案1】:

所以错误基本上说 datebck 是重复的。你在别处定义了吗?也许在你的代码中搜索 "datebck As",也许你在别处声明它

【讨论】:

    【解决方案2】:

    这个经验应该可以帮助您理解为什么使用全局变量不是一个好主意。但是,如果您希望继续这样做,将您的全局变量放在一个将 Predeclared ID 设置为 true 的类中是有意义的。

    例如,如果您创建一个名为 Glb 的类,其中包含您的全局变量(并且仅包含这些变量),您将获得以下优势

    1. 你知道全局变量的位置。

    2. 您可以轻松地对全局变量进行智能感知。例如输入“Glb”。将显示您的全局变量列表,从而减少拼写错误和记忆压力

    3. 如果您需要对分配给全局变量的值进行任何检查,可以在 Glb 类中完成。

    我建议为 VBA 使用免费且出色的 Rubberduck 插件在这个插件中,许多人才是使用 cmets 作为注释,例如"'@PredeclaredId" 这使得设置类的 Predeclared 属性几乎没有痛苦。

    你可以只用变量声明来启动你的全局类

    '@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]

    这将为您提供以下“免费”代码

    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”属性意味着您获得了该类的默认实例,即您不必新建 Glb 对象。当然,通过将 predeclared 属性设置为 true,您还承诺只使用 Glb 实例而不是创建实例。全局变量的多个实例肯定会让您头疼。

    但请注意,通过以这种方式使用类,您将初步尝试在 VBA 中使用对象,而不是在模块中使用混杂的函数。 [1]:https://i.stack.imgur.com/WcSMM.jpg

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-15
      • 2015-10-27
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多