2016-08-01 100 views
1

我有一個表單中有幾個複選框。勾選複選框的值在包含Excel宏的SQL查詢中使用。我在SQL「IN」 - 操作符中使用這些值。所以,everythig工作。但我不喜歡我的宏的代碼。使用SQL中的複選框值「IN」--operator

對於勾選複選框我用這樣的代碼(如果有更多的價值列表將是非常巨大的):

Public Location1 As String 
Public Location2 As String 
Public Location3 As String 
Public Location4 As String 

Private Sub OKCommandButton2_Click() 
If CheckBox1.Value = True Then Location1 = "LocationValue1" 
If CheckBox2.Value = True Then Location2 = "LocationValue2" 
If CheckBox3.Value = True Then Location3 = "LocationValue3" 
If CheckBox4.Value = True Then Location4 = "LocationValue4" 
... 

而對於在SQL中使用它,我用這樣的代碼:

query = "SELECT Param1, Param2, Param3, Param4, 0, 0, Param5, 0 FROM Table1 " & _ 
"WHERE Param1 like'" & "%" & CraftDefinition.Craft & "%" & "'AND Param6>0 AND Param2 IN ('" & _ 
LocationDefinition.Location1 & "','" & LocationDefinition.Location2 & "','" & LocationDefinition.Location3 & "','" & _ 
LocationDefinition.Location4 & "')" & _ 
"ORDER BY Param2, Param3" 

問題是:我可以用更緊湊,簡潔和複雜的方式重寫我的代碼嗎?也許我應該在SQL部分中使用另一個運算符;也許我可以重寫我的VBA部分,因爲在SQl中只使用一個參數。

謝謝。

+0

什麼是'LocationDefinition'? – user3598756

+0

這是一個帶有註釋複選框的表單名稱。 – Mikhail

+0

我猜對了。看到我的回答 – user3598756

回答

0

您可以使用「控制」功能,並從複選框寫你的價值進入「TAG」

Dim TB As Control 
Dim ChkBoxString As String 
ChkBoxString = "(" 

For Each TB In Me.Controls  
    If TypeOf TB Is CheckBox Then 
     If TB.Value = True Then 
      ChkBoxString = ChkBoxString & TB.Tag & ", " 
     End If 
    End If 
Next TB 
ChkBoxString = ChkBoxString & ")" 
ChkBoxString = Replace(ChkBoxString, ",)", ")") 

所以你可以使用你的腳本:

query = "SELECT Param1, Param2, Param3, Param4, 0, 0, Param5, 0 FROM Table1 " & _ 
"WHERE Param1 like'" & "%" & CraftDefinition.Craft & "%" & "'AND Param6>0 AND Param2 " _ 
IN " & ChkBoxString 

電賀拉爾夫

+0

感謝您的解決方案。 宏在您的示例中使用了一些添加。 1)我在必要的地方添加了符號「'」。 2)但最大的問題是「If TypeOf Is CheckBox」 - 條件。只有我把「MSForm」放在這個構造纔有效。之前「CheckBox」。 – Mikhail

0

創建返回帶逗號分隔字符串表達式的函數,並設置複選框的Tag屬性中的值

Function GetExpression() As String 
Dim contr As Control 
Dim comma As String 
Dim str As String 
str = "" 
For Each contr In UserForm1.Controls 
    comma = IIf(str <> "", ",", "") 
    If TypeName(contr) = "CheckBox" Then 
    If contr.Value = True Then str = str + comma + contr.Tag 
    End If 
Next 
GetExpression = str 
End Function 
0

如果子說,「讓」查詢(或建立查詢字符串)被調用,而用戶窗體仍然加載,那麼你可以編寫如下:

Option Explicit 

Dim Locations As String '<--| UserForm scoped variable: all subs in the userform code pane can "see" it 

Private Sub OKCommandButton2_Click() 
    Dim ctrl As Control 

    For Each ctrl In Me.Controls '<--| loop through userform controls 
     If TypeName(ctrl) = "CheckBox" Then '<--| consider only checkboxes 
      If ctrl.value Then Locations = Locations & "LocationValue" & Mid(ctrl.Name, 9, Len(ctrl.Name) - 8) & "','" '<--| if checkbox is checked then update 'Location' string 
     End If 
    Next ctrl  
End Sub 

Private Sub QuerySub() '<-- name of any Sub inside Userfom code pane that has to make the query 
    Dim Query As String 

    If Locations <> "" Then '<--| this Sub can "see" 'Locations' even if it has been initialized in a different Sub of the same Userform code pane 
     Query = "SELECT Param1, Param2, Param3, Param4, 0, 0, Param5, 0 FROM Table1 " & _ 
     "WHERE Param1 like'" & "%" & CraftDefinition.Craft & "%" & "'AND Param6>0 AND Param2 IN ('" & _ 
     Left(Locations, Len(Locations) - 3) & "')" & _ 
     "ORDER BY Param2, Param3" 
    Else 
     ' code to handle 'Locations' empty string 
    End If 
End Sub 
0

這似乎是一點點錯誤的,因爲你IN ('', '', '', '')選中的時候,但如果你不介意的話,也許是這樣的:

locations$ = Mid$(_ 
    IIf(CheckBox1, "','LocationValue1", "") & _ 
    IIf(CheckBox2, "','LocationValue2", "") & _ 
    IIf(CheckBox3, "','LocationValue3", "") & _ 
    IIf(CheckBox4, "','LocationValue4", ""), 4) ' works even is all unchecked 

query = " ... AND Param2 IN ('" & locations & "') ORDER BY Param2, Param3" 

,或者如果所有值真的「LocationValue」然後開始

Locations$ = Mid$(Replace(IIf(CheckBox1, ",1", "") & _ 
    IIf(CheckBox2, ",2", "") & IIf(CheckBox3, ",3", "") & _ 
    IIf(CheckBox4, ",4", ""), ",", "','LocationValue"), 4)