Excel VBA - 匹配函数在循环中给出错误

时间:2017-11-02 00:51:40

标签: excel vba excel-vba match

我是一名业余的excel vba编码器。我试图找出为什么匹配函数给出错误" 1004,无法获得工作表函数的匹配属性"当它在循环中第三次运行时对我来说。

我的代码是:

Sub com_emp()
'Defining variables
Application.Run "set_var"
c_row_now = db_r_datastart
row_now = ce_r_datastart

Do While cy.Cells(c_row_now, db_c_ident) <> ""
On Error GoTo skip_emp 'In case employee is not found in historical, error redirect

    h_row_now = Application.WorksheetFunction.Match(cy.Cells(c_row_now, db_c_ident), hy.Columns(db_c_ident), 0)

    If h_row_now > 0 And hy.Cells(h_row_now, db_c_englev) <> "" Then 'If person is found and also has engagement level

        ce.Cells(row_now, ce_c_ident) = cy.Cells(c_row_now, db_c_ident)
        ce.Cells(row_now, ce_c_his_englev) = hy.Cells(h_row_now, db_c_englev)
        ce.Cells(row_now, ce_c_his_eng) = hy.Cells(h_row_now, db_c_eng)
        ce.Cells(row_now, ce_c_cur_englev) = cy.Cells(c_row_now, db_c_englev)
        ce.Cells(row_now, ce_c_cur_eng) = cy.Cells(c_row_now, db_c_eng)
        ce.Cells(row_now, ce_c_lev1) = cy.Cells(c_row_now, db_c_lev1)
        ce.Cells(row_now, ce_c_lev2) = cy.Cells(c_row_now, db_c_lev2)
        ce.Cells(row_now, ce_c_lev3) = cy.Cells(c_row_now, db_c_lev3)
        ce.Cells(row_now, ce_c_lev4) = cy.Cells(c_row_now, db_c_lev4)
        ce.Cells(row_now, ce_c_lev5) = cy.Cells(c_row_now, db_c_lev5)

        row_now = row_now + 1
    End If


skip_emp:
c_row_now = c_row_now + 1
Loop

End Sub

我正在调用的函数设置了一些其他宏使用的全局变量。

'''''DECLARATIONS'''''
'Current and Historical Year Sheet
Public db_c_ident As Integer
Public db_c_say1 As Integer
Public db_c_say2 As Integer
Public db_c_stay1 As Integer
Public db_c_stay2 As Integer
Public db_c_strive1 As Integer
Public db_c_strive2 As Integer
Public db_c_lev1 As Integer
Public db_c_lev2 As Integer
Public db_c_lev3 As Integer
Public db_c_lev4 As Integer
Public db_c_lev5 As Integer
Public db_c_avg As Integer
Public db_c_englev As Integer
Public db_c_eng As Integer

'Common Employees
Public ce_r_datastart As Integer
Public ce_c_ident As Integer
Public ce_c_his_englev As Integer
Public ce_c_his_eng As Integer
Public ce_c_cur_englev As Integer
Public ce_c_cur_eng As Integer
Public ce_c_lev1 As Integer
Public ce_c_lev2 As Integer
Public ce_c_lev3 As Integer
Public ce_c_lev4 As Integer
Public ce_c_lev5 As Integer

'Workbook, Sheets and other stuff
Public cy As Worksheet
Public hy As Worksheet
Public ce As Worksheet
Public bck As Worksheet



'Variables
Public db_r_datastart As Long
Public row_now As Long
Public h_row_now As Long
Public c_row_now As Long

''''Global Value Pick'''''
Private Sub set_var()

'Workbook, Sheets and other stuff
Set cy = ThisWorkbook.Worksheets("Current Year")
Set hy = ThisWorkbook.Worksheets("Historical Year")
Set ce = ThisWorkbook.Worksheets("Common")
Set bck = ThisWorkbook.Worksheets("Backend")

'Current and Historical Year Sheet
db_r_datastart = bck.Cells(4, 3)
db_c_ident = bck.Cells(5, 3)
db_c_say1 = bck.Cells(6, 3)
db_c_say2 = bck.Cells(7, 3)
db_c_stay1 = bck.Cells(8, 3)
db_c_stay2 = bck.Cells(9, 3)
db_c_strive1 = bck.Cells(10, 3)
db_c_strive2 = bck.Cells(11, 3)
db_c_lev1 = bck.Cells(12, 3)
db_c_lev2 = bck.Cells(13, 3)
db_c_lev3 = bck.Cells(14, 3)
db_c_lev4 = bck.Cells(15, 3)
db_c_lev5 = bck.Cells(16, 3)
db_c_avg = bck.Cells(17, 3)
db_c_englev = bck.Cells(18, 3)
db_c_eng = bck.Cells(19, 3)

'Common Employees
ce_r_datastart = bck.Cells(31, 3)
ce_c_ident = bck.Cells(32, 3)
ce_c_his_englev = bck.Cells(33, 3)
ce_c_his_eng = bck.Cells(34, 3)
ce_c_cur_englev = bck.Cells(35, 3)
ce_c_cur_eng = bck.Cells(36, 3)
ce_c_lev1 = bck.Cells(37, 3)
ce_c_lev2 = bck.Cells(38, 3)
ce_c_lev3 = bck.Cells(39, 3)
ce_c_lev4 = bck.Cells(40, 3)
ce_c_lev5 = bck.Cells(41, 3)


End Sub

我知道我的代码可能不是最有效的,因为我只是在学习,所以任何建议都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

如果您要使用On Error语句,则需要确保正确处理错误。代码应该类似于:

Sub com_emp()
    '...

    Do While cy.Cells(c_row_now, db_c_ident) <> ""
        On Error GoTo myErrHandler 'In case employee is not found in historical, error redirect

        h_row_now = Application.WorksheetFunction.Match(cy.Cells(c_row_now, db_c_ident), hy.Columns(db_c_ident), 0)
        '...

skip_emp:
        c_row_now = c_row_now + 1
    Loop
    Exit Sub

myErrHandler:
    Resume skip_emp ' Finish error handling mode, resume normal mode
End Sub

但是,如果可以的话,最好自己处理错误:

Sub com_emp()
    Dim h_row_now As Variant ' to allow it to accept an error value
                             ' Note: This declaration will "shadow" the public-scoped one
                             ' but it looks like you are just using it here as a
                             ' temporary variable anyway
    'Defining variables
    'Application.Run "set_var"  ' Shouldn't need to "Run" the other sub.
    set_var                     ' Just invoke it.
    c_row_now = db_r_datastart
    row_now = ce_r_datastart

    Do While cy.Cells(c_row_now, db_c_ident) <> ""

        h_row_now = Application.Match(cy.Cells(c_row_now, db_c_ident), hy.Columns(db_c_ident), 0)
        If Not IsError(h_row_now) Then ' only process if a match was found

            If hy.Cells(h_row_now, db_c_englev) <> "" Then 'If person is found and also has engagement level

                ce.Cells(row_now, ce_c_ident) = cy.Cells(c_row_now, db_c_ident)
                ce.Cells(row_now, ce_c_his_englev) = hy.Cells(h_row_now, db_c_englev)
                ce.Cells(row_now, ce_c_his_eng) = hy.Cells(h_row_now, db_c_eng)
                ce.Cells(row_now, ce_c_cur_englev) = cy.Cells(c_row_now, db_c_englev)
                ce.Cells(row_now, ce_c_cur_eng) = cy.Cells(c_row_now, db_c_eng)
                ce.Cells(row_now, ce_c_lev1) = cy.Cells(c_row_now, db_c_lev1)
                ce.Cells(row_now, ce_c_lev2) = cy.Cells(c_row_now, db_c_lev2)
                ce.Cells(row_now, ce_c_lev3) = cy.Cells(c_row_now, db_c_lev3)
                ce.Cells(row_now, ce_c_lev4) = cy.Cells(c_row_now, db_c_lev4)
                ce.Cells(row_now, ce_c_lev5) = cy.Cells(c_row_now, db_c_lev5)

                row_now = row_now + 1
            End If
        End If
        c_row_now = c_row_now + 1
    Loop

End Sub