根据用户输入的数据进行验证

时间:2016-10-01 03:01:18

标签: excel forms vba validation vlookup

我正在尝试为实验室结果的数据输入创建表单,该表单根据所测试产品的规格验证答案。用户输入以下信息:产品代码和SG结果等

我的源数据是一个包含4列的表, 产品代码,说明,SG低,SG高

SOURCE

Source data

当用户输入产品代码和SG时,我希望它根据该产品允许的特定范围(来自源数据)进行验证,并有一个对话框要求用户重新考虑输入的结果(如果超出范围)。

很容易在结果表中标记条件格式,但我不希望我的用户有权访问它。

结果

Results with out of spec flag

我需要参考单独的Range VLOOKUP来返回规格。

表格 the user entry form

提前致谢!

(更新)

Private Sub CommandButton1_Click()
Dim i As Integer
i = 2
While ThisWorkbook.Worksheets("Sheet2").Range("A" & i).Value <> ""
i = i + 1
Wend

Dim losg, loph, hisg, hiph As Double
losg = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 3, False)
hisg = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 4, False)
loph = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 5, False)
hiph = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 6, False)


If SGresult.Text < losg Then
MsgBox "SG result " & SGresult.Text & " too low"
ElseIf SGresult.Text > hisg Then
MsgBox "SG result " & SGresult.Text & " too high"
Else: MsgBox "SG result " & SGresult.Text & " just right"
End If
If pHresult.Text < loph Then
MsgBox "ph result " & pHresult.Text & " too low"
ElseIf pHresult.Text > hiph Then
MsgBox "ph result " & pHresult.Text & " too high"
Else: MsgBox "ph result " & phresult.Text & " just right"
End If

ThisWorkbook.Worksheets("Sheet2").Range("A" & i).Value = ProdCode.Value 'Enter Code in Column A
ThisWorkbook.Worksheets("Sheet2").Range("C" & i).Value = BNenter.Value 'Enter BN in Column C
ThisWorkbook.Worksheets("Sheet2").Range("D" & i).Value = DOMenter.Value 'Enter DOM in Column D
ThisWorkbook.Worksheets("Sheet2").Range("E" & i).Value = SGresult.Value 'Enter SG result in Column E
ThisWorkbook.Worksheets("Sheet2").Range("F" & i).Value = pHresult.Value 'Enter pH result in Column F
ThisWorkbook.Worksheets("Sheet2").Range("K" & i).Value = BatcherID.Value 'Enter Batcher ID in Column K

End Sub

2 个答案:

答案 0 :(得分:1)

将产品保存在&#34; K&#34;列中栏目&#34; L&#34;中各个产品的有效结果。下面的代码将为您提供所需的输出

Dim result, prod As String
Dim rng As Range

result = Val(resultText.Value)
prod = prodText.Value

ActiveSheet.Activate
On Error GoTo step:
Set rng = Range("K:K").Find(What:=prod, LookIn:=xlValues, LookAt:=xlWhole)

If rng.Offset(0, 1).Value <> result Then

    MsgBox "The result entered is out of valid range!"

End If

Exit Sub

step:
MsgBox "Invalid Product"
Exit Sub

答案 1 :(得分:0)

在OP澄清&#34;形式&#34;之后

编辑是一个&#34; UserFom&#34;

您可能希望在他/她编辑/退出任何控件时检查用户输入,而不是等待CommandButton1_Click事件并一起检查

这样的&#34;模块化&#34;方法应该使代码更容易控制和维护

例如,TextBox Exit事件可用于检查用户输入,因为他/她离开它并让他/她在输入错误时返回< / p>

此外

  • 自&#34;产品代码&#34;必须在&#34; Source&#34;中列出的那些之间进行选择。工作表栏&#34; A&#34;

    您可能希望使用ComboBox控件并让用户从列表中选择一个

  • 因为&#34;产品名称&#34;必须是与所选&#34;产品代码&#34;

    相对应的

    您可能希望使用Label控件,并让用户只需外观,其名称与他刚刚选择的产品代码相对应

遵循以上内容并假设&#34; ProductNameLbl&#34;作为标签名称,您的userform代码可能如下所示:

Option Explicit

Private Sub UserForm_Initialize()
    Me.ProdCodeCB.List = GetSourceData(1) '<--| fill Product Name combobox list with "Source" worksheet column 1 data
End Sub


Private Sub ProdCodeCB_Change() '<--| fires when the user change the combobox selection
    Me.ProdNameLbl.Caption = Worksheets("Source").Cells(Me.ProdCodeCB.ListIndex + 2, 2) '<--| update Product Name label with the name corresponding to the chosen Product Code
End Sub


Private Sub SGresultTB_Exit(ByVal Cancel As MSForms.ReturnBoolean) '<--| fires upon exiting the SGresult textbox
    Dim msgErr As String

    With Me '<--| reference the Userform
        If .ProdCodeCB.ListIndex <> -1 Then '<--| if a valid selection has been made in 'ProductCode' combobox
            If Not IsValueInRange(.SGresultTB, GetProdCodeRange(.ProdCodeCB.ListIndex + 1), msgErr) Then '<-- if value out of range then...
                With .SGresultTB
                    MsgBox "SG value " & .Value & msgErr _
                        & vbCrLf & vbCrLf & "Please reconsider the value you input in 'SG' texbox"
                    Cancel = True
                    .SetFocus '<--| get the user back to the textbox
                    ' following two lines select the textbox text so that the user can delete it
                    .SelStart = 0
                    .SelLength = Len(.Text)
                End With
            End If
        End If
    End With
End Sub

'-------------------------------------------------
' helper functions
'---------------------------
Function GetSourceData(colIndex As Long)
    ' this function returns an array with "Source" worksheets data in passed column from its row 2 to last not empty one
    With Worksheets("Source") '<--| reference "Source" worksheet
        GetSourceData = Application.Transpose(.Range(.Cells(2, colIndex), .Cells(.Rows.Count, colIndex).End(xlUp)).Value)
    End With
End Function

Function IsValueInRange(tb As MSForms.TextBox, rangeArr As Variant, msgErr As String) As Boolean
    ' this function returns a boolean (true/false) with the result of the checking whether the passed texbox (tb) text exceeds the passed range (rangeArr)
    ' msgErr is also set to some text if the range is exceeded
    With tb
        Select Case CDbl(.Value) '<-- prepare to act accordingly to its value
            Case Is < rangeArr(1) '<--| if it's smaller than "SG Low" value
                msgErr = " is lower than 'SG Low' = " & rangeArr(1) '<-- build the final part of the error message correspondingly
            Case Is > rangeArr(2) '<--| while if it's greater than "SG High" value
                msgErr = " is greater than 'SG High' = " & rangeArr(2) '<-- build the final part of the error message correspondingly
        End Select
    End With
    IsValueInRange = msgErr = ""
End Function

Function GetProdCodeRange(iProd As Long)
    ' this function returns an array of the SG minimum and maximum values in "Source" worksheet corresponding to the chosen product
    With Worksheets("Source") '<--| reference "Source" worksheet
        With .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)) '<--| reference its column "A" cels from row 2 down to last not empty one
            GetProdCodeRange = Application.Transpose(Application.Transpose(.Cells(iProd, 1).Offset(, 2).Resize(, 2).Value)) '<--| return an array with "SG low" and "SG high" values corresponding to the product index passed
        End With
    End With
End Function
'-------------------------------------------------

正如您所看到的,我在您为其选择的名称之后命名了控件,除了添加后缀以告诉它们是什么类型的控件:

  • ProdCodeCB:&#34; CB&#34; - &GT;它是ComboBox控件名称

  • SGresultTB:&#34; TB&#34; - &GT;它是TextBox控件名称

  • ProdNameLbl:&#34; Lbl&#34; - &GT;它是Label控件名称