MS ACCESS:如何使用组合框和查询条件过滤报告

问题描述 投票:0回答:2

我有一个有3个表的数据库(ListOfDevice,DeviceType,Employee)。

ListOfDevice表

  1. 设备名称
  2. 设备模型
  3. DeviceType ------>使用ID和DeviceType引用DeviceType表。
  4. EmployeeID ------>使用ID和FirstName引用Employee表。
  5. DeviceStatus ------>这只有两个值:Working或Damaged。

某些记录没有employeeID,并且在设备状态字段中标记为“已损坏”。

我创建了一个查询并将其命名为“QryDeviceLists”,在此查询中我导入了这3个表并开始过滤查询和报告结果。我使用“Like”和Wildcard进行过滤。

示例:Like"*" &[Form]![FormName]![ControlName or Combo box name]&"*"

我在这里尝试过滤的是DeviceType,EmployeeID和DeviceStatus。我希望这个过滤器工作的方式是通过组合框,我有一个表单,我命名为过滤器,在这个表单内是3个未绑定的组合框链接到这3个表。以下是我将如何生成报告:

  • 如果我从devicetype组合框中选择一个值“桌面或笔记本电脑”并将其他组合框留空,那么它应该给我一个笔记本电脑或台式机的结果,所有用户和设备状态是否工作或损坏。
  • 对于EmployeeID组合框,如果我选择了名称或员工ID,它应该给出专门为该员工分配的特定设备的结果。
  • 对于设备状态组合框,它应该给出工作或损坏的结果,具体取决于组合框中的选择。
  • 通过将所有组合框留空,它应该显示设备的所有记录,无论是笔记本电脑还是台式电脑,工作还是损坏,分配给所有员工。

以下是我在尝试使用组合框提取报告时遇到的问题。

  • 如果我从“设备类型”中选择一个值并将员工ID和状态保留为空白,则不会显示任何记录。同样的问题转到员工ID组合框,如果我将设备类型和状态保留为空白,也没有显示任何记录。
  • 如果我将所有组合框留空,则仅显示标记为在设备状态上工作的记录。这可能是因为标记为Damaged的其他记录在employee ID字段中没有任何值。因为当我尝试在Employee ID字段中放置一个值并通过将所有组合框留空来重新生成查询时,所有记录都会显示出来。

注意:我没有任何VBA经验,而且我正在使用Access 2013-2016

以下是查询SQL Lines SELECT ListOfDevices.ID, ListOfDevices.DeviceName, ListOfDevices.[Device Model], DeviceType.DeviceType, Employee.FirstName, ListOfDevices.DeviceStatus FROM Employee RIGHT JOIN (DeviceType RIGHT JOIN ListOfDevices ON DeviceType.ID = ListOfDevices.DeviceType) ON Employee.ID = ListOfDevices.EmployeeID WHERE (((DeviceType.DeviceType) Like "*" & [Forms]![filter]![CboDevType] & "*") AND ((Employee.FirstName) Like "*" & [Forms]![filter]![CboEmp] & "*") AND ((ListOfDevices.DeviceStatus) Like "*" & [Forms]![filter]![CboStat] & "*"));

forms ms-access access-vba
2个回答
0
投票

考虑这个纯SQL解决方案,WHERE子句指向组合框(没有LIKE表达式)。如果组合框是空的,NZ()会返回该区域。如果报表/表单绑定到此查询,则不需要VBA。

QryDeviceLists

SELECT l.ID, l.DeviceName, l.[Device Model], d.DeviceType, e.FirstName, l.DeviceStatus 
FROM Employee e
RIGHT JOIN (DeviceType d
RIGHT JOIN ListOfDevices l ON d.ID = l.DeviceType) 
   ON e.ID = l.EmployeeID 

WHERE ((d.DeviceType) = NZ([Forms]![filter]![CboDevType], d.DeviceType)
   AND (e.ID) = NZ([Forms]![filter]![CboEmp], e.FirstName)
   AND (l.DeviceStatus) = NZ([Forms]![filter]![CboStat], l.DeviceStatus))

    OR     
    (
        IIF([Forms]![filter]![CboDevType] IS NULL, d.DeviceType IS NULL, [Forms]![filter]![CboDevType] = d.DeviceType)
    AND IIF([Forms]![filter]![CboEmp] IS NULL, e.ID IS NULL, [Forms]![filter]![CboEmp] = e.ID)
    AND IIF([Forms]![filter]![CboStat] IS NULL, l.DeviceStatus IS NULL, [Forms]![filter]![CboStat] = l.DeviceStatus)
    )

    OR    
    (
      IIF([Forms]![filter]![CboDevType] IS NULL AND 
          [Forms]![filter]![CboEmp] IS NULL AND
          [Forms]![filter]![CboStat] IS NULL, 

          d.DeviceType IS NULL OR e.ID IS NULL OR l.DeviceStatus IS NULL , 

          [Forms]![filter]![CboDevType] = d.DeviceType OR
          [Forms]![filter]![CboEmp] = e.ID OR
          [Forms]![filter]![CboStat] = l.DeviceStatus)         
    )

笔记:

  • 根据您的设置,可能需要在表单或报表上调用Requery(可用作宏命令)
  • 在表单上包含一个使用SetValue宏事件的“删除过滤器”按钮,并为所有控件分配值NULL

0
投票

我从其他论坛找到了一个我无法提及的解决方案,因为如果允许的话,我不会这样做。但是,这是我用来解决问题的SQL Line。

SELECT ListOfDevices.ID, ListOfDevices.DeviceName, ListOfDevices.[Device Model], DeviceType.DeviceType, Employee.FirstName, ListOfDevices.DeviceStatus FROM Employee RIGHT JOIN (DeviceType RIGHT JOIN ListOfDevices ON DeviceType.ID = ListOfDevices.DeviceType) ON Employee.ID = ListOfDevices.EmployeeID WHERE ((([DeviceType.DeviceType] Like "*" & [Forms]![filter]![CboDevType] & "*" Or [Forms]![filter]![CboDevType] Is Null)=True) AND (([FirstName]=[Forms]![filter]![CboEmp] Or [Forms]![filter]![CboEmp] Is Null)=True) AND (([DeviceStatus]=[Forms]![filter]![CboStat] Or [Forms]![filter]![CboStat] Is Null)=True));

感谢Parfait先生的出色表现。

© www.soinside.com 2019 - 2024. All rights reserved.