2016-08-11 100 views
0

使用的MS Access 2016年,我複製我在查詢設計器創建VBA查詢,所以我可以動態改變基於窗體上的一些用戶選擇的WHERE子句。這個查詢然後被設置爲報告的記錄源。的MS Access VBA字符串連接會自動添加回車

在窗體上,用戶可以選擇配置三個項目:1)日期,2)系統(所有系統或特定的一個),3)子系統(所有子系統或特定的一個)。在VBA中,我使用字符串連接組裝查詢語句,並根據所選選項設置WHERE子句。

該報告失敗了,所以我開始調查。當我將字符串打印到即時窗口(debug.print)時,我可以很快看到錯誤。該字符串在大約1138個字符處得到相當長的時間(基於所選選項給出或取出)。字符1027附近VBA似乎自動插入回車。

這是正常的嗎?有沒有解決的辦法?

這是我的代碼:

'Procedure to execute report 
Private Sub cmdExecReport_Click() 
    On Error GoTo ErrHandler 

    Dim ssql As String 
    Dim ssql2 As String 
    Dim StartDate As Date 
    Dim System As Long 
    Dim SubSystem As Long 


    'Step 1: Acquire data from form 

    'Acquire start date 
    StartDate = Me.txtReportDate_Start.Value 
    'Acquire System 
    System = Me.cboSystem.Value 
    'Acquire SubSystem 
    SubSystem = Me.cboSubSystem.Value 


    'Step 2: Configure record source 

    'Assemble the record source string based on the selected items 
    ssql = "SELECT Reliability_MotorData.DateStamp, Config_BaseData_Motors.Service, Config_BaseData_Motors.SysCapacity_Pct AS [Total Capacity], " 
    ssql = ssql & "Reliability_MotorMasterList.EquipmentName AS Equipment, Config_BaseData_Motors.EquipSystem, Config_BaseData_Motors.EquipSubSystem, " 
    ssql = ssql & "Motor_GetSystemName([Config_BaseData_Motors].[EquipSystem]) AS System, Motor_GetSubSystemName([Config_BaseData_Motors].[EquipSubSystem]) AS [Sub System], " 
    ssql = ssql & "IIf(Motor_GetServiceStatus([Reliability_MotorData].[MotorID],[SelectDate])=-1," & """" & "OOS" & """" & ",IIf(Motor_GetServiceStatus([Reliability_MotorData].[MotorID]," 
    ssql = ssql & "[SelectDate])=0," & """" & "In Service" & """" & "," & """" & "Unknown" & """" & ")) AS [Service Mode], Motor_GetCurrentMotorCapacity([Reliability_MotorData].[MotorID],[SelectDate]) AS [Current Capacity] " 
    ssql = ssql & "FROM (Config_BaseData_Motors RIGHT JOIN Reliability_MotorMasterList ON Config_BaseData_Motors.MotorID = Reliability_MotorMasterList.MotorID) " 
    ssql = ssql & "INNER JOIN Reliability_MotorData ON Reliability_MotorMasterList.MotorID = Reliability_MotorData.MotorID " 

    'Configure the Where clause 
    ssql = ssql & "WHERE ((Reliability_MotorData.DateStamp = #" & StartDate & "#) " 

    'Configure the System list 
    ssql = ssql & "AND ((Config_BaseData_Motors.EquipSystem " 
    'Check the system selected 
    If System = -1 Then 'all systems 
     ssql = ssql & "Like " & """" & "*" & """" & ") " 
    Else 'specific one 
     ssql = ssql & "= " & System 
    End If 
    'Add closing paren 
    ssql = ssql & ") " 


    'Configure the SubSystem list 
    ssql = ssql & "AND ((Config_BaseData_Motors.EquipSubSystem " 
    'Check the subsystem selected 
    If SubSystem = -1 Then 'all subsystems 
     ssql = ssql & " Like " & """" & "*" & """" & ")" 
    Else 'specific one 
     ssql = ssql & "= " & SubSystem 
    End If 

    'Add closing paren & ; 
    ssql = ssql & ");" 

    Debug.Print ssql 

    'Step 3: Launch Report 
    ' DoCmd.OpenReport "Motor Capacity 4", acViewPreview, , , , ssql 

    Exit Sub 

ErrHandler: 
    'Write to event log 
    Call WriteWinEventLog(Error, Now() & " - " & "Execution error on form " & CurrentFormName & " in routine cmdExecReport_Click" & vbCrLf _ 
    & "Error Number: " & Err.Number & vbCrLf & "Source: " & Err.Source & vbCrLf & "Description: " & Err.Description) 

End Sub 

這裏是打印的結果(線飼料添加的回車可見性):

SELECT Reliability_MotorData.DateStamp,Config_BaseData_Motors.Service,Config_BaseData_Motors .SysCapacity_Pct AS [總容量],Reliability_MotorMasterList.EquipmentName AS設備,Config_BaseData_Motors.EquipSystem,Config_BaseData_Motors.EquipSubSystem,Motor_GetSystemName([Config_BaseData_Motors] [EquipSystem])AS系統,Motor_GetSubSystemName([Config_BaseData_Motors ] [EquipSubSystem])AS [子系統],IIF(Motor_GetServiceStatus([Reliability_MotorData] [MotorID],[SelectDate]。)= - 1, 「OOS」,IIF(Motor_GetServiceStatus([Reliability_MotorData] [MotorID],[SelectDate ])= 0, 「以服務」, 「未知」))AS [服務模式],Motor_GetCurrentMotorCapacity([Reliability_MotorData] [MotorID],[SelectDate])AS [電流容量] FROM(Config_BaseData_Motors RIGHT JOIN Reliability_MotorMasterList ON Config_BaseData_Motors.MotorID = Reliability_MotorMasterList.MotorID)INNER JOIN Reliability_MotorData ON Reliability_MotorMasterList.MotorID = Reliability_MotorData.MotorID WHERE((Reliability_MotorData.DateStamp =#7/10/2016年#)

AND((Config_BaseData_Motors.EquipSystem像 「」))AND(( Config_BaseData_Motors.EquipSubSystem Like「」));

我可以縮短我的查詢了一下,並使其在這種情況下工作,但如果我想讓他們選擇多個系統或子系統呢?最終我會再次使用字符並遇到同樣的問題。

有沒有更好的方式使用級聯實現我的目標是什麼?我已經嘗試過使用一個大的並置語句,併爲WHERE子句使用第二個字符串變量,然後將它們一起打印出來debug.print ssql & ssql2。他們都產生相同的結果。

可替換地,如果存在方法的方式來動態地修改MS Access查詢改變where子句;這可能是一個選擇。

謝謝

+0

您是否嘗試過使用別名,某事。像這樣SELECT fieldname AS f FROM tablename t WHERE t.f = 1.這將是一個簡單的方法來縮短您的查詢。另一種方法是將查詢保存在視圖中,並使用where子句,即select * from view where ... –

+0

您可以使用'Currentdb.QueryDefs(「query_name」)更改查詢定義。SQL =「new SQL「' – winghei

回答

0

最好的做法是不要在代碼中構建SQL查詢,無論如何。只需保存您構建的查詢,然後使用參數化的querydef來調用它。例如。保存查詢:

SELECT Reliability_MotorData.DateStamp, 
    Config_BaseData_Motors.Service, 
    Config_BaseData_Motors.SysCapacity_Pct AS [Total Capacity], 
    Reliability_MotorMasterList.EquipmentName AS Equipment, 
    Config_BaseData_Motors.EquipSystem, 
    Config_BaseData_Motors.EquipSubSystem, 
    Motor_GetSystemName([Config_BaseData_Motors].[EquipSystem]) AS System, 
    Motor_GetSubSystemName([Config_BaseData_Motors].[EquipSubSystem]) AS [Sub System], 
    IIf(Motor_GetServiceStatus([Reliability_MotorData].[MotorID], [SelectDate])=-1, 
     "OOS", 
     IIf(Motor_GetServiceStatus([Reliability_MotorData].[MotorID],[SelectDate])=0, 
     "In Service", 
     "Unknown")) AS [Service Mode], 
    Motor_GetCurrentMotorCapacity([Reliability_MotorData].[MotorID],[SelectDate]) AS [Current Capacity] 
FROM (Config_BaseData_Motors 
    RIGHT JOIN Reliability_MotorMasterList 
     ON Config_BaseData_Motors.MotorID = Reliability_MotorMasterList.MotorID) 
    INNER JOIN Reliability_MotorData 
     ON Reliability_MotorMasterList.MotorID = Reliability_MotorData.MotorID 
WHERE ((Reliability_MotorData.DateStamp = [SearchDate]) 
    AND ((Config_BaseData_Motors.EquipSystem Like [SearchSystem])) 
    AND ((Config_BaseData_Motors.EquipSubSystem Like [SearchSubSystem])); 

和查詢它像:

Private Sub cmdExecReport_Click() 
    On Error GoTo ErrHandler 

    Dim qdf As QueryDef 
    Dim StartDate As Date 
    Dim System As Long 
    Dim SubSystem As Long 

    'Step 1: Acquire data from form 
    StartDate = Me.txtReportDate_Start.Value 'Acquire start date 
    System = Me.cboSystem.Value 'Acquire System 
    SubSystem = Me.cboSubSystem.Value 'Acquire SubSystem 

    'Step 2: Acquire QueryDef 
    Set qdf = CurrentDB.QueryDefs("qryMyParameterQuery") ' EDIT THIS 

    'Step 3: Substitute Parameters 
    'Substitute date 
    qdf.Parameters("SearchDate") = "#" & StartDate & "#" 

    'Substitute system 
    If System = -1 Then 
     qdf.Parameters("SearchSystem") = """*""" 
    Else 
     qdf.Parameters("SearchSystem") = """" & System & """" ' format as String 
    End If 

    'Substitute subsystem 
    If SubSystem = -1 Then 
     qdf.Parameters("SearchSubSystem") = """*""" 
    Else 
     qdf.Parameters("SearchSubSystem") = """" & SubSystem & """" ' format as String 
    End If 

    ' Step 4: Open report, recordset, etc. 
    ' Example: 
    'Dim rst As Recordset 
    'Set rst = qdf.OpenRecordset() 
    '... 

End Sub 
+0

謝謝!我最終使用了你的答案和上面@winghei的評論的組合。我沒有想過添加到現有查詢的querydef。我最終的目標是允許用戶從每個列表中選擇多個項目,並且'LIKE'運算符不會接受逗號分隔列表。最後,我使用VBA在現有的querydef的末尾組裝並添加一個自定義的'WHERE'子句。 – DaveJM