gpt4 book ai didi

excel - 是否可以在 VBA 中使用不同的数据类型进行 Let 和 Get?

转载 作者:行者123 更新时间:2023-12-04 21:09:53 26 4
gpt4 key购买 nike

我目前正在开发一个 Excel VBA 加载项,以将一个系统的 CSV 导出处理为利益相关者希望查看的格式。我对 OOP 还很陌生,但我认为可以转换优先级在 Let 代码中输入类型,并以与输出相同的格式存储数据。

我写了以下类(class):

'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

属性是 LongString ,不可能两者兼有。 Get/ Let/ Set访问器必须是一致的,在 VBA 中也是如此。

您可以 作弊 通过失去类型安全和早期绑定(bind),通过使您的属性成为 Variant ...但这并不是开始使用 OOP 的好方法 ;-)
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) 一个 Long ,您理所当然地期望 Get一个 Long也。这个类(class)正在乞求 PriorityName仅获取属性:
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

现在,早期绑定(bind)和类型安全(无论您在 VBA 中利用多少)的好处立即显而易见:当您编写分配 Priority 的代码时此类对象的属性, Enum 的 IntelliSense| type 指导表达式的编写:

available enum members appear in a dropdown list

此外, Enum正在抽象底层数值,这变得无关紧要:而不是魔法硬编码 1 ,代码现在显示 HighPriority .此外, Get访问器非常简单,非常好:a Get访问器永远不应该引发任何错误,所以越简单越好。

故事的精神:如果你能提供帮助,不要绕过类型安全,尽你所能保持你的代码早期绑定(bind) - 避免 ObjectVariant越多越好; Actor Object到任何地方的已知类/接口(interface)。

例如更喜欢这个:
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

关于excel - 是否可以在 VBA 中使用不同的数据类型进行 Let 和 Get?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56386250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com