amein
amein

Reputation: 115

Possible for my vba code more compact and simplified

My vba code below to check on the userform textbox for any duplicate data on 3 rows. Once duplicate found, it will notified user and select entire row of the duplicate data. Its working and get job done. But, seems like the code quite long and repetitive. Is it possible to simplified and make my code more compact? Im still learning with vba code and dont know much about more advance function to get more compact code. Thank you.

Private Sub ISBNTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Dim ISBN
    Dim FoundISBN As Range
    Dim Search As String
    Dim ws As Worksheet

    Set ws = Worksheets("booklist")
    Search = ISBNTextBox.Text
    Set FoundISBN = ws.Columns(5).Find(Search, LookIn:=xlValues, Lookat:=xlWhole)
    ISBN = Application.WorksheetFunction.CountIf(ws.Range("E:E"), Me.ISBNTextBox)
    If ISBN > 0 Then
        ISBN_checker.Caption = "Duplicate" & " " & FoundISBN.Address
        FoundISBN.EntireRow.Select
    Else
        ISBN_checker.Caption = ChrW(&H2713)
    End If

End Sub
Private Sub TitleTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Dim Title
    Dim FoundTitle As Range
    Dim Search As String
    Dim ws As Worksheet

    Set ws = Worksheets("booklist")
    Search = TitleTextBox.Text
    Set FoundTitle = ws.Columns(2).Find(Search, LookIn:=xlValues, Lookat:=xlWhole)
    Title = Application.WorksheetFunction.CountIf(ws.Range("B:B"), Me.TitleTextBox)
    If Title > 0 Then
        Title_checker.Caption = "Duplicate" & " " & FoundTitle.Address
        FoundTitle.EntireRow.Select
    Else
        Title_checker.Caption = ChrW(&H2713)
    End If

End Sub

Private Sub CallNoTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Dim CallNo
    Dim FoundCallNo As Range
    Dim Search As String
    Dim ws As Worksheet

    Set ws = Worksheets("booklist")
    Search = CallNoTextBox.Text
    Set FoundCallNo = ws.Columns(6).Find(Search, LookIn:=xlValues, Lookat:=xlWhole)
    CallNo = Application.WorksheetFunction.CountIf(ws.Range("F:F"), Me.CallNoTextBox)
    If CallNo > 0 Then
        CallNo_checker.Caption = "Duplicate" & " " & FoundCallNo.Address
        FoundCallNo.EntireRow.Select
    Else
        CallNo_checker.Caption = ChrW(&H2713)
    End If

End Sub

Upvotes: 0

Views: 142

Answers (2)

Tim Williams
Tim Williams

Reputation: 166316

A lot of repetition there, with a limited number of variable parts, so refactor the common code into a separate Sub and parameterize it.

Simpler:

Private Sub ISBNTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    DupCheck ISBNTextBox.Text, 5, ISBN_checker    
End Sub

Private Sub TitleTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    DupCheck TitleTextBox.Text, 2, Title_checker    
End Sub

Private Sub CallNoTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    DupCheck CallNoTextBox.Text, 6, CallNo_checker    
End Sub

Sub DupCheck(txt, ColNo As Long, theLabel As Object)
    Dim m
    With Worksheets("booklist")
        m = Application.Match(txt, .Columns(ColNo), 0)
        If Not IsError(m) Then '<-Fixed
            theLabel.Caption = "Duplicate" & " " & .Cells(m, ColNo).Address
            .Rows(m).Select
        Else
            theLabel.Caption = ChrW(&H2713)
        End If
    End With
End Sub

Upvotes: 0

Siddharth Rout
Siddharth Rout

Reputation: 149305

Since Search = ISBNTextBox.Text, so

Set FoundISBN = ws.Columns(5).Find(Search, LookIn:=xlValues, Lookat:=xlWhole)

and

ISBN = Application.WorksheetFunction.CountIf(ws.Range("E:E"), Me.ISBNTextBox)

are being used for the same thing. You can rewrite your code as

Option Explicit

Private Sub ISBNTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    Dim FoundISBN As Range
    Dim ws As Worksheet

    Set ws = Worksheets("booklist")
    ISBN_checker.Caption = ChrW(&H2713) '<~~ Set this as default value

    Set FoundISBN = ws.Columns(5).Find(What:=ISBNTextBox.Text, LookIn:=xlValues, _
    LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False)

    '~~> Check if find returned anything
    If Not FoundISBN Is Nothing Then
        ISBN_checker.Caption = "Duplicate" & " " & FoundISBN.Address
        FoundISBN.EntireRow.Select
    End If
End Sub

Note: When using .Find remember 2 things

  1. Excel remembers .Find's last settings and hence to avoid any confusion, use all parameters of it.
  2. Always check whether .Find returned something or not before you try and use it else you will get "Run Time Error 91 - Object Variable or With block variable not set" error

Upvotes: 1

Related Questions