确定string允许的最大长度a的通用方法

看看这个属性(鉴于你在第一张工作表上有一个表格):

Application.Sheets(1).ListObjects(1).name 

这个属性可以包含多less个字符? 那么,在testing了几个string之后,我得出结论:255,超过255个字符的任何string都会导致错误:

运行时错误5 – 无效的过程调用或参数

看看这个属性:

 Application.Sheets(1).ListObjects(1).Summary 

这个属性可以包含多less个字符? 同样,testing几个string,你会得到一个大约50,000的数字,你把它设置得更高,你会得到相同的错误,除非在这种情况下,Excel有时会崩溃或吐出一个不同的错误(多次尝试后):

 Dim i As Integer Dim a As String For i = 1 To 5001 a = a & "abcdefghih" Next i Application.Sheets(1).ListObjects(1).Summary = a 

对象'ListObject'的方法“摘要”失败

这种“隐藏的”字符限制出现在 这里 ( 在这里 , 这里 可能不太具体 ),并且它看起来不像他们在任何地方被logging,例如看看ListObject.Name的页面,没有注意到你可以在这个variables中存储多less个字符…

那么有没有更好的方法来确定呢? 您在属性中设置的string是否存储在固定长度的string中,这些string可以被访问以确定它们的最大长度是什么,或者是否有一些其他forms的文档可以用来获取这些信息?

这让我觉得奇怪的是,这些字符限制是在标准VBA对象中的大部分string上设置的,我不知道它们的目的是什么,为什么devise者select将“ListObjects.name”限制为255个字符,以及这是一个任意的默认限制还是那是一个有意识的决定。 我相信标准string的长度是这个 ,我不知道为什么偏离这个标准。

总结我上面提到的几点,把这个问题压缩成一句话:

是否有一种通用的方法来确定可以在对象的属性中设置的string的最大长度,而不是通过给它另一个值并忽略错误/检查字符截断来首先testing该string的属性?

首先,如果你的目的是存储关于对象的元信息 ,你可以使用CustomDocumentProperties 。 你可以在这里find关于它们的用法的示例,以及Chip Pearson 在这里的一些很好的包装。
由于它们的长度仍然非常有限(255个字符)(感谢您指出!),所以最好的解决scheme可能是使用CustomXMLParts如下所述 。 最难的部分就是使用VBA构build正确的XML,但如果添加对Microsoft XML的引用,也许并非不可能。

但是为了提供一些关于string属性最大长度问题的帮助,下面是一个testing设置,你可以用它(相对)快速地find任意属性的限制。 只需将第19行的ActiveWorkbook.Sheets(1).Namereplace为要testing的属性并运行TestMaxStringLengthOfProperty()

 Option Explicit Const PRINT_STEPS = True ' If True, calculation steps will be written to Debug.Print Private Function LengthWorks(ByVal iLengthToTest As Long) As Boolean Dim testString As String testString = String(iLengthToTest, "#") ' Build string with desired length ' Note: The String() method failed for different maximum string lengths possibly ' depending on available memory or other factors. You can test the current ' limit for your setup by putting the string assignment in the test space. ' In my tests I found maximum values around 1073311725 to still work. On Error Resume Next ' --------------------------------------------------------------------------------- ' Start of the Test Space - put the method/property you want to test below here ActiveWorkbook.Sheets(1).Name = testString ' End of the Test Space - put the method/property you want to test above here ' --------------------------------------------------------------------------------- LengthWorks = Err.Number = 0 On Error GoTo 0 End Function Private Sub TestMaxStringLengthOfProperty() Const MAX_LENGTH As Long = 1000000000 ' Default: 1000000000 Const MAXIMUM_STEPS = 100 ' Exit loop after this many tries, at most ' Initialize variables for check loop Dim currentLength As Long Dim lowerBoundary As Long: lowerBoundary = 0 Dim upperBoundary As Long: upperBoundary = MAX_LENGTH Dim currentStep As Long: currentStep = 0 While True ' Infinite loop, will exit sub directly currentStep = currentStep + 1 If currentStep > MAXIMUM_STEPS Then Debug.Print "Exiting because maximum number of steps (" & _ CStr(MAXIMUM_STEPS) & _ ") was reached. Last working length was: " & _ CStr(lowerBoundary) Exit Sub End If ' Test the upper boundary first, if this succeeds we don't need to continue search If LengthWorks(upperBoundary) Then ' We have a winner! :) Debug.Print "Method/property works with the following maximum length: " & _ upperBoundary & vbCrLf & _ "(If this matches MAX_LENGTH (" & _ MAX_LENGTH & "), " & _ "consider increasing it to find the actual limit.)" & _ vbCrLf & vbCrLf & _ "Computation took " & currentStep & " steps" Exit Sub Else ' Upper boundary must be at least one less upperBoundary = upperBoundary - 1 PrintStep upperBoundary + 1, "failed", lowerBoundary, upperBoundary, MAX_LENGTH End If ' Approximately halve test length currentLength = lowerBoundary + ((upperBoundary - lowerBoundary) \ 2) ' "\" is integer division (http://mathworld.wolfram.com/IntegerDivision.html) ' Using `left + ((right - left) \ 2)` is the default way to avoid overflows ' when calculating the midpoint for our binary search ' (see: https://en.wikipedia.org/w/index.php?title=Binary_search_algorithm& ' oldid=809435933#Implementation_issues) If LengthWorks(currentLength) Then ' If test was successful, increase lower boundary for next step lowerBoundary = currentLength + 1 PrintStep currentLength, "worked", lowerBoundary, upperBoundary, MAX_LENGTH Else ' If not, set new upper boundary upperBoundary = currentLength - 1 PrintStep currentLength, "failed", lowerBoundary, upperBoundary, MAX_LENGTH End If Wend End Sub Private Sub PrintStep(ByVal iCurrentValue As Long, _ ByVal iWorkedFailed As String, _ ByVal iNewLowerBoundary As Long, _ ByVal iNewUpperBoundary As Long, _ ByVal iMaximumTestValue As Long) If PRINT_STEPS Then Debug.Print Format(iCurrentValue, String(Len(CStr(iMaximumTestValue)), "0")) & _ " " & iWorkedFailed & " - New boundaries: l: " & _ iNewLowerBoundary & " u: " & iNewUpperBoundary End If End Sub 

最简洁的答案是不。

问候,扎克Barresse