所以我现在一直在研究如何以一种舒适的方式过滤控件上的行源结果,希望你在我解释的时候理解我的意思。我找到了解决方案,一堆解决方案。我更关心的是评估他们的利益和负面因素。
我有一个具体的例子,但我的关注点更为通用。对我而言,这似乎是我的应用程序的支柱,所以我想确保它正确地完成,最好的方式,而不仅仅是“工作”的方式。
基本上,我有渐进式组合框过滤器。第一个框过滤第二个框,然后在单个窗体视图中选择一个记录。这两个组合框位于表单的标题中。
让我们说我有一张桌子加拿大城市。两个组合框可能是,cboProvinceFilter“按省过滤”,cboCitySelect“选择城市”
当我加载表单时,省级过滤器关闭,因此城市列表中填充了一个选择所有城市的行源(SELECT ID,CityName FROM CanadianCities)。但这是一个很大的列表,所以我有第二个组合框来按省份缩小该列表(SELECT ID,ProvinceName FROM CanadianProvinces)。
因此,目标是在cboProvinceFilter.AfterUpdate上使用更改的where子句(“[...] WHERE ProvinceID = [cboProvinceFilter]”)来重新查询cboCitySelect。
问题在于如何改变where子句。理想情况下,上述内容在设计器中可以正常工作,但SQL设计似乎超出了表单的范围,因此cboProvinceFilter不存在。我同意直接引用表格不好的观点。我不想将我的sql与这样的表单结合起来。另外,我想使用导航表单,但也有移动选项,因此单独运行表单并在导航中运行是理想的,绝对引用不能这样做。
将我的重复SQL语句隐藏在代码中感觉设计效果不佳,并且当参数正是出于这个原因时,重复相同的查询并使用稍微不同的过滤是非常糟糕的。
有些人会对此嗤之以鼻,但在VBA中重写Access设计器的功能也感觉很糟糕。如果我构建自己的SQL,执行我自己的查询,并填充我自己的列表,为什么微软会全力投入构建这个生产力辅助工具?过滤并不是数据库管理的一个模糊特征......我觉得必须有一种合理的方法来做这类事情。
此外,弹出窗体是令人讨厌的,所以我不会只是为了获得可靠的绝对引用而制作特定的形式。这绝对感觉像是一个警察。
感觉良好的解决方案,但我没有做过工作......
SQL参数 我认为最明智的做法应该是SQL参数,因为它们的目的是什么? QueryDef将存储其参数的值,我可以根据需要进行更改。但是,我会让查询在requery上自然执行。
因此,我不是编写少量行来执行查询并填充控件,而是设置参数值并在我的控件上调用requery,它具有内置的所有功能。
因此在SQL语句中定义了一些参数,然后尝试在执行Query之前在VBA中设置这些参数的值,但是如果参数不引用实际对象,则JET似乎总是弹出参数,它没有检查我的代码集querydef。
为了实现这一点,似乎我必须手动执行SQL,并解析我自己的记录集,并填充控件。对于我想要提供的每个过滤选项,这感觉就像是过多的重复。
相对引用 我不介意引用表单,只要它是相对路径。不幸的是[Screen]。[ActiveForm]指的是导航形式,而不是实际的,活跃的形式......所以这似乎已经出来了。
现在我想我唯一的选择是手动设置rowsource然后调用控件的requery。这是一种不那么令人反感的选择。可能最好采用当前查询和字符串替换where部分,因此如果查询结构发生更改,我不必更新每个事件。
最后的想法 无论如何,这已经很多了,所以让我知道你的想法。我并不是在寻找代码解决方案,这就是为什么我提供很少甚至没有硬性的例子。我正在寻找一种管理这种过滤的范例,这种过滤不是太严格(绝对引用)或过于重复/轮重新发明(硬编码的sql,执行,控制填充)。
答案 0 :(得分:1)
如果您的Access版本为> = 2007,则可以使用 TempVars Collection 。这是一个立即窗口会话。
' add a TempVar with value
TempVars.which_id = 12
' or do it explicitly with Add method
TempVars.Add "which_id", 12
? TempVars!which_id
12
' asking for the value of non-existent TempVar returns Null
? TempVars!bogus
Null
查询可以引用TempVar来过滤结果集。
SELECT f.*
FROM tblFoo AS f
WHERE f.id=[TempVars]![which_id] OR [TempVars]![which_id] Is Null;
因此,您可以在 cboCitySelect 组合框的行源查询中使用该方法。然后在 cboProvinceFilter 和下一个Requery
cboCitySelect 的After Update事件中指定TempVar值。
对于Access版本< 2007年, TempVars Collection 不可用。在这种情况下,您可以使用自定义VBA函数来保存可在查询中引用的静态值。
SELECT f.*
FROM tblFoo AS f
WHERE f.id=TargetId() OR TargetId() Is Null;
Public Function TargetId(Optional ByVal pValue As Variant) As Variant
Static varReturn As Variant
If IsMissing(pValue) Then
If VarType(varReturn) = vbEmpty Then
varReturn = Null
End If
Else
varReturn = pValue
End If
TargetId = varReturn
End Function