如何使用数组使以下代码更简单

时间:2011-03-25 21:50:30

标签: ms-access access-vba

这绝不是必要的,但我想了解如何创建更高效​​的代码,我确信这远远没有效率!

在表单上禁用字段值将在保存表单之前清除。

以下代码向用户发送消息,告知用户如果未选中复选框,可能会丢失一些数据。 在形式的上下文中,这一切都是有道理的,我只想知道一种更简单的方法,我确信我可以在某个地方使用数组但不能完全理解它。

Dim couldLoseData As Boolean
Dim msgStr As String

couldLoseData = False

If (Me.chkInvSent = False) And (Not IsNull(Me.invoicedDate)) Then
        couldLoseData = True
        msgStr = "Invoice Sent"
End If
If (Me.chkFeePaid = False) And (Not IsNull(Me.datePaid)) Then
    couldLoseData = True
    If msgStr = "" Then
    msgStr = "Claim Fee Paid"
    Else
    msgStr = msgStr & " / Claim Fee Paid"
    End If
End If
If (Me.chkFeeLodged = False) And (Not IsNull(Me.lodgedDate)) Then
    couldLoseData = True
        If msgStr = "" Then
        msgStr = "Fee Lodged"
        Else
        msgStr = msgStr & " / Fee Lodged"
        End If
End If
If couldLoseData = True Then
    If MsgBox("You will lose data in the following areas as the relevant checkboxes are unticked." & vbNewLine & vbNewLine & _
        msgStr & vbNewLine & vbNewLine & "Do you wish to continue?", vbYesNo, dbNameOf) = vbNo Then
        Cancel = True
    End If
Else
    '
'
'
'   Procedure that gets carried out here

End If

没什么大不了的,但如果有人能给我一个更简单的解决方案,我们将不胜感激。

干杯

诺尔

6 个答案:

答案 0 :(得分:3)

我不确定您认为应该使用数组的原因。当涉及到msgStr变量逻辑时,我只需要输入以下内容:

msgStr = msgStr & "Invoice Sent / "

而不是五行if msgstr =“”然后等等,结束如果行。

然后在最后我会放入以下行

msgStr = lef(msgStr, len(msgStr) - 3) ' remove the trailing /

然后删除尾随的“/”

纯粹主义者会告诉你,你永远不应该在以后删除的字符串中添加任何东西。我说,只要你在那里为下一个正在阅读代码的人发表评论,这就会降低你前面代码行的复杂性,从而更容易理解正在发生的事情。

每当我要查找从MsgBox返回的值时,我将字符串创建放在一个单独的代码行中。因此,一目了然,更容易看到代码正在做什么。

strMsg = "You will lose data in the following areas as the relevant checkboxes are unticked." & vbNewLine & vbNewLine & _
    msgStr & vbNewLine & vbNewLine & "Do you wish to continue?"
If MsgBox(strMsg, vbYesNo, dbNameOf) <> vbYes Then _
    Cancel = True

如果我只在If语句中设置一个值,例如你显示,我也会输入_,因此不需要End If。

我也更喜欢&lt;&gt; vbYes万一有些事情会发生,或者有人,当然不是你,使用msgbox选项。

答案 1 :(得分:1)

为什么在没有填写所有数据字段时,您甚至允许用户关闭表单?

基本上,对我来说,你的逻辑是错误的。如果您的表单上有一个CLOSE按钮(假设您已经摆脱了默认的Windows CLOSE X),那么在所有数据字段都已正确填写之前,您不会启用它。

我通常这样做的方法是编写一个子程序(或函数)来检查所有必须填写的字段,如果一切正常,则启用CLOSE按钮。因此,用户无法关闭表单,直到填写完所有相应的字段,除非您提供了CANCEL按钮(在这种情况下,您希望丢失数据)。

答案 2 :(得分:0)

您不需要数组,只需要一个简单的辅助方法来简化代码并使其更具可重用性:

(只需替换以下代码中的复选框和条件)

Public Function ErrorChecker(assumption As Boolean, errorMessage As String, condition As Boolean, concatenate As Boolean) As String
    Dim ret As String = [String].Empty
    If Not assumption AndAlso condition Then
            If concatenate Then
                ret += " / "
            End If
        ret += errorMessage
    End If
    Return ret
End Function

Private Sub button1_Click(sender As Object, e As EventArgs)
    Dim message As String = [String].Empty
    message += ErrorChecker(checkBox1.Checked, "Error 1", value1 Is Nothing, False)
    message += ErrorChecker(checkBox2.Checked, "Error 2", value2 Is Nothing, True)
    message += ErrorChecker(checkBox3.Checked, "Error 3", value3 Is Nothing, True)
    If message <> String.Empty Then
            'messagebox
    End If
End Sub

答案 3 :(得分:0)

这就是我编码的方式

Dim couldLoseData As Boolean
Dim msgStr As String
Dim InvBoolean as boolean
Dim PaidBoolean as boolean
Dim LodgedBoolean as boolean
Dim response as integer

couldLoseData = False

InvBoolean = (Me.chkInvSent = False) And (Not IsNull(Me.invoicedDate))
PaidBoolean = (Me.chkFeePaid = False) And (Not IsNull(Me.datePaid))
LodgedBoolean = (Me.chkFeeLodged = False) And (Not IsNull(Me.lodgedDate))

couldLoseData = InvBoolean or PaidBoolean or LodgeBoolean
'if any one is true, there could be lost data.

if couldLoseData = false then
    exit sub 'bail if nothing applies
    'you may want a GOTO if there is stuff this sub needs to do regardless
end if

If InvBoolean = true then 'add phrase and move to new line
    msgStr = msgStr & "Invoice Sent" & vbcrlf
end if

If PaidBoolean = true then 'add phrase and move to new line
    msgStr = msgStr & "Claim Fee Paid" & vbcrlf
end if

If LodgedBoolean = true then 'add phrase and move to new line
    msgStr = msgStr & "Fee Lodged" & vbcrlf
end if


If couldLoseData = True Then
    msgStr = "You will lose data in the following areas as the relevant checkboxes are unticked." & vbcrlf & msgStr & vbcrlf
    msgStr = msgStr & "Do you wish to continue?"
    response = msgbox(msgstr, vbYesNo)
    if response = vbno then
        Cancel = True
    End If
end if

答案 4 :(得分:0)

我编写了一个简单的函数来连接两个字符串,这样就无需担心在连接完成后是否需要删除任何内容。这是功能:

'-----------------------------------------------------------------------------
' Purpose   : Concatenates two strings
' Usage     : Dim MyList As String
'             MyList = Conc(MyList, SomeValue)
' Notes     : Eliminates the need to strip off the leading/trailing delimiter 
'             when building a string list
'-----------------------------------------------------------------------------
Function Conc(StartText As String, NextVal, _
              Optional Delimiter As String = ", ") As String
    If Len(StartText) = 0 Then
        Conc = Nz(NextVal)
    ElseIf Len(CStr(Nz(NextVal))) = 0 Then
        Conc = StartText
    Else
        Conc = StartText & Delimiter & NextVal
    End If
End Function

以下是我使用此函数重写代码的方法:

Dim msgStr As String

If (Me.chkInvSent = False) And (Not IsNull(Me.invoicedDate)) Then
    msgStr = Conc(msgStr, "Invoice Sent", " / ")
End If
If (Me.chkFeePaid = False) And (Not IsNull(Me.datePaid)) Then
    msgStr = Conc(msgStr, "Claim Fee Paid", " / ")
End If
If (Me.chkFeeLodged = False) And (Not IsNull(Me.lodgedDate)) Then
    msgStr = Conc(msgStr, "Fee Lodged", " / ")
End If
If Len(msgStr) > 0 Then
    If MsgBox("You will lose data in the following areas as the relevant checkboxes are unticked." & vbNewLine & vbNewLine & _
        msgStr & vbNewLine & vbNewLine & "Do you wish to continue?", vbYesNo, dbNameOf) <> vbYes Then
        Cancel = True
    End If
Else
    '   Procedure that gets carried out here
End If

答案 5 :(得分:0)

如果您真的想要使用数组:

Dim couldLoseData As Boolean
Dim msgStr As String
Dim ConditionsResponses(0 to 2,1)
Dim x as integer
Dim response as integer

couldLoseData = False

ConditionsResponses(0,0) = (Me.chkInvSent = False) And (Not IsNull(Me.invoicedDate))
ConditionsResponses(1,0) = (Me.chkFeePaid = False) And (Not IsNull(Me.datePaid))
ConditionsResponses(2,0) = (Me.chkFeeLodged = False) And (Not IsNull(Me.lodgedDate))

ConditionsResponses(0,1) = "Invoice Sent" & vbcrlf
ConditionsResponses(1,1) = "Claim Fee Paid" & vbcrlf
ConditionsResponses(2,1) = "Fee Lodged" & vbcrlf


couldLoseData = ConditionsResponses(0,0) or ConditionsResponses(0,0) or ConditionsResponses(0,0)
'if any one is true, there could be lost data.

for x = 0 to 2
    if ConditionsResponses(x,0)= true then
    msgStr = msgStr & ConditionsResponses(x,1)
    end if
next x

If couldLoseData = True Then
    msgStr = "You will lose data in the following areas as the relevant checkboxes are unticked." & vbcrlf & msgStr & vbcrlf
    msgStr = msgStr & "Do you wish to continue?"
    response = msgbox(msgstr, vbYesNo)
    if response = vbno then
        Cancel = True
    End If
end if