excel - 是否可以在 VBA 中使用不同的数据类型进行 Let 和 Get?
问题描述
我目前正在开发一个 Excel VBA 加载项,以将一个系统的 CSV 导出处理为利益相关者希望查看的格式。我对 OOP 还很陌生,但我认为可以转换优先级在 Let 代码中输入类型,并以与输出相同的格式存储数据。
我写了以下课程:
'Class Module "Project"
Option Explicit
Private m_sPriority As String
Property Let Priority(lInput As Long)
Select Case lInput
Case 1
m_sPriority = "High"
Case 2
m_sPriority = "Medium"
Case 3
m_sPriority = "Low"
Case Else
m_sPriority = "No Priority"
End Select
End Property
Property Get Priority() As String
Priority = m_sPriority
End Property
这是测试它的模块:
'Standard Module
Option Explicit
Sub test()
Dim Project As Project
Set Project = New Project
Project.Priority = 1
Debug.Print Project.Priority
End Sub
我希望在运行它时看到控制台的“高”输出。
有没有办法在 VBA 中实现这一点,或者,我的代码是否格式错误?
解决方案
是的,您的代码格式错误。不管它值多少钱,你也不能在 .NET 中这样做——无论是在 C# 中,语法都使它相当明确:
private string _priority;
public string Priority
{
get { return _priority; }
private set { _priority = value; }
}
...或在 VB 中:
Private _priority As String
Public Property Priority() As String
Get
Return _priority
End Get
Private Set(ByVal value As String)
_priority = value
End Set
End Property
属性要么是 a 要么是Long
a String
,不能同时是两者。Get
//访问Let
器Set
必须是一致的,在VBA中也是如此。
你可以通过失去类型安全和早期绑定来作弊,通过使你的属性成为......但这并不是开始使用 OOP 的好方法;-)Variant
Public Enum PriorityLevel
NoPriority = 0
HighPriority
MediumPriority
LowPriority
End Enum
Private Type InstanceState
Priority As PriorityLevel
'...
End Type
Private this As InstanceState
Public Property Get Priority() As Variant
Priority = PriorityName(this.Priority)
End Property
Public Property Let Priority(ByVal value As Variant)
this.Priority = value
End Property
Private Function PriorityName(ByVal value As PriorityLevel) As String
Select Case value
Case HighPriority
PriorityName = "High"
Case MediumPriority
PriorityName = "Medium"
Case LowPriority
PriorityName= "Low"
Case Else
PriorityName= "Undefined"
End Select
End Function
虽然这工作得非常好并且表面上看起来很整洁,但在你还没有编写它的时候使用这个类肯定会令人惊讶:如果你设置( Let
) a Long
,你也理所当然地期望Get
a Long
。这个类正在乞求一个PriorityName
get-only 属性:
Public Property Get Priority() As PriorityLevel
Priority = this.Priority
End Property
Public Property Let Priority(ByVal value As PriorityLevel)
this.Priority = value
End Property
Public Property Get PriorityName() As String
Select Case this.Priority
Case HighPriority
PriorityName = "High"
Case MediumPriority
PriorityName = "Medium"
Case LowPriority
PriorityName = "Low"
Case Else
PriorityName = "Undefined"
End Select
End Property
现在,早期绑定和类型安全(无论您在 VBA 中利用多少)的好处立即显而易见:当您编写分配Priority
此类型对象属性的代码时,该类型的IntelliSense将Enum
指导编写表达:
此外,它Enum
正在抽象底层数值,这变得无关紧要:1
代码现在说的是 ,而不是魔法硬编码HighPriority
。此外,Get
访问器尽可能简单,这非常好:Get
访问器永远不应该引发任何错误,所以越简单越好。
故事的精神:如果可以帮助,请不要绕过类型安全,尽一切可能使代码保持早期绑定 -尽可能避免Object
;在任何地方都可以转换为已知的类/接口Variant
。Object
例如更喜欢这个:
Dim sheet As Worksheet
' Workbook.Worksheets(index) returns Object; casting it to Worksheet
Set sheet = ActiveWorkbook.Worksheets(1)
sheet.Range("A1").Value = 42
对此:
' "Range("A1").Value" is entirely late-bound. Beware of typos!
ActiveWorkbook.Worksheets(1).Range("A1").Value = 42
推荐阅读
- redis - RedisJSON - MGET 示例?
- node.js - 我无法为节点 js 添加环境变量
- python - 如何编写我的代码以使其不超过时间限制?
- python - 当我运行代码时,我的所有复选框都被选中。我该如何停止?
- c - 高效的内存分配和释放问题
- flutter - 当我添加 firebase_dynamic_links 插件时,我在 flutter > File 'com.android.builder.files.ZipCentralDirectory@fa121b8' 中得到了这个错误
- c# - 数据库不更新 C#
- php - Kotlin io 套接字永远不会到达后端
- google-app-engine - 将 App Engine & Flask & SQLAlchemy 连接到 Cloud Sql
- python - 根据 DF 的特定行执行计算