VBA Find not working

2019-08-03 17:22发布

问题:

I have a workbook containing a list of all invoices from all branches, let's call it "Everything", and basically I need to search if the invoices are found in another file containing each branch's invoices,. It's actually on file for each branch, and each file is divided with sheets by month, and I need to check in every sheet and then insert a value in a cell. Let's call this one "0001" and so on for each branch.

The "everything" file contains basically one column with the branch number, one with the invoice number, one with the issuer code and one saying if it was found on the branches files. The branches files contains the same except the branch number, and the last column says if the invoice is on the "Everything" file or not. There are cases where an invoice is on the branch file and is not on the "everything file" and also cases where it is on the everything file and is not on the branches file.

What I tried to do was insert a loop in VBA so it would go automatically invoice after invoice in the everything file and open the specific branch file, then search for the invoice number in each sheet. I would also need to check if the issuer is the same, but first I tried this code and when it searched for the value it returned the wrong cell! Here is the code:

Dim sh As Worksheet 
Dim iLoop As Integer 
For iLoop = 7 To 1719 

 ' this is where the invoices are in an excel sheet

iloopoffset = iLoop - 6 

 ' as you see above, the list of invoices starts at line 7, so I used this to offset

If Range("K6").Offset(iloopoffset).Value = "No" Then 

     ' Column K is the one saying if the invoice was found or not in the branches file

    Set searchedvalue = Range("B6").Offset(iloopoffset, 0) 

     ' I used this so i could use the value in the .find formula

    MsgBox (searchedvalue.Value) 
    Workbooks.Open ("C:\Users\xxxxxx\Documents\xxxxxx\XML " + Range("D6").Offset(iloopoffset).Value) 
    For Each sh In Worksheets 
        If ActiveSheet.Name = "062015" Or "052015" Or "042015" Or "032015" Or "022015" Or "012015" Or "122014" Or "112014" Then 

             ' I needed to do this because on the sheets with the names above, the searched value will be in another column. sheets before 112014 are different.

            Set NFE = Worksheets(sh.Name).Range("B:B").Find(Range("B6").Offset(iloopoffset, 0).Value, lookat:=xlPart) 
        Else 
            Set NFE = Worksheets(sh.Name).Range("A:A").Find(Range("B6").Offset(iloopoffset, 0).Value, lookat:=xlPart) 
        End If 


        If Not NFE Is Nothing Then 
            MsgBox ("Found on sheet " + ActiveSheet.Name + " " + NFE.Address) 
            Range(NFE.Address).Offset(, 12).Value = "YES" 

             ' yes for found

            ActiveWorkbook.Save 
            ActiveWindow.Close 
        End If 
    Next sh 
    ActiveWorkbook.Save 
    ActiveWindow.Close 
End If 
Next iLoop 
End Sub 

What is going on? I am a true noob in VBA, but i didn't find anything wrong with this code... can you help me?

回答1:

Untested:

Sub test()

    Const FILE_ROOT As String = "C:\Users\xxxxxx\Documents\xxxxxx\XML "
    Dim shtAll As Worksheet, rw As Range, searchedvalue
    Dim sh As Worksheet, wb As Workbook
    Dim iLoop As Long, colSrch As Long, NFE As Range
    Dim arrSheets

    Set shtAll = ActiveWorkbook.Sheets("Everything") 'adjust to suit...

    'sheets to watch out for....
    arrSheets = Array("062015", "052015", "042015", "032015", "022015", _
                      "012015", "122014", "112014")

    For iLoop = 7 To 1719

        Set rw = shtAll.Rows(iLoop)

        'if not found...
        If rw.Cells(1, "K").Value = "No" Then

            searchedvalue = rw.Cells(1, "B").Value

            Set wb = Workbooks.Open(FILE_ROOT & rw.Cells(1, "D").Value)

            For Each sh In wb.Worksheets

                'which column to search in? check if sheet name is in arrSheets
                colSrch = IIf(IsError(Application.Match(sh.Name, arrSheets, 0)), 1, 2)

                Set NFE = sh.Columns(colSrch).Find(searchedvalue, lookat:=xlPart)

                If Not NFE Is Nothing Then
                    MsgBox ("Found on sheet " + ActiveSheet.Name + " " + NFE.Address)
                    NFE.Offset(, 12).Value = "YES"
                    wb.Save
                    Exit For
                End If
            Next sh

            wb.Close savechanges:=False
        End If

    Next iLoop
End Sub

EDIT

If Not NFE Is Nothing And sh.Range(NFE).Offset(, 8) = cnpj Then

A couple of problem I see here:

  1. NFE is already a Range, so you can just do NFE.Offset(,8)

  2. VBA will always evaluate both parts of an And, even if the first part is False, so in cases where NFE is Nothing the second part will cause a run-time error (since you can't Offset from Nothing...). To handle this you need two distinct If blocks:

    If Not NFE Is Nothing Then
         If NFE.Offset(, 8) = cnpj Then
            'do something
         End If
    End If
    

Should do it.