将类型更改为 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 Let
和 Property Get
公开它们。通过这种方式,您可以在 set 或 get 上(从 class...而不是从 class). 外部修复问题
旁注,关于创建一个helper class
(正如有人向你推荐的):你可以将所有这些函数加入一个class您使用广泛,例如 RemoveArticle
或 InvertArticle
。但是,它需要在您每次要使用它们时创建一个实例对象,因此不能很好地与我给您的建议相结合(如果您只想简化代码)。因此,像现在这样将它们放在 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
希望对你有帮助
我听说过将用户定义类型 (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 Let
和Property Get
公开它们。通过这种方式,您可以在 set 或 get 上(从 class...而不是从 class). 外部修复问题
旁注,关于创建一个helper class
(正如有人向你推荐的):你可以将所有这些函数加入一个class您使用广泛,例如 RemoveArticle
或 InvertArticle
。但是,它需要在您每次要使用它们时创建一个实例对象,因此不能很好地与我给您的建议相结合(如果您只想简化代码)。因此,像现在这样将它们放在 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
希望对你有帮助