获取单元格可以包含的最大字符数
Excel规范和限制说:
单元格可以包含的字符总数: 32,767个字符
有没有办法以编程方式获得这个数字?
我在问,因为硬编码常数应该在一般情况下,如果可行的话,应避免。 这个数字可能会被Office版本所改变(它在2003到2013之间并没有改变,但谁知道微软为我们存储了什么)。
在工作表中获取最大数量的行很容易:
Sheet1.Rows.Count ' returns 65,536 in Office 2003 and 1,048,576 in Office 2007-2013
但显然,获取单元格可以包含的最大字符数并不那么简单。
请注意,将太多字符写入单元格不会导致错误; 它会默默地失败并截断string – 所以适当的error handling不是一个选项在这里。
替代方法:循环附加一个块,直到分配的长度不是预期的
Const INT_MAX As Integer = 32767 Dim i As Long ActiveCell.Value = "" Dim buff As String: buff = Space$(INT_MAX) Do i = i + 1 ActiveCell.Value = ActiveCell.Value & buff If Len(ActiveCell.Value) <> (i * INT_MAX) Then MaxLen = Len(ActiveCell.Value) Exit Function End If Loop
甚至
ActiveCell.Value = Space$(A_BIG_NUMBER) MaxLen = Len(ActiveCell.Value)
这是一个变体,我们采取指数步骤(更大和更大的步骤的大小增加一个因子stepFactor
每次)。
Function MaximumNumberOfCharactersACellCanContain(r As Range, _ Optional ByVal stepFactor As Double = 2) Dim n As Double Dim nActual As Long Dim l As Long n = 1 Do n = n * stepFactor nActual = CLng(n) r.Cells(1, 1).Value = Space$(nActual) l = Len(r.Cells(1, 1).Value) If l <> nActual Then MaximumNumberOfCharactersACellCanContain = l Exit Function End If Loop End Function
用法示例:
Debug.Print MaximumNumberOfCharactersACellCanContain(Range("A1"), 8)
stepFactor
的select是一个妥协之间:
- 减less迭代次数(更大的因子更好),和
- 限制最后一次迭代(失败的)的成本。 如果
stepFactor
太大,那么你写了一个非常长的string,这是非常缓慢的。 - 确保最后一次迭代不会超出内存限制(我的系统上约有1.3亿个字符)。 (可以添加error handling来处理这个可能性。)
介于2到8之间的stepFactor
应该健壮而快速。
在循环中,将字符逐个追加到单元格内容。 每次读取单元格内容,检查是否存在最后添加的字符。 如果不是那么这是限制。
上行:工作,100%可靠。
下行:真的很慢。 完成这个过程需要10到15秒钟,因为有很多对/从表单的读/写操作。
显然,这可以通过使用一个好的猜测(例如32,767)作为初始条件来优化,并且使用searchalgorithm而不是用1来递增。但是如果答案远离最初的猜测,这可能仍然是需要1秒钟的时间才能运行 – 而不是你想要重复调用的东西。
Function MaximumNumberOfCharactersACellCanContain(r As Range) 'NB: Range r will be overwritten. Dim sIn As String Dim sOut As String Dim i As Long Application.ScreenUpdating = False Do i = i + 1 sIn = sIn & Chr(97 + (i - 1) Mod 26) r.Cells(1, 1).Value = sIn sOut = r.Cells(1, 1).Value If Right(sOut, 1) <> Right(sIn, 1) Then Exit Do 'If Len(sOut) <> Len(sIn) Then Exit Do Loop Application.ScreenUpdating = True MaximumNumberOfCharactersACellCanContain = i - 1 End Function
用法示例:
MsgBox MaximumNumberOfCharactersACellCanContain(Range("A1"))