Possible for my vba code more compact and simplified

妖精的绣舞 提交于 2021-01-29 12:09:05

问题


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

回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/60013629/possible-for-my-vba-code-more-compact-and-simplified

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!