MS Access VBA字符串连接自动添加回车符

时间:2016-08-11 15:02:45

标签: string excel vba concatenation access

使用MS Access 2016,我将我在查询设计器中创建的查询复制到VBA,因此我可以根据表单上的某些用户选择动态更改WHERE子句。然后将此查询设置为报告的记录源。

在表单上,​​用户可以选择配置三个项目: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 [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 [当前容量] 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 =#8/10/2016#)

     

AND((Config_BaseData_Motors.EquipSystem赞" "))AND((Config_BaseData_Motors.EquipSubSystem Like" "));

我可以稍微缩短我的查询并使其在这个实例中工作,但是如果我想允许他们选择多个系统或子系统呢?最终我会再次开始使用角色并遇到同样的问题。

使用连接是否有更好的方法来实现我的目标?我已经尝试使用一个大的连接语句,并为WHERE子句使用第二个字符串变量,然后将它们一起打印debug.print ssql & ssql2。它们都产生相同的结果。

或者,如果有办法动态编辑MS Access查询以更改where子句;这可能是一种选择。

谢谢

1 个答案:

答案 0 :(得分: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