我对VBA如何在不同情况下处理Range感到困惑。
我有两张“Main”和“Data”。 “Main”表上有一个按钮,其中包含以下代码:
Worksheets("Data").Activate
Worksheets("Data").Select
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Dim SrchRange As Range
Set SrchRange = Range(Cells(1, 1), Cells(LastRow, 7))
因为即使激活并选择了“数据”表,SrchRange也会引用“主”表。对于“LastRow”,我发现这个解决方法将它作为ActiveSheet.Cells(...但对于“SrchRange”我找不到这样做的方法。 我至少尝试过:
Set SrchRange = ActiveSheet.Range(Cells(1, 1), Cells(LastRow, 7))
Set SrchRange = Sheets("Data").Range(Cells(1, 1), Cells(LastRow, 7))
Set SrchRange = Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(LastRow, 7))
所有这些都会给我一个运行时错误'1004'。如果更详细地描述Range,我不明白情况如何变化。即使使用Sheets和ActiveSheet,它不应该仍然是范围?我该怎么做到这一点?
我设法通过完全不使用Range变量来解决问题。 以下是使用SrchRange变量的部分。
For Each HeaderMatch In SrchRange
If HeaderMatch Like HeaderKeyWord Then
我将其替换为:
For Each HeaderMatch In ActiveSheet.Range(ActiveSheet.Cells(1, 1),
ActiveSheet.Cells(LastRow, 7))
If HeaderMatch Like HeaderKeyWord Then
我更喜欢第一个,因为它更清晰,更原则我想让它按照我的意图运作,因为我知道这是可能的,但我不知道如何。
我不太了解ActiveSheet的概念并选择了工作表。如果仍然需要将其称为ActiveSheet,激活工作表有什么意义?如果你总是需要使用参考,为什么不使用Sheets()来选择特定的工作表。并且更加激动Select的用途是什么?
答案 0 :(得分:2)
在同时处理2个或更多工作表时使用ActiveSheet
会让人感到困惑。最好将工作表设置为变量,如下面的代码:
Dim ws1 as Worksheet, ws2 As Worksheet
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
然后用这两个变量指向工作表。此外,使用With
块会使代码更清晰,以告知您正在处理哪个工作表。因此,您给出的代码可以重写如下:
Dim wsData As Worksheet
Set wsData = Worksheets("Data")
With wsData
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Dim SrchRange As Range
Set SrchRange = .Range(.Cells(1, 1), .Cells(LastRow, 7))
End With
我为ActiveSheet
进行了一些测试,并在没有指定特定参考的情况下调用集合。假设我有Workbook
个Worksheets
,一个名为SheetA
,另一个名为SheetB
。以下代码放在SheetA
。
Private Sub test()
Worksheets("B").Activate
MsgBox Range("A1").Parent.Name
MsgBox ActiveSheet.Range("A1").Parent.Name
End Sub
结果是第一个MsgBox
提供SheetA
,第二个提供SheetB
。因此,我假设如果您在未指定引用的情况下调用集合,则默认值是调用marco的集合。
然后我将代码放在一个模块中。这次MsgBox
无论在执行代码之前哪个工作表处于活动状态,都会得到相同的结果SheetB
。所以这是我的结论。
Workbook
。让我们来看看你提到的这三行:
Set SrchRange = Range(Cells(1, 1), Cells(LastRow, 7))
所有三个集合,即Range
,Cells
和Cells
。来自同一父代,代码属于或活动表,取决于代码的位置。所以它总是会通过编译器,但并不总能给你正确的结果。
Set SrchRange = Sheets("Data").Range(Cells(1, 1), Cells(LastRow, 7))
Range
集合来自Sheets("Data")
,但Cells
可能来自另一张表,因此有时会出错。
Set SrchRange = Range(Sheets("Data").Cells(1, 1), Sheets("Data").Cells(LastRow, 7))
两个Cells
来自同一张表格,但Range
的父级取决于atob('message I want to obfuscate')
。因此它与[2]相同,有时会通过,有时会失败。
答案 1 :(得分:1)
我自己遇到了这个问题。原因是因为.End()
方法仅适用于活动工作表。
每Microsoft's documentation的.End()
相当于按下 end + ↑, end + ↓ , end + ←或 end + →。只读Range对象。这就是为什么仅在当前选择数据的情况下使用Set Range1 = Sheets("Data").Range(("A1"),Range("A1").End(Xldown))
设置范围的原因。
要解决此问题,请使用数据表上的.Activate
方法来设置范围。
答案 2 :(得分:0)
如果所有工作表都在包含vba代码的工作簿中,则可以使用工作表代码名称,而不必设置为单个变量。
示例我将工作表“Data”的代码名称更改为cnData并使用此...
var currentView = '',
d = new Date(),
today = d.getDay(),
dow = 1;
$('#calendar').fullCalendar({
header: {
left: 'prev,next',
center: 'title',
right: 'month,agendaWeek'
},
defaultDate: d,
navLinks: true,
firstDay: 1, //Monday
viewRender: function(view) {
if (view && view.name !== currentView) {
if (view.name === 'agendaWeek') {
dow = today;
} else {
dow = 1;
}
setTimeout(function() {
$("#calendar").fullCalendar('option', 'firstDay', dow);
}, 10);
}
if (view) {
currentView = view.name;
}
}
});