与多列的查找和关系

Posted

技术标签:

【中文标题】与多列的查找和关系【英文标题】:Lookup and Relationship with multiple columns 【发布时间】:2013-08-21 21:49:10 【问题描述】:

我对 Access 完全陌生,但我已经完成了教程,并且对 Excel 有一些 VBA 经验,所以我不应该绝望。

我还没有进入表单,现在我专注于定义和填充表格,以及定义关系。

我已更改此处示例中的实际表,但上下文和问题仍然存在。

表 1 是食物。除了 autofield 键,它还有两个字段

FoodCat  FoodType  
Fruit    banana    
Fruit    apple     
Fruit    pear     
Meat     lamb
Meat     beef
Meet     Chicken
Vegetable Broccoli

等等……

此表由另一个表在查找和关系设置中使用。 它很容易设置,因此另一个表有一个字段,该字段仅限于包含 FoodCat 字段中项目的条目(尽管它是重复的)。我还可以将下一个字段限制为具有 FoodType 字段的条目,但这给了我所有的选择。

我想做的是,在新表中,将 FoodType 选项限制为具有匹配 FoodCat 选项的条目。

因此,如果在 FoodCat 下的新表中选择的项目是肉类,我只希望 FoodType 选择是羊肉、牛肉或鸡肉。

这甚至可能在表格中吗?我需要使用表单来完成这项工作吗?

【问题讨论】:

我认为表单是一个更好的地方来尝试这个。使用 VBA,您可以更改组合框的 RowSource 属性以限制选择。引用“访问的十诫”:“你永远不能让你的用户直接查看或编辑表格,而只能通过表单”(access.mvps.org/access/tencommandments.htm) 谢谢。我读了这些,并对查找表的邪恶感到非常惊讶。所有的访问培训都热情地支持他们。如何在没有查找表的情况下创建表之间的任何关系? 我已经在下面回答了您的评论。除了这个特殊的问题,我建议你买一本关于 Access 的好书。 【参考方案1】:

回答您的评论:

当您使用“查找”字段时,您会在表之间强制建立新关系。

避免Ten Commandments of Access(特别是:The evils of the lookup fields in tables)中列出的问题的最佳方法是手动创建关系,然后使用它们在表单或报表中创建适当的“查找”控件。

假设您有以下表格:

tblCategories

id | catName
---+-----------
1  | Fruit
2  | Meat
3  | Vegetable

tblFood

id | idCat | foodName
---+-------+-------------
1  | 1     | Apple
2  | 1     | Banana
3  | 2     | Lamb
4  | 2     | Beef
5  | 3     | Broccoli

在这个例子中很明显这两个表之间存在一对多的关系,并且tblFood 中的idCat 字段是一个外键。您可以在“关系”窗口中手动创建此关系。

通过以下查询,您可以正确获取foodNamecatName 字段(构建报告的好方法):

select f.*, c.catName
from tblFood as f
    inner join tblCategories as c on f.idCat = c.id;

这会抛出这样的东西:

id | idCat | foodName | catName
---+-------+----------+------------
1  | 1     | Apple    | Fruit
2  | 1     | Banana   | Fruit
3  | 2     | Lamb     | Meat
4  | 2     | Beef     | Meat
5  | 3     | Broccoli | Vegetable

这是一个很好且有用的查询,您可以在报告中使用...而不需要在报告中使用组合框。

那么:到底如何构建一个控件,例如 ComboBox,它根据 catName 值仅过滤 foodName 值?

首先:创建表单

然后:创建一个组合框并将其放入RowSource 属性中:

select id, catName from tblCategories

将控件设置为具有两列和列宽:0, 10。这将使下拉列表中的id 列“不可见”。一定要知道这个组合框的名称(假设它被命名为comboBox01)。

现在,创建第二个组合框,将 RowSource 属性保留为空,并将列宽设置为 0, 10。还要确保知道第二个组合框的名称(假设它被命名为comboBox02)。

现在让我们让 VBA 执行您需要的操作:在 comboBox01 控件的属性表上,查找 afterUpdate 事件,单击省略号按钮,选择“VBA 代码”并编写以下内容

Sub comboBox01_afterUpdate() ' This is added automatically by the VBA editor
    strSQL = "select id, foodName from tblFood where idCat=" & comboBox01.Value
    comboBox02.rowSource = strSQL
    comboBox02.Requery
End Sub ' This is added automatically by the VBA editor

“查找控件”(没有“查找字段”)在表单中使用时非常有用。它们可以为您的数据库用户(包括您)省去很多麻烦。但我强烈建议您避免直接在表格中创建它们

希望这会有所帮助。

【讨论】:

【参考方案2】:

是的,可以在表格内进行。但是,通过表格更容易,通过表格更实用。您永远不会希望您的用户直接与表交互。

【讨论】:

以上是关于与多列的查找和关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent 关系 - 表的多列引用相同的外键

查找不同单词之间的语义相似性和关系

使用多对多关系还是多列?

在父表和查找表之间创建 Eloquent 关系?

sql中一对多关系的查询结果的多行转换成一行多列

在多列上组合 sql 内部和外部联接