vba 列号中的列地址

vba column address from column number

我有一个列号,比如 columnNumber = 4。我需要此列的使用范围。我知道如何找到最后使用的行,我可以将列号转换为像这样的列号

ColumnLetter = Split(Cells(1, ColumnNumber).Address, "$")(1)
LastRow = sht.Cells(sht.Rows.Count, ColumnLetter).End(xlUp).Row

然后像这样建立一个地址

rngaddy = ColumnLetter & "1:" & ColumnLetter & LastRow

最后做

Range(rngaddy)

但是,有没有一种更简单的方法可以根据列的编号找到列的完整使用范围?

   Dim rngaddy As Range
    With Sheet1
        Set rngaddy = .Range(.Cells(1, 4), .Cells(.Rows.Count, 4).End(xlUp))
    End With

如果出于某种原因,您想查看 A1 表示法中的地址,只需:

debug.print rngaddy.address

请注意,这样做时,rngaddy 本身就是范围对象,而不是字符串。所以不需要做 Range(rngaddy)

您可以 return 最后填充的单元格位于列 # col 中:

MsgBox Cells(sht.Rows.Count,col).End(xlUp).Address

如果您也想 return 第一个填充的单元格,您可以使用:

MsgBox IIf(IsEmpty(Cells(1,col)),Cells(1,col).End(xlDown),Cells(1,col)).Address

因此,这 return 只有第 4 列 (D) 的 "used" 范围:

Sub Example_GetUsedRangeOfColumn()
   Const col = 4
   Dim sht As Worksheet
   Set sht = Sheets("Sheet1")
   MsgBox Range(IIf(IsEmpty(Cells(1, col)), Cells(1, col).End(xlDown), _
       Cells(1, col)), Cells(sht.Rows.Count, col).End(xlUp)).Address
End Sub

  • 所以这个例子:

    ...以上程序将 return: .

我的首选方法是尽可能使用 ListObjects aka Excel Tables 来保存任何输入数据。 ListObjects 是 Excel 代表您自动维护的命名范围,并且因为它们会在添加新数据时自动增长,所以它们为您提供了一种非常强大的方式来引用 Excel 中来自 VBA 的范围,这对用户做的事情更有免疫力,否则这些事情可能会破坏依赖于 .End(xlUp) 方法的代码。

? Range("MyTable").ListObject.ListColumns("Column 1").DataBodyRange.Address
$A:$A

通常我会给相关列一个自己的命名范围,以防用户(或开发人员)以后想要更改 Table 列名称,并在我的代码中使用该名称.

? Range("FirstColumn").Address
$A:$A

如果有人(也许是我)添加 rows/columns above/left 感兴趣的范围或打乱 Table 列的顺序,或更改列的名称,代码仍然引用预期的范围,不需要更改。

? Range("FirstColumn").Address
$C:$C
? Range(Range("FirstColumn").Address & ":" &  Range("FirstColumn").EntireColumn.cells(1).address).Address
$C:$C

当然,获取从顶部单元格(可能在 ListObject 上方)到相关列底部的范围的方法有点长,但是一旦您开始在代码中更多地使用 ListObjects,您通常不会不在乎上面或下面是什么......你只想要里面的货物。

我已经很多年没有使用 .End(xlUp) 了,除了在将其转换为 ListObject 的过程中查找我的数据应该在何处结束。但我是 ListObject 的传道者......你的里程可能会有所不同:-)

要获得您可以使用的列的 真实 UsedRange

With Columns(columnNumber).SpecialCells(xlCellTypeConstants)
    Set rngaddy = .Parent.Range(.Areas(1), .Areas(.Areas.Count))
End With

其中 rngaddy 是一个 Range 对象

当然,如果该列没有 "constant" 个单元格,上面的操作将会失败,那么您可能需要添加一些错误捕获或条目检查(例如 If WorksheetFunction.CountA(Columns(columnNumber)) = 0 Then Exit Sub

Option Explicit
Public Sub test()
    Const columnNumber As Long = 4
    Dim rngaddy As Range
    Set rngaddy = Intersect(Columns(2), ActiveSheet.UsedRange): Debug.Print rngaddy.Address
End Sub