我听说过将用户定义类型 (UDT) 更改为常规类的建议,以克服 UDT 的局限性,例如无法将 For Each 与 UDT 一起使用。
我还听到了从常规类更改为 UDT 的建议,以克服无法通过 BYREF 传递事物的类限制,例如...
'Function:
Public Function RemoveArticle (ByRef strMovieTitle As String)
'Expected input is like "Terminator, The"
strMovieTitle = Left(... 'removes the article.
End Function
对于这个调用来说效果很好:
Dim strMovieTitle As String
strMovieTitle = "Terminator, The"
RemoveArticle strMovieTitle
但不是这个调用:
Dim objMovie As MovieClass
objMovie.strMovieTitle = "Terminator, The"
objMovie.strMovieGenre = "Sci-Fi"
InvertArticle objMovie.strMovieTitle
即使 MovieClass 定义
strMovieTitle As String
我不能更改 RemoveArticle(以及类似它的每个简单小函数)以采用 MovieClass 参数而不是 String 参数,因为还有其他 UDT 或类和字符串变量也需要使用 RemoveArticle。
如果我需要使用 For Each 并且我还需要通过 ByRef 怎么办? 类有没有办法解决参数问题?
(使用 Excel 2010。)
最佳答案
现在我明白你的顾虑了。
您根本无法采用这种方法来实现您的目标。正如蒂姆威廉姆斯在您的问题中所评论的那样,您最好的选择是这样的:
Dim objMovie As MovieClass
Dim strMovieTitle As String
strMovieTitle = "Terminator, The"
objMovie.strMovieTitle = InvertArticle(strMovieTitle)
不过,我看这还是不能满足你的需求。
我的建议如下:
- 使您的对象成为内部对象,将属性设为
Private
,并使用Property Let
和Property Get
公开它们。通过这种方式,您可以在 set 或 get 上(从类内……而不是从类外修复东西)对属性进行所需的修改。
旁注,关于创建辅助类
(正如有人向您推荐的那样):您可以将所有广泛使用的函数加入到一个类中,例如作为 RemoveArticle
或 InvertArticle
。但是,它需要在您每次要使用它们时创建一个实例对象,因此不能很好地与我给您的建议相结合(如果您只想简化代码)。因此,像现在这样将它们放在 Module
中就可以了。澄清一下:他们给你的那些建议与你在这里的问题无关。
示例 A:在 set
在您的 MovieClass
类中,首先将 strMovieTitle
的所有实例重命名为 pStrMovieTitle
并将其添加到您的代码中:
Private pStrMovieTitle As String
Public Property Let strMovieTitle (strIn As String)
pStrMovieTitle = InvertArticle(strIn)
End Property
Public Property Get strMovieTitle As String
strMovieTitle = pStrMovieTitle
End Property
用法是这样的:
Dim objMovie As MovieClass
objMovie.strMovieTitle = "Terminator, The" ' the article position gets rectified on assignation
objMovie.strMovieGenre = "Sci-Fi"
'InvertArticle objMovie.strMovieTitle ' => you don't need to do this call
示例 B:关于get
要保留原始字符串,并在获取属性值时应用您的 helpers
。这样你就可以始终保留原始字符串。但是,这种方法需要更多的返工,并且只有在您有很多方法可以在代码的不同部分使用该 String
的情况下才值得使用。
Private pStrMovieTitleSource As String
Public Property Let strMovieTitle (strIn As String)
pStrMovieTitleSource = Trim(strIn)
End Property
Public Property Get strMovieTitleSource () As String
strMovieTitleSource = pStrMovieTitleSource
End Property
Public Property Get strMovieTitleRoot () As String
strMovieTitleRoot = RemoveArticle(pStrMovieTitleSource)
End Property
Public Property Get strMovieTitle () As String
strMovieTitle = InvertArticle(pStrMovieTitleSource)
End Property
希望对你有帮助
关于vba - 将 Type 更改为 Class 会导致 ByRef 参数执行 ByVal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45516092/