我听说使用.Select
在Excel VBA中会被人们所反感,但我不知道该如何避免使用它。如果能够使用变量而不是Select
函数,那么我的代码将更加可重用。然而,如果不使用Select
,我不确定如何引用诸如ActiveCell
等内容。
我找到了这篇关于范围的文章和这个避免使用select的例子,但我找不到任何有关“如何”的信息。
我听说使用.Select
在Excel VBA中会被人们所反感,但我不知道该如何避免使用它。如果能够使用变量而不是Select
函数,那么我的代码将更加可重用。然而,如果不使用Select
,我不确定如何引用诸如ActiveCell
等内容。
我找到了这篇关于范围的文章和这个避免使用select的例子,但我找不到任何有关“如何”的信息。
在我看来,使用.select
的人通常是像我一样通过录制宏并修改代码来学习VBA的人,他们没有意识到.select
和随后的selection
只是一个不必要的中间代理。
可以通过直接使用已经存在的对象来避免使用.select
,就像许多人已经发布的那样,这允许各种间接引用,比如以复杂的方式计算i和j,然后编辑cell(i,j)等。
否则,.select
本身并没有什么明显的问题,你很容易找到这个的用途。例如,我有一个电子表格,我在里面填写日期,激活执行某些神奇操作的宏,然后将其以可接受的格式导出到另一个工作表,但是这需要对相邻单元格进行一些最终的手动(不可预测)输入。这时,就需要使用.select
来节省鼠标移动和点击的时间了。
面对现实吧:录制宏时,这种情况经常发生:
Range("X1").Select
Selection.Copy
Range("Y9").Select
Selection.Paste
虽然这个人只想要的东西是:
Range("Y9").Value = Range("X1").Value
Destination_Range.Value = Source_Range.Value
Range("B1:B6").Value = Range("A1:A6").Value
。当然,上面的一些答案并没有解决OP的核心问题 :-) - T.M.Select
操作,特别是与所选单元格有关的情况(如 OP 在 ActiveCell
中提到的)。ActiveCell
是 J4。
ActiveCell.Offset(2,0).Value = 12
- 这将把距离 activecell
(即 J6)两行下方的单元格的值更改为 12。
- 如果是 -2
,则会将值 12 放在两行上面的 J2 中。
ActiveCell.Offset(0,1).Copy ActiveCell.Offset(,2)
- 这将把右侧一列的单元格(k4)复制到距离 activecell
两列的单元格(L4)中。
- 注意,偏移参数中可以省略 0
。
- 因此:ActiveCell.Offset(,2)
和 ActiveCell.Offset(0,2)
是相同的。
- 与前面的示例类似,-1
将使单元格向左移动一列(i4)。select
好。请注意,在工作表中应避免使用 EXCEL 函数 Offset,因为它是一个挥发性函数。Dim wb as Workbook
Dim ws as Worksheet
Set wb = ThisWorkBook
Set ws = wb.sheets("Output")
"Set wb = ThisWorkbook"命令是非常重要的。"ThisWorkbook"在Excel中是一个特殊的值,它表示你的VBA代码当前正在运行的工作簿。这是设置工作簿变量的一个非常有用的快捷方式。
在你的子程序顶部完成这个操作之后,使用它们非常简单,只需要在任何你会使用"Selection"的地方使用它们即可:
所以,要将"Output"工作表中的单元格"A1"的值更改为"Hello",不需要写成:
Sheets("Output").Activate
ActiveSheet.Range("A1").Select
Selection.Value = "Hello"
ws.Range("A1").Value = "Hello"
新的代码不仅更可靠,如果用户在处理多个电子表格时还不太可能崩溃;而且编写起来更短、更快、更容易。
另外一个好处是,如果你总是将变量命名为"wb"和"ws",那么你可以从一个工作簿复制和粘贴代码到另一个工作簿,通常只需要进行最少的修改就可以运行。
ThisWorkbook
... 我不确定你的评论是否准确。 - BigBenSub ShowParents()
Dim myRng As Range
Set myRng = ActiveCell
Debug.Print myRng.Address ' An address of the selected cell
Debug.Print myRng.Parent.name ' The name of sheet, where MyRng is in
Debug.Print myRng.Parent.Parent.name ' The name of workbook, where MyRng is in
Debug.Print myRng.Parent.Parent.Parent.name ' The name of application, where MyRng is in
' You may use this feature to set reference to these objects
Dim mySh As Worksheet
Dim myWbk As Workbook
Dim myApp As Application
Set mySh = myRng.Parent
Set myWbk = myRng.Parent.Parent
Set myApp = myRng.Parent.Parent.Parent
Debug.Print mySh.name, mySh.Cells(10, 1).Value
Debug.Print myWbk.name, myWbk.Sheets.Count
Debug.Print myApp.name, myApp.Workbooks.Count
' You may use dynamically addressing
With myRng
.Copy
' Pastes in D1 on sheet 2 in the same workbook, where the copied cell is
.Parent.Parent.Sheets(2).Range("D1").PasteSpecial xlValues
' Or myWbk.Sheets(2).Range("D1").PasteSpecial xlValues
' We may dynamically call active application too
.Parent.Parent.Parent.CutCopyMode = False
' Or myApp.CutCopyMode = False
End With
End Sub
Select
和/或ActiveSheet
等等。这里有一个我找到的例子:https://dev59.com/6mEh5IYBdhLWcg3wHAND - Rick.Select / .Selection
。 - BruceWayne