String VBA字符串是不可变的吗?

String VBA字符串是不可变的吗?,string,vba,excel,String,Vba,Excel,我知道.NET(因此VB.NET)字符串是不可变的。但是,我在Excel 2010中使用VBA 7.0。字符串是不可变的吗?我正在做大量的字符串处理,对于少量的字符串,一些(直接)字符串操作是可以的,但我担心它不会扩展-因为从一个字符串移动到另一个字符串的每个额外字符可能会创建另一个字符串实例。而VB.NET字符串是不可变的,这是System.string、VBA(包括VB6?)强制要求的字符串可以进行变异(例如使用Mid$)。请参阅并记录操作后的StrPtr结果 原始答案;有文档支持,与反例

我知道.NET(因此VB.NET)字符串是不可变的。但是,我在Excel 2010中使用VBA 7.0。字符串是不可变的吗?我正在做大量的字符串处理,对于少量的字符串,一些(直接)字符串操作是可以的,但我担心它不会扩展-因为从一个字符串移动到另一个字符串的每个额外字符可能会创建另一个字符串实例。

而VB.NET字符串是不可变的,这是System.string、VBA(包括VB6?)强制要求的字符串可以进行变异(例如使用
Mid$
)。请参阅并记录操作后的
StrPtr
结果


原始答案;有文档支持,与反例相反

VBA字符串是不可变的

与VB.NET一样,在不创建新字符串的情况下,无法“替换字符串的一部分”或“附加到”字符串。这是否重要——因为现代计算机非常快——取决于实际的算法、数据和环境


与.NET文档不同,VBA的此类行为参考[变得]难以追踪。从中,我们发现了这颗稀有的小宝石

单个数据值是不可变的。这意味着在VBA环境中没有可导致数据值更改为其他数据值的已定义机制


如果字符串表示“单个数据值”。

它们是不可变的,除非它们表现出可变的行为,否则它们不是

例如,通过
mid$()
分配的速度明显快于分配中的普通新字符串

Dim s As String

s = "ABC"

Debug.Print s, StrPtr(s)

'// -> ABC            122899836

Mid$(s, 1, 1) = "Z"

Debug.Print s, StrPtr(s)

'// -> ZBC            122899836     

s = "??" & Right$(s, 1)

Debug.Print s, StrPtr(s)

'// -> ??C            196635748 

VBA字符串是可变的。Alex K的回答是错误的,但他对微软VB.Net中的
Mid()=
软糖的看法是正确的,该软糖正确地宣称它们是不可变的-----尽管支持
Mid()=

因此,在所有VB6、VBA、VB.Net中,您可以使用(例如)
Mid(a$,1,2)=“hi”
,如Alex的回复中所述,覆盖字符串的部分内容。然而,正如user2864740所指出的,只有VB6和VBA可以非常快地完成这项工作。这是在VB6(VBA)和VB.Net中测试的代码

Dim n1&, start!, bigstring$
bigstring$ = Space(10 ^ 6)
start = timer() ' in vb.Net this is function with "timer = (DateTime.Now.Ticks - Today.Ticks) / 10000000.0#"

For n1 = 1 To 5000
    Mid(bigstring, n1, 1) = "1"
Next

Debug.Print("Elapsed millisecs: " & (timer() - start!) * 1000.0! & " over cycle count of " & n1 - 1)

在超过1兆字节的大字符串上,此技术对于速度至关重要,因此具有可扩展性。在VBA上,它可以在不到一毫秒的时间内完成此操作。然而,在VB.Net中,它的效率低得惊人——同样的测试在3GHz CPU上需要7秒,每次迭代大约1毫秒。随着迭代次数从5000次增加到100万次,VBA仍然只需要40毫秒。VB.Net需要30分钟。提示:在VB.Net中,您可以将
Dim BigByte()用作byte
然后
BigByte=System.Text.Encoding.UTF8.GetBytes(bigstring)
这样您就可以使用字节数组了。如何使其灵活和Unicode超出了这个主题。

+1我只是想说
Dim str As String:str=“this String”:Debug.Print VarPtr(str),strprtr(str):Mid(str,3,2)=“at”:Debug.Print VarPtr(str),strprprtr(str)
这个答案是错误的,但我同情这张海报,因为即使在发表这篇评论之日,微软仍然声称它们是不变的微软说疯狂的话!请参阅我的最后一个答案。@www-0av-Com您的链接是针对VB.NET的。说字符串是不可变的是正确的,因为它们在.NET中是不可变的。VBA是一种独立的语言。VB.NET执行了一个小“技巧”来重新分配变量,使其看起来字符串已更改。原始字符串没有更改<代码>Dim a$=“你好!”;Dim b$=a$;Console.WriteLine(ReferenceEquals(a$,b$);中期(a$,1)=“再见”;Console.WriteLine(ReferenceEquals(a$,b$)。这将显示“True,False”(使用MID将$重新分配给新字符串,同时保持原始字符串不变)。NET中的System.String类型是不可变的,不管使用它的语言是什么。我还没有在VB6/VBA中确认。您的参考链接是针对VB.NET的,其中字符串是不可变的,因为它们在.NET中原则上是不可变的,所以文档是正确的。在VBA中,没有这样的限制,字符串是可变的.Wrt。“所以,在所有VB6、VBA、VB.Net中,…”。无论如何,我已经更新了我的答案(不是这个答案),以反映Alex K的答案wrt VBA/VB6行为。感谢所有更新。当我准备将VB6 web服务器(使用
Mid()=
everywhere提高速度)迁移到VB.Net时,你们三位帮了我不少忙。我必须做出比最初想象的更大的改变。@user2864740。。既然我帮你纠正了你的答案,我自己也没有纠正,我就对你的回答投了更高的票,并且给一般性问题增加了很多深度,那么投更高的票怎么样?我不是荣誉猎人,但是有些事情没有一定的等级我是做不到的。交换条件(嗯?:)