2

I have this form to enter new data to a table. I would like to warn the user when he is entering an invoice number that already exist. Here is the code I have but its not working:

Private Sub CommandButton1_Click()
Dim L As Long
Dim Code As String
Dim TextBox2 As Long
Dim valFormula As String
valFormula = "=COUNTIFS($F12:$F1702,F1702,$D12:$D1702,D1702)=1"

If MsgBox("Confirm?", vbYesNo, "Confirming new invoice") = vbYes Then
    With Worksheets("FACTURE")
        L = Sheets("FACTURE").Range("D65535").End(xlUp).Row + 1 'Pour placer     le nouvel enregistrement _ la premi_re ligne de tableau non vide
    End With
    With Me
        Range("D" & L).Validation
            .Add Type:=xlValidateCustom, _
            AlertStyle:=xlValidAlertWarning, _
            Formula1:="=COUNTIFS($F12:$F1702,F1702,$D12:$D1702,D1702)=1"
            .InputTitle = ""
            .ErrorTitle = "Duplicate alert"
            .InputMessage = ""
            .ErrorMessage = "This invoice number already exist. Continue?"

        Range("B" & L).Value = .ComboBox2 & .ComboBox3
        Range("C" & L).Value = (Now)
        Range("D" & L).Value = .TextBox2
        Range("E" & L).Value = .TextBox3
        Range("F" & L).Value = .TextBox4
        Range("G" & L).Value = .TextBox5
        Range("K" & L).Value = .ComboBox1
        Range("L" & L).Value = .ComboBox2
        Range("M" & L).Value = .ComboBox3
        Range("N" & L).Value = .TextBox9
        Range("O" & L).Value = .TextBox10
        Range("R" & L).Value = .TextBox39
        Range("P" & L).Value = .TextBox40
        Range("C" & L).Interior.ColorIndex = 0
        If .OptionButton1 Then
            FormatCell Range("B" & L), xlThemeColorAccent3
        ElseIf .OptionButton2 Then
            FormatCell Range("B" & L), xlThemeColorAccent1
        ElseIf .OptionButton3 Then
            FormatCell Range("B" & L), xlThemeColorAccent4
        Else
            FormatCell Range("B" & L), xlThemeColorAccent2
        End If
    End With
End If
End Sub

Any advice?

1
  • 2
    Just use .Find on the range the invoice number might be in? Commented Sep 3, 2016 at 23:25

1 Answer 1

3

As Comintern suggested, use Find() method of Range object, with code like:

Set f = rngToSerachIn.Find(what:=factureNo, LookIn:=xlValues, lookat:=xlWhole)

where

  • f is a range variable where to store the range with the searched value

  • rngToSerachIn is the range where to search the value

  • factureNo is the value to search for

furthermore it seems to me your invoices will be stored in rows from 12 downwards, so it could be useful to write a generic function to get first empty cell in a given column of a given worksheet ranging from a certain row

Since it'd be a good practice to demand specific tasks to Sub/Function to improve both code readability and maintenance, you could do that for:

  • getting first empty row after last non empty one starting from a given row in a given column of a given worksheet

  • validating invoice number

  • filling worksheet ranges

  • formatting invoice cell

as follows:

Option Explicit

Private Sub CommandButton1_Click()
    Dim L As Long
    Dim factureWs As Worksheet

    If MsgBox("Confirm?", vbYesNo, "Confirming new invoice") = vbNo Then Exit Sub

    Set factureWs = Worksheets("FACTURE") '<--| set the worksheet you want to work with

    L = GetLastNonEmptyRow(factureWs, "D", 12) + 1 '<--| get passed worksheet first empty row after last non empty one in column "D" from row 12 (included)

    If L > 12 Then If Not CheckDuplicate(Me.TextBox2, factureWs.Range("D12:D" & L - 1)) Then Exit Sub '<--| exit if duplicated non accepted by the user

    FillRanges factureWs, L '<--| fill worksheet ranges with userfom controls values

    FormatInvoice factureWs.Range("B" & L) '<--| color invoice cell depending on option buttons values
End Sub

Function GetLastNonEmptyRow(ws As Worksheet, colIndex As String, firstRow As Long) As Long
    Dim lastRow As Long
    With ws
        lastRow = .Cells(.Rows.Count, colIndex).End(xlUp).row ' <--| get last non empty row in given column
        If lastRow = 1 Then If IsEmpty(.Range(colIndex & 1)) Then lastRow = 0  '<--| handle the case of an empty column
        If lastRow < firstRow Then lastRow = firstRow - 1 '<--| handle the case the last non empty row is above the first passed one
    End With
    GetLastNonEmptyRow = lastRow
End Function

Function CheckDuplicate(factureNo As String, rng As Range) As Boolean
    Dim f As Range
    Set f = rng.Find(what:=factureNo, LookIn:=xlValues, lookat:=xlWhole)
    If Not f Is Nothing Then
        CheckDuplicate = MsgBox("This invoice number already exist!" & vbCrLf & vbCrLf & "Continue?", vbExclamation + vbYesNo, "Duplicate alert") = vbYes
    Else
        CheckDuplicate = True
    End If
End Function

Sub FormatInvoice(rng As Range)
    Dim thColor As XlThemeColor

    With Me
        Select Case True
            Case .OptionButton1
                thColor = xlThemeColorAccent3
            Case .OptionButton2
                thColor = xlThemeColorAccent1
            Case .OptionButton3
                thColor = xlThemeColorAccent4
            Case Else
                thColor = xlThemeColorAccent2
        End Select
    End With
    FormatCell rng, thColor
End Sub

Sub FillRanges(ws As Worksheet, L As Long)
    With ws
        .Range("C" & L).Value = (Now)
        .Range("D" & L).Value = Me.TextBox2
        .Range("E" & L).Value = Me.TextBox3
        .Range("F" & L).Value = Me.TextBox4
        .Range("G" & L).Value = Me.TextBox5
        .Range("K" & L).Value = Me.ComboBox1
        .Range("L" & L).Value = Me.ComboBox2
        .Range("M" & L).Value = Me.ComboBox3
        .Range("N" & L).Value = Me.TextBox9
        .Range("O" & L).Value = Me.TextBox10
        .Range("R" & L).Value = Me.TextBox39
        .Range("P" & L).Value = Me.TextBox40
    End With
End Sub

you may find it useful and follow this pattern in your subsequent coding

Sign up to request clarification or add additional context in comments.

3 Comments

Can't wait to try this one! Thanks
Alright so everything is working perfectly except for the formatting of the B column. Looks like the FormatInvoice Sub is good but not applied when confirming the data entry. Any idea how I could add it to the CommandButton_Click Sub?
you must (1) step through the code by (2) placing breakpoints at its relevant statements and (3) querying Immediate Window for relevant variables value to see what's going on. (1) place the cursor in any code line of CommandButton1_Click and press F8; the code start and the first statement to be executed highlights in yellow: keep pressing F8 to jump to next statement (2) you place breakpoint by placing cursor in any line and pressing F9 (3) at any statement you can use Immediate Window (Ctrl+G) and query any variable value by typing ? variablename.variableproperty and pressing return

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.