运行时错误'424'必需对象-不确定我在这段代码中写错了什么吗?

时间:2019-09-25 14:52:21

标签: excel vba runtime-error

utm_source=404Redirect&utm_medium=404Redirect

我在Parameter Purpose Examples --------- ------- -------- utm_source Identifies which site sent the traffic. utm_source=Facebook utm_medium Identifies what type of link was used. utm_medium=cpc utm_campaign Identifies a specific product promotion. utm_campaign=new_sale utm_term Identifies search terms. utm_term=treck+shoes utm_content Identifies what was clicked to bring the user to the site. utm_content=loginlink 行上收到Sub automated_gr_lookup() Dim st As Long Dim en As Long Dim c1 As Long Dim c2 As Long Dim iRowAsset As Integer Dim table As Range Dim tmpRiskID As Variant Sheets("Geotechnical Risk Register").Select Application.ScreenUpdating = False Set assetTbl = Application.Range("M002_") 'Asset table = DES M002 Set riskTbl = Application.Range("geotechRisks") 'GRR Set compiledTbl = Application.Range("CompiledM002") 'Output for M002 For iRowRisk = 1 To riskTbl.Rows.Count 'loop through risks tmpRiskID = riskTbl.Row.Range("Ref No. ID") 'Temporary risk as it gets overridden 'if assets chainage match risk iRowRisk (4 conditions) If (en > c1 And en < c2) Or (st > c1 And en < c2) Or (st > c1 And st < c2) Or (st < c1 And en > c2) Then 'copy asset row assetTbl.Rows(iRowAsset).Copy 'paste row in compiled compiledTbl.Rows(xlEndRow).PasteSpecial xlPasteValues 'paste risk id in last column of that row compiledTbl.Cells(xlEndRow, ColumnH).Value = tmpRiskID End If Next iRowRisk End Sub ,不确定为什么吗?我目前正在尝试将其分配给表格标题。

1 个答案:

答案 0 :(得分:0)

Sheets("Geotechnical Risk Register").Select

这是问题开始的地方。该工作表在哪里?如果它在任何工作簿正处于活动状态中,那么就会出现运行时错误9“下标超出范围”,以提醒您任何工作簿正处于活动状态一定有一个同名的工作表。

如果工作表位于承载VBA代码的同一工作簿中,那么您希望“无论当前处于活动状态的工作簿”,但是ThisWorkbook-这样会更好:

ThisWorkbook.Worksheets("Geotechnical Risk Register").Select

但是,您 不需要.Select。考虑:

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Geotechnical Risk Register")

好得多:现在我们可以针对该特定工作表进行成员调用,并且我们知道我们正在针对正确的工作表进行操作。

除了,如果工作表在编译时存在于ThisWorkbook中,那么它是完全多余的。

在VBE的 Project Explorer 工具窗口(Ctrl + R)中选择工作表模块,然后调出其属性(F4)。属性列表的顶部是(Name)属性,当前可能类似于Sheet42-将其更改为更有意义的内容,例如GeotechRiskRegisterSheet。现在,您有了一个名为GeotechRiskRegisterSheet的全局对象变量(实际上是project-scope),您可以在VBA项目中的任何地方使用它来引用该特定图纸

此答案的其余部分假定您已完成此操作。如果工作表不在ThisWorkbook中,请坚持为其声明一个局部Worksheet变量,并从Worksheet集合中提取Workbook.Worksheets对象引用您要使用的工作簿

Set assetTbl = Application.Range("M002_")

这是分配给一个看起来像是局部变量的变量,但未在局部范围内的任何地方声明。 Application.Range仅比Range好一点,而且距离最明确的ActiveSheet.Range仅间接一级-但是,您又不要意味着无论ActiveSheet是什么,都可以使用它们,并且在表要做定义命名范围和命名范围 时,都可以使用{{1}属性,这将更加清晰和绝对明确:

Range

对其他两个同样适用:

Dim assetTbl As ListObject
Set assetTbl = GeotechRiskRegisterSheet.ListObjects("M002_")

继续:

Set riskTbl = Application.Range("geotechRisks") 'GRR
Set compiledTbl = Application.Range("CompiledM002") 'Output for M002

然后我们开始循环:

Dim riskTbl As ListObject
Set riskTbl = GeotechRisksSheet.ListObjects("geotechRisks")

Dim compiledTbl As ListObject
Set compiledTbl = CompiledSheet.ListObjects("CompiledM002")

如果For iRowRisk = 1 To riskTbl.Rows.Count 'loop through risks 仅是另一个riskTbl,则可以。如果RangeriskTbl,我们可以做得更简单,更快捷:

ListObject

然后我们得到您要询问的运行时错误:

Dim currentRow As ListRow
For Each currentRow In riskTbl.ListRows

这是错误424“需要对象”,因为tmpRiskID = riskTbl.Row.Range("Ref No. ID") 'Temporary risk as it gets overridden 是一个riskTbl.Row整数值:它没有Long成员,所以您不能做{{1} } 像这样。如果您要使用该Range循环来迭代普通的Range.Row.Range,那么您希望它看起来像这样:

Range

For iRowRisk是指“参考编号ID”列的硬编码列索引。不理想,是吗?与利用tmpRiskID = riskTbl.Cells(iRowRisk, 12).Value API相比:

12

如果在循环外部定义ListObject变量,则每次迭代都可以重用其值,并且只要标题标题保持“ Ref No. ID”,该列就可以位于用户想要的任何位置-而使用硬编码的列索引,如果用户插入新列,则代码会中断。

Dim refIDColumn As Long
refIDColumn = riskTbl.ListColumns("Ref No. ID").Index

tmpRiskID = currentRow.Range.Cells(ColumnIndex:=refIDColumn).Value

我希望您已经在实际代码中声明并分配了这些变量-否则此条件表达式将无法可靠地求值,因为这些标识符均没有值。考虑使用传达使用意图的有意义的名称:refIDColumn 'if assets chainage match risk iRowRisk (4 conditions) If (en > c1 And en < c2) Or (st > c1 And en < c2) Or (st > c1 And st < c2) Or (st < c1 And en > c2) Then enst对不熟悉任何人思考过程的任何人来说绝对没有任何意义编写了该代码。无论如何,请确保模块顶部在某处显示c1

c2

我不认为您实际上需要在此处使用剪贴板。再次考虑使用Option Explicit API-这应该可以工作(未经测试):

        'copy asset row
        assetTbl.Rows(iRowAsset).Copy
        'paste row in compiled
        compiledTbl.Rows(xlEndRow).PasteSpecial xlPasteValues
        'paste risk id in last column of that row
        compiledTbl.Cells(xlEndRow, ColumnH).Value = tmpRiskID

ListObject将在循环体之前声明和分配的地方:

    With compiledTbl.ListRows.Add
        .Range.Value = currentRow.Range.Value
        .Range.Cells(ColumnIndex:=compiledRiskIdColumn).Value = tmpRiskID
    End With