为什么Application.Clean()删除可打印的字符?

赏金问题:

虽然有一个答案提供了合理的解释,但我想确定是否出现string截断,因为Clean()是一个WorksheetFunction和该问题背后的推理。 当VBA调用时, WorksheetFunctions是否将string传递给一个“单元格”,以便在null Chr(0)处截断?

原问题:

为什么TestItApplication.Clean方法删除了Chr(0)之后的所有字符,即使它们是可打印的? 在null Chr(0)上进行replace之后, TestIt2正确返回8个字符。

编辑:
值得注意的是,某些版本的Excel将要求您编写Application.WorksheetFunction.Clean()
来testing这个错误。

 Sub TestIt() Dim TryIt As String TryIt = "Test" & Chr(0) & "asdf" MsgBox Len(TryIt) 'Prints 9 TryIt = Application.Clean(TryIt) MsgBox Len(TryIt) 'Prints 4 End Sub 

 Sub TestIt2() Dim TryIt As String TryIt = "Test" & Chr(0) & "asdf" MsgBox Len(TryIt) 'Prints 9 TryIt = Replace(TryIt, Chr(0), "") MsgBox Len(TryIt) 'Prints 8 End Sub 

对此的答案似乎很简单:删除所有字符后面的chr(0)是一个错误。

Clean被devise为只删除chr(0)以及其他非打印字符,如VBA语言参考中所示:

Clean函数devise用于从文本中删除7位ASCII码(值为0到31)中的前32个非打印字符。

对所有其他提到的chr()值进行Clean工作,除了chr(0)之后,清除所有后续字符。

如果您必须使用空值,则需要进行某种转换。 你可以通过TryIt = Replace(TryIt, Chr(0), Chr(1))来得到预期的结果,然后结果按预期工作(对于其他所有31个chr()被devise为删除):

 Sub TestIt3() Dim TryIt As String Dim iCounter As Integer For iCounter = 0 To 31 TryIt = "Test" & Chr(iCounter) & "asdf" TryIt = Replace(TryIt, Chr(0), Chr(1)) Debug.Print "chr(" & iCounter & ")" & " " & Len(TryIt) TryIt = Application.Clean(TryIt) Debug.Print "cleaned - chr(" & iCounter & ")" & " " & Len(TryIt) Next iCounter End Sub 

@Gserg在上面的评论是正确的

Visual Basic 不能处理由NULL字符终止的string。 事实上,所有的DLL都以这种方式终止string。 Chr(0)被视为string的终止字符。

这是检查它的最好方法。

 Sub TestIt() Dim TryIt As String TryIt = "Test" & Chr(0) & "asdf" Debug.Print Len(TryIt) Debug.Print TryIt ThisWorkbook.Sheets(1).Range("A1").Value = TryIt End Sub 

这将在单元格A1写入“testing”

最好的办法就是像你这样处理它。 使用。 .Replace 。 另一种(更长)的方法是使用INSTR