在VBA中优化此代码

时间:2010-07-14 13:07:18

标签: access-vba

嗨,大家好,所以我正在浏览,其中一个主题是“如何判断一个学生是否对此进行了编码”......好吧,我是一名学生,作为一名实习生在一家大公司工作。我最近在Access中为他们编写了一个报告工具,并对一段代码提出了疑问

    'get the dates'
'check if both date fields are filled out'
If A_AfterDateTxt.Value <> "" And A_BeforeDateTxt.Value <> "" Then
    'check if they are valid (ie, one date is not bigger then the other)'
    If CDate(A_AfterDateTxt.Value) > CDate(A_BeforeDateTxt.Value) Then
        MsgBox "You have selected invalid dates. Try again."
        GetSQLForActiveRecords = False   'this is the function name
        Exit Function  'exit the function'
    Else
        'this takes both fields and appends them to the sql statement'
        strSql = strSql & " AND ([Submitted] >= #" & A_AfterDateTxt.Value & "#  and [Submitted] <= #" & A_BeforeDateTxt.Value & "#)"
    End If
Else
    'one or both of them are blank, select the one thats entered
    If (SF_isNothing(A_AfterDateTxt.Value) And Not SF_isNothing(A_BeforeDateTxt.Value)) Then
        strSql = strSql & " AND ([Submitted] <= #" & A_BeforeDateTxt.Value & "#)"
    ElseIf (SF_isNothing(A_BeforeDateTxt.Value) And Not SF_isNothing(A_AfterDateTxt.Value)) Then
        strSql = strSql & " AND ([Submitted] >= #" & A_AfterDateTxt.Value & "#)"
    End If
End If

注意:SI_isnothing只是一个检查null / empty的函数,但由于它们的数据来自文本框,它永远不会为空吗?

因此有两个日期文本框(AfterDate和BeforeDate)。我根据填写的内容构建我的SQL语句(即输入一个,另一个空)

那么如何修改它以使其更具可读性。

5 个答案:

答案 0 :(得分:3)

只有4个可能的“州”:

  • 都是空的
  • 有效
  • b有效
  • 两者都有效

考虑到这一点,你可以减少你的逻辑:

    Dim dx As Integer = 0

    If Not String.IsNullOrEmpty(txtBefore.Text) Then
        If IsDate(txtBefore.Text) Then
            dx += 1
        End If
    End If

    If Not String.IsNullOrEmpty(txtAfter.Text) Then
        If IsDate(txtAfter.Text) Then
            dx += 2
        End If
    End If

    Select Case dx
        Case 1
            'only before date is not empty and a valid date
        Case 2
            'only after date is not empty and a valid date
        Case 3
            'both are valid and not empty
    End Select

请注意这是vb.NET,我不确定其中有多少转换为VBA

答案 1 :(得分:1)

我清理了一下代码。您可以将文本框中的值放在变量中,这使得使用值的代码不那么麻烦。

'get the dates
Dim before As String = A_BeforeDateTxt.Value
Dim after As String = A_AfterDateTxt.Value
'check if both date fields are filled out
If after.Length > 0 And before.Length > 0 Then
    'check if they are valid (ie, one date is not bigger then the other)
    If CDate(after) > CDate(before) Then
        MsgBox "You have selected invalid dates. Try again."
        GetSQLForActiveRecords = False
        Exit Function
    Else
        'this takes both fields and appends them to the sql statement
        strSql = strSql & " AND ([Submitted] >= #" & after & "#  and [Submitted] <= #" & before & "#)"
    End If
Else
    'one or both of them are blank, select the one thats entered
    If (after.Length = 0 And before.Length > 0 Then
        strSql = strSql & " AND ([Submitted] <= #" & before & "#)"
    ElseIf before.Length = 0 And after.Length > 0 Then
        strSql = strSql & " AND ([Submitted] >= #" & after & "#)"
    End If
End If

你是对的,总是一个字符串的值不能是Nothing。检查不会发生的情况只会使代码更加混乱,因为它意味着该值可能是实际上不可能的值。

我使用Length属性来检查字符串是否为空。比较数字比比较字符串更有效,而且它也更不容易出现拼写错误。你可能不小心写了“'”而不是“”,这并不容易发现。

我删除了一些毫无意义的评论。注释应该解释代码中需要解释的内容,只是字面上告诉代码执行的注释只会使代码混乱,如下所示:

Exit Function  'exit the function'

可以重写代码以重用添加条件的部分,这样就不会在三个地方重置代码。它会使代码变得更复杂,所以它是值得的,这是值得怀疑的。

答案 2 :(得分:1)

通常,将多个布尔值计算结合到单个变量中通常会提高可读性。

If A_AfterDateTxt.Value <> "" And A_BeforeDateTxt.Value <> "" Then .....

becomes

Dim dateValuesPresent as Boolean = A_AfterDateTxt.Value <> "" And A_BeforeDateTxt.Value <> ""

If dateValuesPresent Then ....





If CDate(A_AfterDateTxt.Value) > CDate(A_BeforeDateTxt.Value) Then ....

becomes

Dim areValidDates as Boolean = CDate(A_AfterDateTxt.Value) > CDate(A_BeforeDateTxt.Value)

If areValidDates Then ....

答案 3 :(得分:0)

使用以下功能:

Private Function IsNullOrZLS(toCheck As Variant) As Boolean
IsNullOrZLS = True
If TypeName(toCheck) = "String" Then
    If Len(toCheck) > 0 Then IsNullOrZLS = False
End If
End Function

我建议如下:

Public Function GetSQLForActiveRecords() As Boolean
Dim whereClause As String, badDate As Boolean
Dim before As Date, after As Date

If Not IsNullOrZLS(A_BeforeDateTxt) Then
    If Not IsDate(A_BeforeDateTxt) Then
        MsgBox "Unable to parse date!"
        GetSQLForActiveRecords = False
        Exit Function
    End If
    before = CDate(A_BeforeDateTxt)
    whereClause = "[Submitted] <= #" & A_BeforeDateTxt.value & "#"
End If

If Not IsNullOrZLS(A_AfterDateTxt) Then
    If Not IsDate(A_AfterDateTxt) Then
        MsgBox "Unable to parse date!"
        GetSQLForActiveRecords = False
        Exit Function
    End If
    after = CDate(A_AfterDateTxt)
    If Len(whereClause) > 0 Then whereClause = whereClause & " AND "
    whereClause = "[Submitted] >= #" & A_AfterDateTxt.value & "#"
End If

If after <> 0 And before > after Then
    MsgBox "Invalid dates!"
    GetSQLForActiveRecords = False
    Exit Function
End If

GetSQLForActiveRecords = True

If Len(whereClause) = 0 Then Exit Function

strsql = strsql & " AND (" & whereClause & ")"
End Function

一些注意事项:

  • 这可以处理无效日期的可能性
  • 它在VBA中,而不是VB.NET
  • 一旦检测到错误,请退出该功能。这有助于避免嵌套的If-Then
  • 尚未初始化的Date变量的值为0,对应于1899年12月30日12:00 AM。如果将该日期输入A_AfterDateTxt文本框,则代码会将其视为空。
  • 必须有一些方法可以避免重复日期解析消息。

答案 4 :(得分:0)

你想要可读性吗?像这样:

Select Case True
Case Not IsDate(A_BeforeDateTxt.Value) And Not IsDate(A_AfterDateTxt.Value)
    MsgBox "You have selected invalid dates. Try again."
    GetSQLForActiveRecords = False   'this is the function name

Case A_AfterDateTxt.Value = ""
    strSql = strSql & " AND ([Submitted] <= #" & A_BeforeDateTxt.Value & "#)"

Case A_BeforeDateTxt.Value = ""
    strSql = strSql & " AND ([Submitted] <= #" & A_BeforeDateTxt.Value & "#)"

Case CDate(A_AfterDateTxt.Value) > CDate(A_BeforeDateTxt.Value)
    MsgBox "You have selected invalid dates. Try again."
    GetSQLForActiveRecords = False   'this is the function name

Case Else
    strSql = strSql & " AND ([Submitted] >= #" & A_AfterDateTxt.Value & "# and
      [Submitted] <= #" & A_BeforeDateTxt.Value & "#)"

End Select