将类型更改为 Class 会导致 ByRef 参数执行 ByVal

Changing a Type to a Class causes ByRef parameters to act ByVal

我听说过将用户定义类型 (UDT) 更改为常规 Class 的建议,以克服 UDT 的局限性,例如无法将 For Each 与 UDT 一起使用。

我还听到了从常规 Class 更改为 UDT 的建议,以克服无法通过 BYREF 传递事物的 Class 限制,例如...

'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

即使电影Class定义

strMovieTitle As String

我无法更改 RemoveArticle(以及类似它的每个简单小函数)以使用 MovieClass 参数而不是 String 参数,因为还有其他 UDT 或 Classes 和 String同样需要使用 RemoveArticle 的变量。

如果需要使用For Each,还需要传ByRef怎么办? 有没有办法 Class 可以解决参数问题?

(使用 Excel 2010。)

现在我明白你的顾虑了。

您根本无法采用这种方法来实现您的目标。正如蒂姆威廉姆斯在你的问题中评论的那样,你最好的选择是这样的:

Dim objMovie As MovieClass
Dim strMovieTitle As String
strMovieTitle = "Terminator, The"
objMovie.strMovieTitle = InvertArticle(strMovieTitle)

不过,我看还是不能满足你的需求。

我的建议如下:

  • 使您的对象成为内部对象,目标属性 Private 并使用 Property LetProperty Get 公开它们。通过这种方式,您可以在 setget 上(从 class...而不是从 class).
  • 外部修复问题

旁注,关于创建一个helper class(正如有人向你推荐的):你可以将所有这些函数加入一个class您使用广泛,例如 RemoveArticleInvertArticle。但是,它需要在您每次要使用它们时创建一个实例对象,因此不能很好地与我给您的建议相结合(如果您只想简化代码)。因此,像现在这样将它们放在 Module 中就可以了。澄清一下:他们给你的那些建议与你在这里的问题无关。

示例 A:在 set

在你的 class 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

希望对你有帮助