【问题标题】:Query holds on to old criteria & Subform won't refresh查询保留旧条件且子表单不会刷新
【发布时间】:2020-05-18 16:39:30
【问题描述】:

我目前正在从头开始重新设计我公司的 access 数据库,之前没有经验,因为它的结构的最后一次编辑是在 2006 年进行的,它基本上是一个包含 20 万条记录的列表,真是太慢了。 (当前具有工作功能的测试已经显示出显着的改进,耶!)

我尝试创建一个显示查询结果的子表单,但查询本身依赖于多选。该查询作用于客户 ID,并根据所选客户返回结果。 (这行得通)

我一直在寻找解决方案,但是,我就是不知道该怎么做。 我正在处理的问题是双重的,我怀疑是相关的,但首先是一点上下文。

首先,子表单只是拒绝视觉更新。虽然查询保留了所需的结果,但子表单根本没有更新,我尝试过刷新,docmd.requery,你可以命名它,唯一有效的基本上是“重新附加”源。无法从“表面”访问任何设法刷新显示结果的方式。

其次,查询似乎“保留”了之前选择的任何客户端。尽管它可以从所有客户(我将其写为“没有选择意味着一切”)到特定客户,但在选择之间,它会保留先前选择的标准,并将它们向前推进。

'Dashboard' 是嵌套子表单 TabGeneralSubform 的表单,qryTetraGeneral 是用作子表单源的查询。 MultiCustomer 是多选表单。

Sub ListAll_Click() [access vba]


Set MyDB = CurrentDb
flgSelectAll = 0

Set qdef = MyDB.QueryDefs("qryTetraGeneral")

'strSQL is based on the SQL conversion of the SelectClientAll query
'the final AND clause will be appended by strWhere which is based on the MultiList Selection
'If there is no selection the query will default to All active Subs

 strSQL = "SELECT [EQ-TETRA_ISSI].ISSI,[EQ-TETRA_TEI].TEI, [EQ-TETRA_ISSI].Active," & _
    " [EQ-TETRA_TEI].Activation, Client_Table.[Customer Name], Client_Table.[Customer ID], [EQ-TETRA_REQFUL].ReqType, SERVICEREQUEST_TABLE.REQNUM," & _
    " SERVICEREQUEST_TABLE.REQDATE, SERVICEREQUEST_TABLE.RESPUSER" & _
    " FROM ((Client_Table INNER JOIN [EQ-TETRA_ISSI] ON Client_Table.[External Customer Index] = [EQ-TETRA_ISSI].[Customer Index])" & _
    " INNER JOIN SERVICEREQUEST_TABLE ON Client_Table.[External Customer Index] = SERVICEREQUEST_TABLE.Index) INNER JOIN ([EQ-TETRA_TEI]" & _
    " INNER JOIN [EQ-TETRA_REQFUL] ON [EQ-TETRA_TEI].TEI = [EQ-TETRA_REQFUL].TEI) ON (SERVICEREQUEST_TABLE.REQNUM = [EQ-TETRA_REQFUL].Reqnum)" & _
    " AND ([EQ-TETRA_ISSI].ISSI = [EQ-TETRA_REQFUL].ISSI)" & _
    " WHERE ((([EQ-TETRA_TEI].TEI)=[EQ-TETRA_REQFUL].[TEI]) AND (([EQ-TETRA_ISSI].Active)=True) AND (([EQ-TETRA_TEI].Activation)=True) AND ("

'extracts selection from list and creates SQL line to be added to strSQL

 For i = 0 To MultiCustomer.ListCount - 1
    If MultiCustomer.Selected(i) Then
        flgSelectAll = flgSelectAll + 1
        strIN = strIN & "([EQ-TETRA_ISSI].[Customer Index]=" & MultiCustomer.Column(0, i) & ")" & " OR "
    End If
 Next

 If flgSelectAll = 0 Then
    strSQL = "SELECT [EQ-TETRA_ISSI].ISSI,[EQ-TETRA_TEI].TEI, [EQ-TETRA_ISSI].Active," & _
    " [EQ-TETRA_TEI].Activation, Client_Table.[Customer Name], Client_Table.[Customer ID], [EQ-TETRA_REQFUL].ReqType, SERVICEREQUEST_TABLE.REQNUM," & _
    " SERVICEREQUEST_TABLE.REQDATE, SERVICEREQUEST_TABLE.RESPUSER" & _
    " FROM ((Client_Table INNER JOIN [EQ-TETRA_ISSI] ON Client_Table.[External Customer Index] = [EQ-TETRA_ISSI].[Customer Index])" & _
    " INNER JOIN SERVICEREQUEST_TABLE ON Client_Table.[External Customer Index] = SERVICEREQUEST_TABLE.Index) INNER JOIN ([EQ-TETRA_TEI]" & _
    " INNER JOIN [EQ-TETRA_REQFUL] ON [EQ-TETRA_TEI].TEI = [EQ-TETRA_REQFUL].TEI) ON (SERVICEREQUEST_TABLE.REQNUM = [EQ-TETRA_REQFUL].Reqnum)" & _
    " AND ([EQ-TETRA_ISSI].ISSI = [EQ-TETRA_REQFUL].ISSI)" & _
    " WHERE ((([EQ-TETRA_TEI].TEI)=[EQ-TETRA_REQFUL].[TEI]) AND (([EQ-TETRA_ISSI].Active)=True) AND (([EQ-TETRA_TEI].Activation)=True)) ORDER BY [EQ-TETRA_ISSI].ISSI;"
Else
    strWhere = Left(strIN, Len(strIN) - 3) & ")) ORDER BY [EQ-TETRA_ISSI].ISSI;"
    strSQL = strSQL + strWhere
End If

qdef.SQL = strSQL
Call CallRefreshForm([Forms]![Dashboard])

For Each ListObject In MultiCustomer.ItemsSelected
    MultiCustomer.Selected(ListObject) = False
Next ListObject

现在,诚然,代码与我的前辈留下的代码有些拼凑,SQL 语句看起来很乱,但是,它可以工作并根据标准显示所需的结果,目前,这已经足够好了为了我。当我知道所有需要的功能都正常工作时,我可能会尝试将其缩小。

【问题讨论】:

  • 检查Debug.Print strSQL 在您做qdef.SQL = strSQL 时向您显示的内容是您根据所选客户指数所期望的吗?如果你做DoCmd.OpenQuery "qryTetraGeneral",它会返回正确的数据吗?
  • HansUp ,SQL 字符串是我所期望的,只是它似乎继承了之前执行 SQL 语句的条件。即您寻找客户 A,然后,您选择不同的客户 B,执行 VBA 代码,但同时显示 A 和 B。我的前任通过基本上删除查询然后使用 CreateQueryDef 来“解决”这个问题。但是,这在我的用例中引起了一些烦人的错误,我认为可能有一种更优雅的方式来做到这一点。

标签: sql vba ms-access


【解决方案1】:

有几种方法可以简化这一过程。首先,当你基于列表框构建SQL时,不要大量使用IN/OR,而是使用一次IN(我这里有点空编码,请见谅)

For i = 0 To MultiCustomer.ListCount - 1
    If MultiCustomer.Selected(i) Then
        strSQL = strSQL & MultiCustomer.Column(0, i) & "," 
    End If
Next i
If Right(strSQL,1)="," Then strSQL=Left(strSQL,Len(strSQL)-1)
If Len(strSQL)>0 Then
    strSQL="SELECT [EQ-TETRA_ISSI].ISSI,[EQ-TETRA_TEI].TEI, [EQ-TETRA_ISSI].Active," & _
    " [EQ-TETRA_TEI].Activation, Client_Table.[Customer Name], Client_Table.[Customer ID], [EQ-TETRA_REQFUL].ReqType, SERVICEREQUEST_TABLE.REQNUM," & _
    " SERVICEREQUEST_TABLE.REQDATE, SERVICEREQUEST_TABLE.RESPUSER" & _
    " FROM ((Client_Table INNER JOIN [EQ-TETRA_ISSI] ON Client_Table.[External Customer Index] = [EQ-TETRA_ISSI].[Customer Index])" & _
    " INNER JOIN SERVICEREQUEST_TABLE ON Client_Table.[External Customer Index] = SERVICEREQUEST_TABLE.Index) INNER JOIN ([EQ-TETRA_TEI]" & _
    " INNER JOIN [EQ-TETRA_REQFUL] ON [EQ-TETRA_TEI].TEI = [EQ-TETRA_REQFUL].TEI) ON (SERVICEREQUEST_TABLE.REQNUM = [EQ-TETRA_REQFUL].Reqnum)" & _
    " AND ([EQ-TETRA_ISSI].ISSI = [EQ-TETRA_REQFUL].ISSI)" & _
    " WHERE [EQ-TETRA_TEI].TEI=[EQ-TETRA_REQFUL].[TEI] " _
    & " AND [EQ-TETRA_ISSI].Active=True " _
    & " AND [EQ-TETRA_TEI].Activation=True " _
    & " AND [EQ-TETRA_ISSI].[Customer Index] IN (" & strSQL & ")
Else
    strSQL="SELECT [EQ-TETRA_ISSI].ISSI,[EQ-TETRA_TEI].TEI, [EQ-TETRA_ISSI].Active," & _
    " [EQ-TETRA_TEI].Activation, Client_Table.[Customer Name], Client_Table.[Customer ID], [EQ-TETRA_REQFUL].ReqType, SERVICEREQUEST_TABLE.REQNUM," & _
    " SERVICEREQUEST_TABLE.REQDATE, SERVICEREQUEST_TABLE.RESPUSER" & _
    " FROM ((Client_Table INNER JOIN [EQ-TETRA_ISSI] ON Client_Table.[External Customer Index] = [EQ-TETRA_ISSI].[Customer Index])" & _
    " INNER JOIN SERVICEREQUEST_TABLE ON Client_Table.[External Customer Index] = SERVICEREQUEST_TABLE.Index) INNER JOIN ([EQ-TETRA_TEI]" & _
    " INNER JOIN [EQ-TETRA_REQFUL] ON [EQ-TETRA_TEI].TEI = [EQ-TETRA_REQFUL].TEI) ON (SERVICEREQUEST_TABLE.REQNUM = [EQ-TETRA_REQFUL].Reqnum)" & _
    " AND ([EQ-TETRA_ISSI].ISSI = [EQ-TETRA_REQFUL].ISSI)" & _
    " WHERE [EQ-TETRA_TEI].TEI=[EQ-TETRA_REQFUL].[TEI] " _
    & " AND [EQ-TETRA_ISSI].Active=True " _
    & " AND [EQ-TETRA_TEI].Activation=True "
End If
strSQL=strSQL & " ORDER BY [EQ-TETRA_ISSI].ISSI;"

我也不相信您需要在 WHERE 子句中包含 [EQ-TETRA_TEI].TEI=[EQ-TETRA_REQFUL].[TEI],因为您已经在使用它将两个表连接在一起。

问候,

【讨论】:

  • 感谢您的回复。我会看看你的精简建议。我最初尝试使用 in ('@','@'),但我遇到了标准不匹配错误,我想是因为它将 IN 的参数视为字符串,而我的索引是数字,以我的方式使用'OR' ,似乎已经解决了这个问题。
猜你喜欢
  • 2019-03-16
  • 2010-11-04
  • 2011-06-29
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多