Search code examples
excelvba

vba find if a user input value exist in excel sheet gets error if not found twice but ok when not found once


I have the below macro but the problem is I need to input many records and when value not found it gives the msgbox which is fine but if again a value not found the whole thing collapse and stop working. Why first time value not found the program continues normally but if again a value not found it collapses?

Sub Macro4()

On Error GoTo errmsg

errmsg:

MsgBox "not found"

Do While MsgBox("Do you have after sales applications?", vbYesNo) = vbYes

    Cells.Find(What:=InputBox("Please input Full Account Number"), After:=ActiveCell, LookIn:=xlFormulas _

        , LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _

        MatchCase:=False, SearchFormat:=False).Select

    Selection.EntireRow.Select

    Selection.Copy

    Sheets("Sheet1").Select

    Range("A1").Insert 

    Sheets("ELEC").Select

    ActiveCell.EntireRow.Delete Shift:=xlUp

    Application.CutCopyMode = False

    On Error GoTo errmsg

Loop


        Sheets("Sheet1").Select

        Columns("R:R").Select

        Selection.Replace What:="N", Replacement:="R", LookAt:= _

        xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _

        ReplaceFormat:=False

     finalRow = Cells(Rows.Count, "B").End(xlUp).Row

    Range(Cells(1, "B"), Cells(finalRow, "B")).EntireRow.Select

    Selection.Cut

    Sheets("ELEC").Select

    Rows("7:7").Insert

End Sub

Solution

  • Improving Code: Message Box and Input Box in Do...Loop

    • Usually, account numbers are in a single column so you should restrict the find to it with e.g. sws.Columns("A").Find(...). Also, the significance of row 7 is unclear so maybe you need sws.Range("A2:A6").Find(...). Be careful though, if you modify as suggested, ActiveCell will not work and you should use the last cell of the suggested range as the After argument's parameter.
    • I think ActiveCell is a bad idea anyway because it is the only reason why I had to add the first two If statements.
    • The source-destination logic is kind of compromised since in the 'bottom part' of the code you're moving from destination to source.
    Sub MoveAccounts()
        
        Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
        If Not wb Is ActiveWorkbook Then wb.Activate
    
        Dim sws As Worksheet: Set sws = wb.Sheets("ELEC")
        If Not sws Is ActiveSheet Then sws.Select
        
        Dim dws As Worksheet: Set dws = wb.Sheets("Sheet1")
        
        Dim scell As Range, AccountNumber As String, HasAccountMoved As Boolean
        
        Do While MsgBox("Do you have after sales applications?", _
                vbYesNo + vbQuestion) = vbYes
            
            AccountNumber = InputBox("Please input Full Account Number")
            
            Set scell = sws.Cells.Find(What:=AccountNumber, _
                After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlWhole, _
                SearchOrder:=xlByRows)
            
            If scell Is Nothing Then
                MsgBox "Account number not found!", vbExclamation
            Else
                With scell.EntireRow
                    .Copy
                    dws.Range("A1").Insert
                    .EntireRow.Delete Shift:=xlShiftUp
                    Application.CutCopyMode = False
                End With
                HasAccountMoved = True
            End If
        
        Loop
    
        If Not HasAccountMoved Then Exit Sub
        
        dws.Columns("R").Replace What:="N", Replacement:="R", LookAt:=xlPart, _
            SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
            ReplaceFormat:=False
        
        Dim drg As Range, dLastRow As Long
        
        dLastRow = dws.Cells(dws.Rows.Count, "B").End(xlUp).Row
        Set drg = dws.Range(dws.Cells(1, "B"), dws.Cells(dLastRow, "B")).EntireRow
    
        drg.Cut
        sws.Rows(7).Insert
    
    End Sub