在VBA中使用InputBox
方法可以让用户选择单元格区域,交互体验和输入公式参数基本上相同,其返回值为Range对象。语法格式参见:
InputBox微软帮助文档
如果用户选择了多个区域,如下图中黄色区域所示,那么使用Range对象的Address
属性获取单元格引用地址时,结果为$B$5:$B$7,$B$13,$B$19
。
如果希望得到每个单元格的单独地址($B$5,$B$6,$B$7,$B$13,$B$19
),那么可以使用VBA处理一下。
示例代码如下。
Sub demo()Dim arrAddress(), rngSelectSet rngSelect = Application.InputBox("Select Range", Type:=8)If Not rngSelect Is Nothing ThenReDim arrAddress(1 To rngSelect.Count)intIndex = 1For Each c In rngSelectarrAddress(intIndex) = c.AddressintIndex = intIndex + 1NextDebug.Print Join(arrAddress, ",")End IfEnd Sub
【代码解析】
第3行代码调用InputBox
方法实现用户选择单元格区域。
第4行代码判断用户是否选择了单元格区域。
第5行代码声明动态数组,用于保存单元格地址。
第6行代码初始化数组下标变量。
第7~10行代码使用For Each循环遍历单元格区域。
第8行代码将单元格地址保存在数组中。
第9行代码下标变量加一,指向下一个位置。
第11行代码调用Join
函数将数组组合为一个字符串。
运行示例代码【立即窗口】中输出如下图所示。
这个代码并不复杂,多少VBA爱好者都可以完成,这里要提醒大家注意的是,循环遍历Range对象有两种方法
For Each循环For循环,Range(编号)
对于连续单元格区域,这两种方式都可以,但是对于本示例来说,只能使用第一种方式。
使用第2中方式改写代码如下。
Sub demo()Dim arrAddress(), rngSelectSet rngSelect = Application.InputBox("Select Range", Type:=8)If Not rngSelect Is Nothing ThenReDim arrAddress(1 To rngSelect.Count)For intIndex = 1 To rngSelect.CountarrAddress(intIndex) = rngSelect.Cells(intIndex).AddressNextDebug.Print Join(arrAddress, ",")End IfEnd Sub
运行代码,结果如下所示。
$B$5,$B$6,$B$7,$B$8,$B$9
其中的问题在于rngSelect.Cells(intIndex)
,并没有像我们希望的那样在Range对象中依次遍历单元格,而是以第一个单元格为基准单元格,顺次向下定位单元格,因此返回值为5个连续单元格。
大家在选择遍历方法的时候,需要注意二者的区别,而不是简单地认为二者永远都是相同的。