1
votes

I'm writing a sub in Excel VBA, and it keeps giving me a 'Type Mismatch' error message when trying to assign the result of a .Find() to a Range variable. I feel pretty confident that my types are appropriate, so perhaps there's a syntax error somewhere?

Help would be GREATLY appreciated: (Line preceded by asterisks is where error is thrown)

Sub totalTiger(fCode As String, project As String, ttls() As Double)

    'Set shorcuts to Worksheets
    Dim this As Workbook:   Set this = ThisWorkbook
    Dim proj As Worksheet:  Set proj = this.Worksheets(project)

    'Dim req variables
    Dim tRng As Range:  Set tRng = proj.Range("A:A").Find(What:="Program Description")   'Establish where Staff data ends and Tiger data begins
    ***Dim rng As Range:   Set rng = proj.Range("C:C").Find(What:=fCode, After:=tRng)   'First fCode entry***

    'For each fCode entry BEFORE the Tiger data, sum the assignments by month
    Do While Not rng Is Nothing And rng.row > tRng.row

        'For each month
        For col = 4 To 15

            'Add this month's assignment to our running total
            ttls(col - 4) = ttls(col - 4) + CDbl(proj.Cells(rng.row, col).Value)

        Next

        'Update the rng reference
        Set rng = proj.Range("C:C").Find(What:=fCode, After:=rng)

    Loop

End Sub
3

3 Answers

4
votes

I think the problem is in "After:=tRng": it may be out of the range of the "find"

Dim rng As Range:   Set rng = proj.Range("C:C").Find(What:=fCode, After:=tRng)

Try removing "After:=tRng" and, if it works after removing, then try to insert a correct range.

Dim rng As Range:   Set rng = proj.Range("C:C").Find(What:=fCode)

I'm not sure that's what you need, but you can try:

Dim rng:    Set rng = proj.Range("C:C").Find(What:=fCode, After:=proj.Range("C" & tRng.Row))

It finds the first 'fCode' starting by the row where was found "Program Description"

1
votes

If you are scratching your head because all logical explanations (such as those above) do not fit, it may be CORRUPTION. I have a live workbook example where, as absurd as it looks, a sheet (with nothing on it; hitting control end lands on A1) reproducibly shows ?activesheet.usedrange.address giving "$B$1:$A$1" and ?activesheet.usedrange.count gives 0.

Thus a most rigorous coding defense should test, BEFORE doing the find,

If Not Intersect(tRng, proj.Range("A:A")) Is Nothing

for the example above, and before any general range expression for {expression}.find,

If Not Intersect(tRng, {expression}) Is Nothing

Your "Else" could drill into the issue, e.g.

msgbox tRng.address & "/" & {expression}.address

The If statement would prevent the Type Mismatch error, not only if you "illegally" or improperly set an "After:" that is not in the search range, but also for at least some cases of corrupt workbooks such as I have encountered IRL. Corrupt workbooks are scary, brutally dangerous, but Microsoft won't address the problem, so corruption is going to happen; testing such as above would at least serve to sound a potential corruption alarm (if applicable), as well as serve the basic function of simply identifying if you had an (After and {expression}) combination that is not permitted.

0
votes

It is possible that tRng is set to nothing, so the problem is not with the returned value of find, but rather with the parameter you give it.