我试图将一个简单的excel函数复制到VBA中,但是我遇到了Type mismatch错误。基本上,我有两个命名范围rDate和rYear以及以下Excel函数,它完美地提供以下输出:
= IF(YEAR(RDATE)= rYear,rYear,"&#34)
https://www.screencast.com/t/rPpsVjudqrI
但是,正如我所提到的,尝试将其转换为VBA时出现类型不匹配错误。这是我的代码:
Public ws As Worksheet
Sub Test()
Dim rDate, rYear, rResult, cell As Range
Set ws = Worksheets("Sheet1")
Set rDate = ws.Range("rDate")
Set rYear = ws.Range("rYear")
Set rResult = ws.Range("rResult")
For Each cell In rResult
If Year(rDate) = rYear Then 'Problematic line
cell = rYear
Else
cell = ""
End If
Next
End Sub
请让我知道我做错了什么。谢谢
答案 0 :(得分:1)
vba对范围的反应与工作表不同。在vba中,需要将一个单元的值与多个单元范围内的一个值进行比较,再到多单元范围。
而不是试图将整个范围等同于根据单元格的位置选择每个范围中的一个单元格。
要获得垂直范围的正确参考,我们要找到相对的行:
rDate.Cells(cell.Row - rResult.Row + 1, 1)
和相关栏目:
rYear.Cells(1, cell.Column - rResult.Column + 1)
然后:
Dim rDate, rYear, rResult, cell As Range
仅将cell
声明为范围,其他声明为Variant
。
所以使用:
Dim rDate As Range, rYear As Range, rResult As Range, cell As Range
工作表函数根据公式的相对位置对行和列进行假设,而vba则没有。
Public ws As Worksheet
Sub Test()
Dim rDate As Range, rYear As Range, rResult As Range, cell As Range
Set ws = Worksheets("Sheet1")
Set rDate = ws.Range("rDate")
Set rYear = ws.Range("rYear")
Set rResult = ws.Range("rResult")
For Each cell In rResult
If Year(rDate.Cells(cell.Row - rResult.Row + 1, 1)) = rYear.Cells(1, cell.Column - rResult.Column + 1) Then 'Problematic line
cell = rYear.Cells(1, cell.Column - rResult.Column + 1)
Else
cell = ""
End If
Next
End Sub
更快的方法是将数据加载到内存数组中并循环遍历这些数据。
Public ws As Worksheet
Sub Test()
Dim rDate, rYear, rResult
Dim i As Long, j As Long
Set ws = Worksheets("Sheet1")
rDate = ws.Range("rDate").Value
rYear = ws.Range("rYear").Value
ReDim rResult(1 To UBound(rDate, 1), 1 To UBound(rYear, 2))
For i = LBound(rDate, 1) To UBound(rDate, 1)
For j = LBound(rYear, 2) To UBound(rYear, 2)
If rYear(1, j) = Year(rDate(i, 1)) Then
rResult(i, j) = rYear(1, j)
Exit For
End If
Next j
Next i
ws.Range("rResult").Value = rResult
End Sub
每次从vba访问工作表时,都会降低代码的速度。使用此方法,我们只能访问工作表3次,无论范围有多大。