vba - 将 Type 更改为 Class 会导致 ByRef 参数执行 ByVal

标签 vba class pass-by-reference user-defined-types

我听说过将用户定义类型 (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 LetProperty Get 公开它们。通过这种方式,您可以在 setget 上(从类内……而不是从类外修复东西)对属性进行所需的修改。

旁注,关于创建辅助类(正如有人向您推荐的那样):您可以将所有广泛使用的函数加入到一个类中,例如作为 RemoveArticleInvertArticle。但是,它需要在您每次要使用它们时创建一个实例对象,因此不能很好地与我给您的建议相结合(如果您只想简化代码)。因此,像现在这样将它们放在 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/

相关文章:

database - VBA 范围不起作用,全局参数?

vba - 如何检测当前打开的 swf 文件名

excel - Range.Item 和 Range.Cells 之间有什么区别?

javascript - js : how to access a class defined inside require from the outside (accessibility issue)

java - JNI目录结构c和java

C++ 通过引用传递 : two level deep function calls

C++ 类 : Pass by reference

ios - 传递对实例变量的引用?

excel - 删除工作表

javascript - 在激活另一个类时添加一个类