为什么Excel表格必须在select之前激活?

这个代码

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

将在VBA中失败,因为您只能在活动的对象上使用Select 。 我明白这是事实。

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

  • Excel的数据模型的哪个部分阻止select而不激活?

正如brettdj指出的那样,您不必为了select范围而激活工作表。 这里有一个参考与select单元格/范围的惊人的大量的例子 。

现在至于为什么我必须首先激活表格? 我不相信这是数据模型的错误,而只是范围select方法的限制。

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

  1. Excel必须能够更新UI以指示select的内容。
  2. 父级范围(IE表单)必须处于活动状态。

为了支持这种说法,你也不能从隐藏的表单中select一个单元格。

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

简单地说,当涉及到范围,你不能select一个你看不到的。

我会声称这是一个select所有在一起的限制,除了你可以实际select一个隐藏的工作表中的对象。 愚蠢的Excel。

我知道这个晚会有点迟,但是我发现了这个做法。

试试这个代码:

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

请注意,这是一个黑客,但它的窍门!

@Daniel Cook:感谢您的回复,但不幸的是,Excel本身并没有按照Excelmacros所强加的相同规则来玩。

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

我试图重新设置一个表的内容到一个共同的状态。 该方法将应用于各种表格中的多个表格:

 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 

对于下面的每个用例,在Sheet1findTable1

用例1:

  • 激活Sheet1 ,select范围A1
  • 运行restoreTable
  • 观察:范围Sheet1 A1保持选中状态

用例2:

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

这绝对是可怕的,但这是我能find的最好的解决scheme

 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 *范围是不必要的,但是您明白了:您可以caching原始select并在完成时恢复

我真的不喜欢excel

当然,您不必select或激活工作表来select/激活单元格。 我的方法是使用“On Error Resume Next”和“On Error GoTo 0”。 下面的代码select工作簿的每个工作表中的第一个单元格而不select它。 工作表甚至在这个舞台上都很隐蔽。

 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