为什么在选择之前必须激活Excel工作表?

时间:2012-10-02 23:36:48

标签: excel vba excel-vba datamodel

此代码

Sheets(1).Activate
Sheets(2).Range("A1").Select

将在VBA中失败,因为您只能在Select的对象上使用Active。我理解是这种情况。

Excel数据模型的哪个元素会导致这种情况?我认为在使用Activate之前,用户/编码器有一个隐含的意图Select任何对象 - 我不明白为什么VBA不会做出这个假设,并且我假设有这种区别存在的原因。

  • Excel的数据模型的哪一部分会阻止选择而不激活?

4 个答案:

答案 0 :(得分:5)

正如brettdj指出的那样,您无需激活工作表即可选择范围。这是一个引用数量惊人的examples for selecting cells/ranges

现在我为什么要首先激活表单?我不认为这是数据模型的错误,而只是Ranges的select方法的限制。

从实验中看,在Excel中选择一个范围看起来有两个要求。

  1. Excel必须能够更新UI以指示所选内容。
  2. 范围parent(I.E。工作表)必须处于活动状态。
  3. 要支持此声明,您也无法从隐藏的工作表中选择单元格。

    Sheets(1).Visible = False
    Sheets(1).Activate
    'The next line fails because the Range cannot be selected.
    Sheets(1).Range("A1").Select
    

    简单地说,当谈到Ranges时,你无法选择一个你看不到的。

    我会声称这是一起选择所有权限的限制,除了您可以实际选择隐藏表单中的对象。愚蠢的Excel。

答案 1 :(得分:2)

我知道派对的时间有点晚了,但我发现了这样做的黑客......

试试这段代码:

Sheets(1).Activate
Sheets(2).Range("A1").Copy
Sheets(2).Range("A1").PasteSpecial xlPasteFormulas
Application.CutCopyMode = False

请注意,这是一个黑客攻击,但它可以解决问题!!

答案 2 :(得分:0)

@Daniel Cook:感谢您的回复,但遗憾的是Excel本身并没有遵循Excel宏的相同规则......

为了说明,我将简要介绍我目前的问题......

我试图将表格的内容重新设置为公共状态。此方法将应用于各种工作表中的多个表:

Public Sub restoreTable()
    Dim myTableSheet As Worksheet: Set myTableSheet = Range("Table1").Parent
    Dim myTable As ListObject: Set myTable = myTableSheet.ListObjects("Table1")

    ' --- Clear Table's Filter(s)
    If myTable.ShowAutoFilter Then ' table has auto-filters enabled
        Call myTable.Range.AutoFilter ' disables autofilter
    End If
    myTable.Range.AutoFilter ' re-apply autofilter

    ' --- Sort by Sequence number
    Call myTable.Sort.SortFields.Clear ' if not cleared, sorting will not take effect

    myTable.Sort. _
        SortFields.Add Key:=Range("Table1[[#Headers],[#Data],[Column1]]"), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

    myTable.Sort.Header = xlYes
    myTable.Sort.Orientation = xlTopToBottom
    myTable.Sort.SortMethod = xlPinYin
    Call myTable.Sort.Apply

    myTable.Sort.SortFields.Clear
End Sub

对于下面的每个用例,Table1

中都会找到Sheet1

用例1:

  • 激活Sheet1,选择范围A1
  • 运行restoreTable
  • 观察:范围Sheet1 A1仍处于选中状态

用例2:

  • 激活Sheet1,选择范围A1
  • 激活Sheet2
  • 运行restoreTable
  • 观察:范围Sheet1 A1 已选中,而是选择范围Table1[#Data]

<强>解决方案

这绝对可怕,但这是我能找到的最佳解决方案

Public Sub resotreTable_preserveSelection()
    Dim curSheet As Worksheet: Set curSheet = ActiveSheet
    Dim tableSheet As Worksheet: Set tableSheet = Range("Table1").Parent

    ' Change Sheet
    tableSheet.Activate

    ' Remember Selection / Active Ranges
    Dim originalSelection As Range:  Set originalSelection = Selection
    Dim originalActiveCell As Range: Set originalActiveCell = ActiveCell

    ' Restore Table
    Call restoreTable

    ' Restore Old Selection
    originalSelection.Select
    originalActiveCell.Activate

    ' Change Back to old sheet
    curSheet.Activate
End Sub

注意:在这种情况下,original *范围不是必需的,但您明白了:您可以缓冲原始选择并在完成后将其恢复

我真的不喜欢excel

答案 3 :(得分:0)

当然,您不必选择或激活工作表来选择/激活单元格。我的方法是使用&#34; On Error Resume Next&#34;和&#34; On Error GoTo 0&#34;。下面的代码选择工作簿的每个工作表中的第一个单元格而不选择它。工作表甚至在这个阶段都非常隐蔽。

On Error Resume Next
For i_wks = 1 To wb_macro.Worksheets.Count
    wb_macro.Worksheets(i_wks).Cells(1).Select
Next i_wks
On Error GoTo 0