我的主要问题是分配变量并在VBA中操作它。
我知道这段代码有效,但我不确定这是否是在VBA中分配变量的正确方法,就像我对currentcell = Cells(i,1).Value
一样Sub C()
Dim i As Integer
For i = 1 To 4
currentcell = Cells(i, 1).Value
MsgBox currentcell
Next i
End Sub
答案 0 :(得分:1)
宏录制器和许多教程不会告诉你的是,这些调用隐含地引用了ActiveSheet
,这显然隐含在ActiveWorkbook
中。当你需要处理的只是一个单独的工作表时,它可能很好,但实际情况是从来没有这种情况,用ActiveSheet
隐式引用编写的代码非常脆弱,容易出错,而且底层导致过多的Stack Overflow问题被标记为vba:
Cells
Range
Name
Rows
Columns
每当您使用其中任何一个时,您都会针对某个全局范围的Property Get
访问者进行调用,该访问者“方便地”为您提取ActiveSheet
引用:
Rubberduck工具栏的屏幕截图,显示所选代码的声明网站。 免责声明:我管理开源VBIDE加载项目。
所以是的,这个“有效”,但你想要的是取而代之的是显式的 Worksheet
对象引用。有许多方法来获取Worksheet
对象引用,但最好的方法是不关心工作表的来源,并将其作为参数:
Sub DoSomething(ByVal ws As Worksheet)
Dim currentCell As Variant
Dim i As Integer
For i = 1 To 4
currentcell = ws.Cells(i, 1).Value
'in-cell error values can't be converted to a string:
If Not IsError(currentCell) Then MsgBox currentcell
Next i
End Sub
这需要负责确切知道要使用哪个工作表而不是程序,并将其提供给调用代码,如下所示:
DoSomething Sheet1 'uses the sheet's CodeName property
或者这个:
DoSomething ThisWorkbook.Worksheets("Period" & n)
或者其他什么。有很多方法,每种都有自己的陷阱 - 通常你会看到这样的东西:
DoSomething Sheets("Sheet1") 'where "Sheet1" is in ThisWorkbook
除Sheets
隐式引用ActiveWorkbook
之外,ThisWorkbook
可能是Sheets
,Chart
集合可能会返回Worksheet
1}}对象,不是"Sheet1"
。此外,如果ThisWorkbook
位于CodeName
(包含正在运行的代码的工作簿)中,则按名称引用工作表意味着只要用户重命名该工作表的选项卡,代码就会中断。
引用编译/设计时存在的工作表的最强大方法是CodeName
。在 Project Explorer (Ctrl + R)中选择工作表,然后打开 Properties 工具窗口(F4),并通过更改{{(Name)
来设置它。 1}}属性到你需要的任何东西:VBA用这个名称定义一个全局范围的全局对象变量,所以你可以调用它MyAwesomeReport
然后在代码中引用它:
DoSomething MyAwesomeReport
如果用户更改工作表的“名称”,该代码将不会中断。
您的代码(无论该代码片段多么小)还有其他问题,特别是它使用未声明的变量,这意味着您没有使用Option Explicit
,这是另一件事情,最终会在后端咬你并且在Stack Overflow中遇到一个令人尴尬的问题,归结为一个错字 - 因为在每个模块的顶部都没有指定Option Explicit
,VBA会很乐意编译一个拼写错误,使你的代码行为异常,而不是简单地编译。这些错误很难找到,而且它们很容易被阻止:
使用。选项。明确。总是