VBA 中的错误 "object required",引用了重复的问题

Error "object required" in VBA , referred to duplicate questions

我的目的是将任务拆分成多个组成任务,发现最重要的 one.The 宏写在 workallotment.xlsm 的 "May" sheet 中,任务在tasks.xlsx

例如:

                                   Constituents  Constituents  Important Imp
Praveen T1  T2  T3  T4  T5  T6     T1+T2+T3 =T5  T3+T5+T6 =T9     T1      T6
         4  3   1   2   8   9               
Karthik P1  P2  P3  P4          " among T1,T2,T3- T1 takes more time".its imp       
         6  3   2   2                       
Walter  c1  c2  c3  c4                      
        1   2   3   4                       
Arvind  g1  g2  g3                          
         2  1   3                           
Sreelatha   h1  h2  h3                          
            2   1   1                           

代码:

Sub workallotment()
    Dim workallotmentWB, tasksWB As Workbook
    Dim waSheet As Worksheet
    Dim str(9) As String
    Dim splitArray() As String, S(10) As String
    Dim col_new As Integer

    Dim wa_nameRng As Range

    Dim r As Integer, max As Integer, imps As String
    Dim wa_nameRow, wa_firstRow, wa_lastRow As Integer  'work allotment rows
    Dim t_firstRow, t_lastrow As Integer                'task rows

    Dim curTaskCol As Integer   'current task column
    Dim wa_tmpcol As Integer    'work allotment, temp column


        Set workallotmentWB = ThisWorkbook
        Set tasksWB = Workbooks.Open("E:/tasks.xlsx")

        'notes on data structure:
        '- tasks workbook:
            'first name starts in A1 of "Sheet1"
        '- workallotment workbook:
            'first name starts in A2 of Sheet named "workallotment"
            'tasks are to be written starting in B2
            'in Row 1 are headers (number of days)

        t_firstRow = 1
        wa_firstRow = 2
        wa_nameRow = 0

        Set waSheet = workallotmentWB.Worksheets("May")             ' in this file - workallotment.xlsm

        With tasksWB.Worksheets("May")                              ' in tasks.xlsx which is attached

            'finding the last rows
            t_lastrow = .Range("A1000000").End(xlUp).row + 1
            wa_lastRow = waSheet.Range("A1000000").End(xlUp).row

            'goes through all the names in tasks_Sheet1
            For r = t_firstRow To t_lastrow Step 2


                Set wa_nameRng = waSheet.Range("A:A").find(.Range("A" & r).Value, _
                LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False)

                If Not wa_nameRng Is Nothing Then

                    wa_nameRow = wa_nameRng.row

                    curTaskCol = 2
                    wa_tmpcol = 2

                    Do While Not IsEmpty(.Cells(r, curTaskCol).Value)

                        For C = 1 To .Cells(r + 1, curTaskCol).Value
                            waSheet.Cells(wa_nameRow, wa_tmpcol).Value = .Cells(r, curTaskCol).Value
                            wa_tmpcol = wa_tmpcol + 1
                        Next C

                        curTaskCol = curTaskCol + 1

                    Loop

                End If

            Next r

        End With

        MsgBox ("done")



    For r = t_firstRow To t_lastrow Step 2                ' loop to find importance

    col = 2                                               'setting to initial col
    curTaskCol = 17    ' position input - constituent jobs at 17th col in tasks.xls

    Do While Not IsEmpty(tasksWB.Worksheets("May").Cells(r, curTaskCol).Value)

     str(curTaskCol - 16) = tasksWB.Worksheets("May").Cells(r, curTaskCol).Value
            ' reading input to first array of string element

    substr = Left(str(curTaskCol - 16), Application.WorksheetFunction.find("=", str(curTaskCol - 16)) - 1)         ' if T1+T2=T3 it'll look before "=" symbol
    MsgBox (substr)
    splitArray() = Split(substr, "+")  ' if T1+T2 it will be split as T1 & T2


    For i = LBound(splitArray) To UBound(splitArray)

        S(i + 1) = splitArray(i)          ' assigning split elements to string array

        Next i
    For i = LBound(splitArray) To UBound(splitArray)
        col_new = 2                   ' checking from 2nd column


        Do While Not IsEmpty(tasksWB.Worksheets("May").Cells(r, col_new).Value)
         If (S(i + 1) = tasksWB.Worksheets("May").Cells(r, col_new).Value) Then                 'initialising max and imps
          imps = S(i + 1)       ' most important job

          max = tasksWB.Worksheets("May").Cells(r + 1, col_new).Value

        End If                       ' maximum time taken for task
        col_new = col_new + 1
        Loop

        For j = LBound(splitArray) To UBound(splitArray)

          col_new = findcol(S(j + 1), r, tasksWB)


          If (max < tasksWB.Worksheets("May").Cells(r + 1, col_new).Value) Then
          max = tasksWB.Worksheets("May").Cells(r + 1, col_new).Value
          imps = tasksWB.Worksheets("May").Cells(r, col_new).Value

        End If
        Next j

        Next i
    tasksWB.Worksheets("May").Cells(r, curTaskCol + 6).Value = imps
                                ' assign most IMPORTANT task on 6th column from current column
    curTaskCol = curTaskCol + 1               ' RUNTIME ERROR 1004

     Loop


     Next r


End Sub

Public Function findcol(S As String, row As Integer, theWB As Workbook) As Integer
    Dim col As Integer, addr As Integer
    col = 2                  ' checking from column 2
    'Set tasksWB = Workbooks.Open("E:/tasks.xlsx")


    Do While Not IsEmpty(theWB.Worksheets("May").Cells(row, col).Value)

         If (StrComp(Trim(S), Trim(theWB.Worksheets("May").Cells(row, col).Value)) = 0) Then
           addr = col                         ' if task string is found in column
        End If
        col = col + 1                            ' return column found
        Loop
        findcol = addr
End Function

tasksWBfindcol 函数中无法识别,因为它在主进程中被声明为 Private (=Dim)。

在模块的顶部声明它,它就会起作用! ;)

克里希南,

在您的主程序 workallotment 中声明了变量 tasksWB

在您的方法中 'findcol' 然后您引用 tasksWB。看起来您已将这段代码从主过程中提取出来。 tasksWB 仅在 workallot 范围内,因此您需要提供 findcol 这个对象,这样它也会在它的范围内。

我建议您将 tasksWB 作为第三个参数传递给方法。

您的方法将如下所示。

编辑您对为什么 findcol 没有 return 的评论。 Exit Function 将确保在设置 return 值后立即退出该方法。如果没有这个,你最终会再次要求正确的任务名称。

Public Function findcol(S As String, row As Integer, theWB as Workbook) As Integer
    col = 2                  ' checking from column 2
    Do While Not IsEmpty(theWB.Worksheets("May").Cells(row, col).Value)
        If (S = theWB.Worksheets("May").Cells(row, col).Value) Then                   
           findcol = col                         ' if task string is found in column                      
           Exit Function
        End If
        'MsgBox ("Enter correct task names")  Not sure why this is here.
        col = col + 1                            ' return column found
    Loop
End Function

你会用

来称呼它
col_new = findcol(S(j + 1), r, tasksWB)    ' ERROR line function to find column of task string

这将确保您不会 "leak" 您的变量定义进入全局范围,并且您还确保您的方法不依赖于外部全局变量。

编辑 3: 你的findcol还是错了。

Public Function findcol(S As String, row As Integer, theWB As Workbook) As Integer
    Dim col As Integer
    '******* you don't need this because you can exit early
    'Dim addr As Integer
    col = 2                  ' checking from column 2

    '*****   THIS LINE NEEDS TO BE REMOVED because you are using theWB being passed in *****
    'Set tasksWB = Workbooks.Open("E:/tasks.xlsx")


    Do While Not IsEmpty(theWB.Worksheets("May").Cells(row, col).Value)

        '****** this line must use theWB
        'If (StrComp(Trim(S), Trim(tasksWB.Worksheets("May").Cells(row, col).Value)) = 0) Then
        If (StrComp(Trim(S), Trim(theWB.Worksheets("May").Cells(row, col).Value)) = 0) Then

            '*************  you can exit early once you've found what you need.
            'addr = col                         ' if task string is found in column
            findcol = col
            exit function            
        End If
        col = col + 1                            ' return column found
    Loop
    ' You can exit early so don't need this.
    ' findcol = addr
End Function

你可能应该在调用函数时检查值是否 returned 0,例如

new_col = findcol( .... )
if new_col = 0 then
   msgbox "couldn't find the column with that str" & S(j + 1)
end if