2010-07-14 63 views
1

嗨,大家好,我正在瀏覽所以我的主題之一是「如何判斷一個學生是否編碼了這個」..我是一名在實習生中爲一家大公司工作的學生。我最近編碼的訪問爲他們的報告工具,並且有關於一段代碼的問題在VBA中優化此代碼

'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僅僅是檢查空/空的功能,但因爲他們的數據是從一個文本框它將永遠不會是空的權利?

所以有兩個日期文本框(AfterDate和BeforeDate)。我建立我的SQL語句取決於填寫什麼(即一個輸入,另一個空)

所以我怎麼能修改這使它更具可讀性。

+0

爲什麼它需要更具可讀性?它目前有效嗎? – Fosco 2010-07-14 13:10:42

+0

是的,它的工作原理是,但我希望它對下一個將要工作的人更具可讀性。 – masfenix 2010-07-14 13:11:43

+0

文本框的值可以爲null。 – 2012-10-17 09:53:30

回答

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' 

的代碼可以重寫,你重複使用部分添加條件,以便在三個地方沒有這些條件。這會讓代碼更復雜一點,所以值得懷疑是否值得。

+0

這看起來像VB.NET。在VBA中,字符串沒有Length屬性;你使用Len函數檢查一個字符串的長度。 – 2012-10-17 09:49:59

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

+0

我非常喜歡這種方法。我會嘗試。 – masfenix 2010-07-14 13:53:17

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 .... 
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文本框中,則該代碼將其視爲空白。
  • 必須有一些方法來避免重複日期分析消息。
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