Table ListObject 不限于 table 行,而是计算整个 sheet
Table ListObject not limited to rows of table but counts the whole sheet
我使用 insert / table 命令在 excel 中创建了两个名为 table 的文件,并将它们命名如下。在 excel 中,一切看起来都很好。 table House_details 的行数是 50,包括 header 行,Sale_price_schedule 的行数是 15,包括 header 行。
我的相关 vba 代码是
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 2 To Rows.Count
iTemp = Rows.Count
strProductType = Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = Rows.Count
For iCount2 = 2 To Rows.Count
If Cells(iCount2, 3) = strProductType And Cells(iCount2, 1) <= dSaleDate And Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
Cells(iCount, 6) = dblSalePrice
Next iCount
End With
我的问题是 tblHouseDetails 行数不是我在 Excel 中定义的 50 行,而是完整的 sheet (1048576)。
为什么我的 Rows.Count 不正确?
当"Rows"和"Cells"单独使用时,指的是"ActiveSheet.Rows"和"ActiveSheet.Cells"。
如果你想引用"With.DataBodyRange"的范围,你需要在前面加一个点(".Rows", ".Cells"):
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 1 To .Rows.Count
iTemp = .Rows.Count
strProductType = .Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = .Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = .Rows.Count
For iCount2 = 1 To .Rows.Count
If .Cells(iCount2, 3) = strProductType And .Cells(iCount2, 1) <= dSaleDate And .Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = .Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
.Cells(iCount, 6) = dblSalePrice
Next iCount
End With
但更好的解决方案是将行用作变量:
Dim rowsA As Range, rowsB As Range
Set rowsA = tblHouseDetails.DataBodyRange.Rows
Set rowsB = tblSalePriceSchedule.DataBodyRange.Rows
'Find the product type, look for the relevant price and insert it into the appropriate house details column
For i = 1 To rowsA.Count
strProductType = rowsA.Cells(i, 5).Value 'The fifth columns is the product type
dSaleDate = rowsA.Cells(i, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
dblSalePrice = -999
For j = 1 To rowsB.Count
If rowsB.Cells(j, 3) = strProductType And rowsB.Cells(j, 1) <= dSaleDate And rowsB.Cells(j, 2) >= dSaleDate Then
rowsA.Cells(i, 6) = rowsB.Cells(j, 4)
End If
Next
Next
如果您正在寻找一个高性能的解决方案,我会使用数组中的值:
Dim dataA(), dataB(), i&, j&, strProductType$, dSaleDate, dblSalePrice
' Get all the values in an array
dataA = Sheets("House details").ListObjects("House_details").DataBodyRange.Value
dataB = Sheets("Sale price schedule").ListObjects("Sale_price_schedule").DataBodyRange.Value
For i = 0 To UBound(dataA)
strProductType = dataA(i, 4) 'The fifth columns is the product type
dSaleDate = dataA(i, 2) 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
dblSalePrice = -999
For j = 0 To UBound(dataB)
If dataB(j, 2) = strProductType And dataB(j, 0) <= dSaleDate And dataB(j, 1) >= dSaleDate Then
dataA(i, 5) = dataB(j, 3)
End If
Next
Next
' Copy the values back to the sheet
Sheets("House details").ListObjects("House_details").DataBodyRange.Value = dataA
您在 .DataBodyRange property of the House_details ListObject. All references used inside that With ... End With statement 内工作需要以句号开头(又名 句号 或 .
)以便传递给父级参考。
Rows.Count
需要.Rows.Count
,Cells(iCount2, 3)
需要.Cells(iCount2, 3)
,等等
Range.Parent property shifts to the Sale_price_schedule table once you enter the nested With ... End With and these Range.Cells and Range.Rows 属性需要相同的语法才能将其父引用调整为 Sale_price_schedule table。
所有 Cells(...)
和 Rows.Count
调用都默认为 ActiveSheet property,没有序号。
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 2 To .Rows.Count
iTemp = .Rows.Count
strProductType = .Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = .Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = .Rows.Count
For iCount2 = 2 To .Rows.Count
If .Cells(iCount2, 3) = strProductType And .Cells(iCount2, 1) <= dSaleDate And .Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = .Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
.Cells(iCount, 6) = dblSalePrice
Next iCount
End With
在相关说明中,检索 Range.Row property will retrieve the actual row on the worksheet and must be adjusted by the row of the .HeaderRowRange property 到 return 行在 table.
中的位置
我使用 insert / table 命令在 excel 中创建了两个名为 table 的文件,并将它们命名如下。在 excel 中,一切看起来都很好。 table House_details 的行数是 50,包括 header 行,Sale_price_schedule 的行数是 15,包括 header 行。
我的相关 vba 代码是
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 2 To Rows.Count
iTemp = Rows.Count
strProductType = Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = Rows.Count
For iCount2 = 2 To Rows.Count
If Cells(iCount2, 3) = strProductType And Cells(iCount2, 1) <= dSaleDate And Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
Cells(iCount, 6) = dblSalePrice
Next iCount
End With
我的问题是 tblHouseDetails 行数不是我在 Excel 中定义的 50 行,而是完整的 sheet (1048576)。
为什么我的 Rows.Count 不正确?
当"Rows"和"Cells"单独使用时,指的是"ActiveSheet.Rows"和"ActiveSheet.Cells"。
如果你想引用"With.DataBodyRange"的范围,你需要在前面加一个点(".Rows", ".Cells"):
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 1 To .Rows.Count
iTemp = .Rows.Count
strProductType = .Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = .Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = .Rows.Count
For iCount2 = 1 To .Rows.Count
If .Cells(iCount2, 3) = strProductType And .Cells(iCount2, 1) <= dSaleDate And .Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = .Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
.Cells(iCount, 6) = dblSalePrice
Next iCount
End With
但更好的解决方案是将行用作变量:
Dim rowsA As Range, rowsB As Range
Set rowsA = tblHouseDetails.DataBodyRange.Rows
Set rowsB = tblSalePriceSchedule.DataBodyRange.Rows
'Find the product type, look for the relevant price and insert it into the appropriate house details column
For i = 1 To rowsA.Count
strProductType = rowsA.Cells(i, 5).Value 'The fifth columns is the product type
dSaleDate = rowsA.Cells(i, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
dblSalePrice = -999
For j = 1 To rowsB.Count
If rowsB.Cells(j, 3) = strProductType And rowsB.Cells(j, 1) <= dSaleDate And rowsB.Cells(j, 2) >= dSaleDate Then
rowsA.Cells(i, 6) = rowsB.Cells(j, 4)
End If
Next
Next
如果您正在寻找一个高性能的解决方案,我会使用数组中的值:
Dim dataA(), dataB(), i&, j&, strProductType$, dSaleDate, dblSalePrice
' Get all the values in an array
dataA = Sheets("House details").ListObjects("House_details").DataBodyRange.Value
dataB = Sheets("Sale price schedule").ListObjects("Sale_price_schedule").DataBodyRange.Value
For i = 0 To UBound(dataA)
strProductType = dataA(i, 4) 'The fifth columns is the product type
dSaleDate = dataA(i, 2) 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
dblSalePrice = -999
For j = 0 To UBound(dataB)
If dataB(j, 2) = strProductType And dataB(j, 0) <= dSaleDate And dataB(j, 1) >= dSaleDate Then
dataA(i, 5) = dataB(j, 3)
End If
Next
Next
' Copy the values back to the sheet
Sheets("House details").ListObjects("House_details").DataBodyRange.Value = dataA
您在 .DataBodyRange property of the House_details ListObject. All references used inside that With ... End With statement 内工作需要以句号开头(又名 句号 或 .
)以便传递给父级参考。
Rows.Count
需要.Rows.Count
,Cells(iCount2, 3)
需要.Cells(iCount2, 3)
,等等
Range.Parent property shifts to the Sale_price_schedule table once you enter the nested With ... End With and these Range.Cells and Range.Rows 属性需要相同的语法才能将其父引用调整为 Sale_price_schedule table。
所有 Cells(...)
和 Rows.Count
调用都默认为 ActiveSheet property,没有序号。
Set tblHouseDetails = Sheets("House details").ListObjects("House_details")
Set tblSalePriceSchedule = Sheets("Sale price schedule").ListObjects("Sale_price_schedule")
'Find the product type, look for the relevant price and insert it into the appropriate house details column
With tblHouseDetails.DataBodyRange
For iCount = 2 To .Rows.Count
iTemp = .Rows.Count
strProductType = .Cells(iCount, 5).Value 'The fifth columns is the product type
dSaleDate = .Cells(iCount, 3).Value 'The third column is the sale date
'Find the correct sale price in the SalePriceSchedule
'----------------------------
dblSalePrice = -999
With tblSalePriceSchedule.DataBodyRange
iTemp = .Rows.Count
For iCount2 = 2 To .Rows.Count
If .Cells(iCount2, 3) = strProductType And .Cells(iCount2, 1) <= dSaleDate And .Cells(iCount2, 2) >= dSaleDate Then
dblSalePrice = .Cells(iCount2, 4)
End If
Next iCount2
End With
'------------------------------
.Cells(iCount, 6) = dblSalePrice
Next iCount
End With
在相关说明中,检索 Range.Row property will retrieve the actual row on the worksheet and must be adjusted by the row of the .HeaderRowRange property 到 return 行在 table.
中的位置