如何在一个范围内获得一个单元格的位置?

时间:2015-06-15 11:53:28

标签: excel vba excel-vba

我如何获得范围内细胞的相对位置?使用Row - 和Column - 属性查找工作表中单元格的位置是微不足道的,但我不确定如何在范围内执行相同操作。

我考虑使用我想要找到单元格位置的左上角单元格的位置,然后从工作表中单元格的位置中扣除它(-1),但它得到了有点累赘。是否有更优雅的方式来解决这个问题?

到目前为止,我的最佳尝试,包括测试,是:

Option Explicit

Sub test()
  Dim r As Range: Set r = Sheet1.Range("B2:E10")
  Dim c As Range: Set c = Sheet1.Range("C2")

  Debug.Print "Column in sheet: " & c.Column
  Debug.Print "Row in sheet: " & c.Row
  Debug.Print "Column in range: " & column_in_range(r, c)
  Debug.Print "Row in range: " & row_in_range(r, c)
End Sub

Function column_in_range(r As Range, c As Range) As Long
  column_in_range = c.Column - (r.Cells(1, 1).Column - 1)
End Function

Function row_in_range(r As Range, c As Range) As Long
  row_in_range = c.Row - (r.Cells(1, 1).Row - 1)
End Function

这给出了所需的输出:

Column in sheet: 3
Row in sheet: 2
Column in range: 2
Row in range: 1

但我想知道是否有任何我可以使用的本机功能呢?

5 个答案:

答案 0 :(得分:10)

使用 lori_m

提供的变体进行了更新
  

但我想知道是否有任何原生功能......

使用此

Sub test()
    Dim r As Range, c As Range
    With Sheet1
        Set r = .[B2:E10]
        Set c = .[C2]
    End With
    If Not Intersect(r, c) Is Nothing Then
        Debug.Print "Column in sheet: " & c.Column
        Debug.Print "Row in sheet: " & c.Row
        Debug.Print "Column in range: " & Range(r(1), c).Columns.Count
        Debug.Print "Row in range: " & Range(r(1), c).Rows.Count
    End If
End Sub

输出

Column in sheet: 3
Row in sheet: 2
Column in range: 2
Row in range: 1

答案 1 :(得分:5)

没有本地方法可以做到这一点。我也做了你在上面的代码中提到的。但是我做了一些额外的检查。

Sub test1()
    Dim r As Range: Set r = Sheet1.Range("B2:E10")
    Dim c As Range: Set c = Sheet2.Range("C2") '<~~ Changed Sheet1 to sheet2
    Dim rng As Range

    On Error Resume Next
    Set rng = Intersect(c, r)
    On Error GoTo 0

    '~~> Check if the range is in main range
    If Not rng Is Nothing Then
        '
        '~~> Rest of your code
        '
    Else
        MsgBox c.Address & " in " & c.Parent.Name & _
               " is not a part of " & _
               r.Address & " in " & r.Parent.Name
    End If
End Sub

答案 2 :(得分:5)

在我看来,几乎是原生的方式来检查它,但结果是一个字符串需要一些额外的操作。您需要使用的只是.Address property的正确构造(根据MSDN)。一些例子:

Dim r As Range: Set r = Sheet1.Range("B2:E10")

Dim c As Range: Set c = Sheet1.Range("c2")
Debug.Print c.Address(False, False, xlR1C1, , r.Cells(0, 0))
        '>>result: R[1]C[2]
'-----------------------------------------------------

Set c = Sheet1.Range("e2")
Debug.Print c.Address(False, False, xlR1C1, , r.Cells(0, 0))
        '>>result: R[1]C[4]
'-----------------------------------------------------

Set c = Sheet1.Range("e5")
Debug.Print c.Address(False, False, xlR1C1, , r.Cells(0, 0))
        '>>result: R[4]C[4]
'-----------------------------------------------------

答案 3 :(得分:4)

看看on MSDN to see more

您可以使用以下内容:

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIDeviceOrientationPortrait);//choose portrait or landscape}

- (BOOL) shouldAutorotate{
return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
//return UIInterfaceOrientationMaskLandscape;
return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{ 
//    return UIInterfaceOrientationLandscapeLeft |
//    UIInterfaceOrientationLandscapeRight;
return UIInterfaceOrientationPortrait;
}

但是你会得到关于行和列的信息,但不是单独的。

所以你仍然需要从两个函数中的答案中提取这些值(看起来像MsgBox ActiveCell.Address(RowAbsolute:=True, _ ColumnAbsolute:=True, _ ReferenceStyle:=xlR1C1, _ External:=False, _ RelativeTo:=Range("B2")) 'Or shorter version : MsgBox ActiveCell.Address(, , xlR1C1, False, Range("B2")) ),所以几乎相同的问题......

答案 4 :(得分:1)

我不完全确定这是不是你所追求的。 但在这里:

Sub ts2()

    Dim test As Range
    Set test = Range("B2:E10")

    Dim topcorner As Range
    Dim testcell As Range

    Set topcorner = Cells(test.Row, test.Column)
    Set testcell = Range("D7")
    rel_row = testcell.Row - topcorner.Row
    rel_col = testcell.Column - topcorner.Column

End Sub

通过这个,你会找到相对位置。 但也许你正在寻找一些内置功能? 如果这不是你想要的,请编辑你的帖子......