问题现象
写宏时想拿到「数据最后一行」,是最高频也最容易出错的一步:
- 用向下定位的写法,区域里只有一个单元格有数据时,返回的是工作表的最末行,一百多万行;
- 数据中间夹着空行时,返回的行号停在第一处空行之前,后面的数据被整段漏掉;
- 用「已使用区域」取行数,明明只有五行数据,返回的结果却大得多;
- 给某个空单元格上了底色,什么都没写,结果却跟着变了;
- 变量声明成整型时,稍大的表直接抛出溢出错误;
- 工作表里一个数据都没有时,查找写法直接抛「对象变量未设置」的运行时错误。
原因分析
第一,向下定位模拟的是键盘操作。那段常见的写法等价于先按结束键再按方向键,其行为是「从起点出发,跳到当前连续区域的边界」。当起点下方没有任何数据时,它一路跳到工作表的最后一行;当中间存在空行时,它停在空行之前。也就是说,它返回的是「连续区域的终点」,而不是「数据的最后一行」,两者只在数据完全连续时才相等。
第二,已使用区域记录的是「曾经被用过」,不是「现在有数据」。只要某个单元格被写入过、设置过格式、上过色、加过边框,它就会被计入已使用区域。即便后来把内容清空,这个记录也不会立刻消失。因此用它的行数去反推数据末尾,结果必然偏大,而且会随着用户的格式操作而漂移。
第三,计数函数无法区分空行位置。统计非空单元格数量的函数只能给出总个数,一旦数据中间存在空行,个数与最后一行的行号就不再对应,把它当行号用必然出错