Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: Zipall

vba中使用index字符数为什么不能超过255?

  [复制链接]
 楼主| 发表于 2011-7-22 10:18 | 显示全部楼层
回复 吕?布 的帖子

谢谢你的回复.
没接触过c,虽然不懂它的原理,但是我觉得你的解释更容易接受一些.

不过从7楼的test5来看,是不是index函数在excel2010中做了修改?使得它摆脱了255的限制,进而能处理这种更长的字符串了?
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

发表于 2011-7-22 10:20 | 显示全部楼层
本帖最后由 兰色幻想 于 2011-7-22 10:24 编辑

回复 吕?布 的帖子

但在VBA受255限制有很多,象range里的字符串长度,evaluate中的表达式串,这和函数无关,我觉得这些受255字符限制是同一个原因所致。

点评

全是LPSTR(a null-terminated C string)的原因,这个东西害人害了很长时间,后面的版本,其它语言都要考虑兼容它  发表于 2011-7-22 10:44
回复

使用道具 举报

发表于 2011-7-22 10:35 | 显示全部楼层
实际上自己写XLL也受这个255限制,就是因为为个字符类型的原因,从2007好象放宽了这个限制。我刚查了一下SDK
Strings
All versions of Excel:

[signed] char * - null-terminated byte strings of up to 255 characters

unsigned char * - length-counted byte strings of up to 255 characters

Starting in Excel 2007:

unsigned short * - Unicode strings of up to 32,767 characters, which can be null-terminated or length-counted

回复

使用道具 举报

发表于 2011-7-22 10:38 | 显示全部楼层
本帖最后由 吕?布 于 2011-7-22 10:40 编辑

Worksheet, Argument, and String Limits
In Excel 2003, the worksheet contained 256 columns x 65,536 rows (28 x 216). In Excel 2007, this was expanded to 16,384 x 1,048,576 (214 x 220)—that is, from 224 to 234 cells. These new limits overflow the integer types that were used to contain them in the old range and array structures. This made it necessary to have new data structures with wider integers to define the size of ranges and arrays.

In Excel 2003, any function, whether built-in or provided by an add-in, was limited to at most 30 arguments. In Excel 2007, this is increased to 255.

DLLs and XLLs can now exchange long Unicode strings with Excel instead of just the limited length byte strings supported in the old C API.
回复

使用道具 举报

发表于 2011-7-22 10:48 | 显示全部楼层
从下面代码结果可以看出,字串数组在内存中的位置并不是连续的,所以Index函数一定是一个一个的拷贝字串值,而拷贝时很可能字串使用的是LPSTR类型
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Sub test()
    Dim arr, arr1
    Dim i As Long, j As Long
    Dim lCount As Long
    Dim s(1 To 1024) As Byte
    Dim lLen As Long, lRefCount As Long
   
    Debug.Print "元素", "内存地址", "元素值"
    arr = Range("a1:b5").Value
    For j = LBound(arr, 2) To UBound(arr, 2)
        For i = LBound(arr, 1) To UBound(arr, 1)
            CopyMemory lCount, ByVal VarPtr(arr(i, j)) + 8, 4& * 1          ' 取得字符串真实地址
            Debug.Print "arr(" + CStr(i) + "," + CStr(j) + ")", ; lCount, ;
            CopyMemory ByVal VarPtr(s(1)), ByVal lCount, LenB(arr(i, j))   ' 取得字符串内容
            Debug.Print s
        Next i
    Next j
    Debug.Print
   
    arr = Application.WorksheetFunction.Index(arr, 0, 2)
    For j = LBound(arr, 2) To UBound(arr, 2)
        For i = LBound(arr, 1) To UBound(arr, 1)
            CopyMemory lCount, ByVal VarPtr(arr(i, j)) + 8, 4& * 1          ' 取得字符串真实地址
            Debug.Print "arr(" + CStr(i) + ","; CStr(j) + ")", ; lCount, ;
            CopyMemory ByVal VarPtr(s(1)), ByVal lCount, LenB(arr(i, j))   ' 取得字符串内容
            Debug.Print s
        Next i
    Next j
    Debug.Print

    arr = Range("a6:b10").Value
    arr1 = Application.WorksheetFunction.Index(arr, 0, 2)
End Sub


评分

参与人数 1 +20 金币 +20 收起 理由
兰色幻想 + 20 + 20 学习~~~

查看全部评分

回复

使用道具 举报

发表于 2011-7-22 10:51 | 显示全部楼层
这个要有官方说明就好了,我们也不用在这里猜想

点评

我前面两个英文的就是官方说明啊,只是没有明确针对Index函数  发表于 2011-7-22 11:30
回复

使用道具 举报

 楼主| 发表于 2011-7-22 11:00 | 显示全部楼层
回复 吕?布 的帖子

这段代码在winxp+excel2010中运行,直接关掉了excel进程

根据7楼的测试,在声明了arr为string后,index在copy时为什么就不受这个限制了?
我是否可以理解为index在处理variant类型的string时,才会将它当做LPSTR处理?
回复

使用道具 举报

发表于 2011-7-22 11:17 | 显示全部楼层
据说是有两种字串
1. [signed] char * - null-terminated byte strings of up to 255 characters
2. unsigned char * - length-counted byte strings of up to 255 characters
你单个单元格时应该是使用的第二种。实际上,如果全是第一种,那Excel一个单元格的长度就不能超过255了,也许用的人会少很多。也许我们也不会在这里研究来研究去了

另外,我在2010里试了,代码没有问题啊,只不过CopyMemory是很容易出问题
字串数组中字串内存地址.rar (11.98 KB, 下载次数: 1)
回复

使用道具 举报

 楼主| 发表于 2011-7-22 11:23 | 显示全部楼层
本帖最后由 Zipall 于 2011-7-22 11:29 编辑

回复 吕?布 的帖子

这个确实没问题.
我在A列填充了公式 =row() 就出问题了


原来如此~~~

点评

不同类型的数据,储存格式是不一样的,如果是数值,数组元素内存地址是连续的,我这里的只适用于字串  发表于 2011-7-22 11:27
回复

使用道具 举报

发表于 2011-7-22 11:57 | 显示全部楼层
官方网页只找到个好象有点搭界的
http://support.microsoft.com/kb/213841/zh-cn
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-4 00:35 , Processed in 0.409248 second(s), 18 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表