在数据表或连续表单视图中的表单上,我们如何将第二个组合框中的可能值基于第一个组合框中选择的值?

Posted

技术标签:

【中文标题】在数据表或连续表单视图中的表单上,我们如何将第二个组合框中的可能值基于第一个组合框中选择的值?【英文标题】:On a form in a datasheet or continuous forms view how do we base the possible values in a second combobox on the value selected in a first combobox? 【发布时间】:2020-11-02 15:24:32 【问题描述】:

如果我们使用列表框、列表框和组合框的某种组合,甚至是我们的第二个控件(组合框或列表框)所基于的第一个控件(文本框、复选框等)的另一种控件类型,这个问题同样适用用户可以从中选择的可能值。

这个问题有两个部分。

首先,第二个组合框的可能值(用户可以从中选择)基于先前通过第一个组合框选择的值。

在解决了这个问题之后,第二个问题就出现了。在显示的数据表(或连续表单)中的多条记录中,第二个组合框将清除第一个组合框的最后选择所排除的值。

我回答我自己的问题,解决问题的两个部分......

编辑 01:添加问题的第一和第二部分。

编辑 02:Mods 注释。这个问题不可能更集中。它表达了一个单一的焦点问题。如果有什么问题可以更改为更笼统,请将“组合框”换成“控制”。然而,这是不可取的:组合框是更常见的场景;并在答案正文中解释了一般适用性..

编辑 03:模组注意事项 ...

只是为了强调为什么问题的重点应该是合理的。网上存在附近的注意力不集中问题。在O'Reilly > Limit the Items in One Combo Box Based on the Selected Item in Another。

但这仅适用于您在主表单和子表单上有一个组合的情况(该解决方案也可以应用于标准“表单视图”中的一个表单上的两个组合)。实际上,O'Reilly 页面警告说,在更加集中的情况下“在连续表单的详细信息部分使用相关的组合框”,这“可能导致问题”,暗示这些是无法解决的问题。 (如果表单是数据表视图,这也是同样的问题)。

那个重点问题,我的问题引用的具体问题,也在堆栈溢出时反复提出。例如

Using cascading combo boxes in a datasheet subform Change control source only selected combo box in continous form Dependent Combobox in a Datasheet in Access?

但这些职位中的每一个都不是我试图克服的理想形式。第一个和第二个不是问题的形式(可以说,即使有问号,第三个也不是)。并且所有这三个都没有捕获(在“问题”的文本中)该问题同样适用于数据表视图中的表单和连续视图(它们选择一个视图而不是另一个视图)。这样一来,他们就错误地过于专注了。

此外,这些帖子中的每一个都有选择的答案,这些答案错误地断言这个问题没有解决方案,有时还含糊地暗示了解决方法。我的回答提供了一个详细的解决方案,这在 *** 上通常被认为无法解决。

【问题讨论】:

我认为它已关闭,因为它作为编程问题不容易回答(请参阅on-topic)。我不使用 ms-acess,所以这只是一个猜测,但也许如果你包含了你已经编写的代码并指出了究竟是什么不起作用,那么问题就不会被关闭。 我已经完成了您在我的原始帖子中建议的所有内容。在我的问题正文中,我指出了究竟什么不起作用(并且确实起作用)。我在我的答案中详细说明了哪些内容不起作用(并且确实起作用)。在我的回答中,我还提供了解决问题的 code。除了 ms-access 环境中所需的所有内容(例如设置控件的属性)。所以你对版主想法的猜测是不可信的。 嗯,是的,我没有看到答案(在审核队列中不可见);无论如何,不​​必阅读答案即可理解问题 对。不必阅读答案即可理解问题。这就是为什么我像我一样提出这个问题(以一种最能专注的方式表达一个非常具体问题的问题;这显然是一个编程 向任何熟悉 MS Access 的人提问)。在任何情况下,感谢任何提出问题的人。 【参考方案1】:

概述

一般来说,这是通过让第二个组合框基于引用第一个组合框的参数查询来实现的。

但是在你完成之后,问题中相对困难的部分就出现了。在显示的数据表(或连续表格)中的多条记录中,第二个组合框将清除第一个组合框的最后选择所排除的值。

通过在该组合框的 Enter 事件期间将第二个组合框的行源临时更改为“选择相关”数据集(根据第一个中选择的值限制第二个组合框中的可能值)来解决该问题。然后在第二个组合框的 Exit 事件中,RowSource 恢复“显示相关”数据集(不会根据第一个组合框中选择的值限制第二个组合框中的可能值)。

详情

我们的例子

对于除表之外的所有对象,我将使用 Reddick 的 RVBA 命名约定。具体来自Host Application and Component Extensions Tags > Access Objects。对于表,我不会有任何“匈牙利”前缀(这只是我个人的怪癖)。

在我们的示例中,我们将有一个 frmCashInflow(表单),显示为数据表,它(显然足够)跟踪企业的现金流入。

我们的第一个组合框将是 cboCashInflowCategory。 我们的第二个组合框是cboCashInflowSubcategory,它将根据第一个组合框中选择的值来限制其可能的值。

相关查找数据如下:

CashInflowCategory(表格)

| CashInflowCategoryID | CashInflowCategoryName                                |
| -------------------- | ----------------------------------------------------- |
| 1                    | Sales                                                 |
| 2                    | Bank Interest Received                                |
| 3                    | Refunds from Suppliers                                |
| 4                    | Property, Plant, and Equipment - Asset Disposal Sales |
| 5                    | Intangible Assets - Asset Disposal Sales              |
| 6                    | ATO Refunds Received                                  |
| 7                    | Contributions from Owner                              |

CashInflowSubCategory(表格)

| CashInflowSubcategoryID | CashInflowSubCategoryName              |
| ----------------------- | -------------------------------------- |
| 1                       | Retained-copyright-software-copy-sales |
| 2                       | Services                               |
| 3                       | Notice of Assessment, Business Portion |
| 4                       | Business Activity Statement            |

接下来我们有一个表格,表示属于特定类别的子类别。为了完整示例,我们将允许某些类别没有任何子类别。

CashInflowCategorySubcategory(表格)

| CashInflowCategorySubcategoryID | CashInflowCategoryID                                  | CashInflowSubcategoryID                |
| ------------------------------- | ----------------------------------------------------- | -------------------------------------- |
| 1                               | Sales                                                 | Retained-copyright-software-copy-sales |
| 2                               | Sales                                                 | Services                               |
| 3                               | Bank Interest Received                                |                                        |
| 4                               | Refunds from Suppliers                                |                                        |
| 5                               | Property, Plant, and Equipment - Asset Disposal Sales |                                        |
| 6                               | Intangible Assets - Asset Disposal Sales              |                                        |
| 7                               | ATO Refunds Received                                  | Notice of Assessment, Business Portion |
| 8                               | ATO Refunds Received                                  | Business Activity Statement            |
| 9                               | Contributions from Owner                              |                                        |

此表的一些方面:

CashInflowCategoryIDCashInflowSubcategoryID 字段实际上存储数字。在表格的设计视图中,在 [查找] 选项卡上设置了“组合框”的 Display Control,行源分别为 CashInflowCategoryCashInflowSubCategory。 [查找] 选项卡上的其他值可根据需要适当/设置。最终结果是,在上表中,我们看到的是用户友好的 ID 名称(如上),而不是原始数字 ID。

同样在表格设计视图中,我们创建了一个名为 idxCashInflowCategorySubcategory 的索引,包括两个字段 CashInflowCategorySubcategoryIDCashInflowSubcategoryID 。对于此索引,“忽略 Nulls”设置为 No。Unique 设置为“Yes”。创建此索引(并添加单个字段主键)而不是将主键设置为同时包含 CashInflowCategorySubcategoryIDCashInflowSubcategoryID 以允许某些类别没有子类别。这是一个常见但不是必需的要求 - 取决于业务规则。

在关系图中,引用完整性设置在CashInflow(表)和:

CashInflowCategorySubcategory(表格),通过CashInflowCategorySubcategoryIDCashInflowSubcategoryID。也就是说,而不是 CashInflowCategory(表格)和CashInflowSubCategory(表格)分开。

这是为了强制在CashInflow(表)中不能选择与CashInflowCategorySubcategory(表)所表示的类别不相关的子类别。

在关系图中设置了参照完整性:

CashInflowCategorySubcategory(表格)和CashInflowCategory(表格);和之间 CashInflowCategorySubcategory(表格)和CashInflowSubcategory(表格)

也就是说,CashInflowCategorySubcategory 表表达了CashInflowCategory(表)和CashInflowSubcategory(表)之间的多对多关系。

程序

    我们有上面的表格。我们将frmCashflow 绑定到CashInflow(表),即添加我们事务的表。

    frmCashflow 添加cboCashInflowCategory

      控制源:CashInflowCategoryID 行来源:CashInflowCategory 行源类型:表/查询 绑定列:1 限制列表:是 列数:2 列宽:0cm;1cm [我们隐藏了 ID,因为这是数字,对用户不友好] 列表宽度:11 厘米 [显示我们用户友好的类别名称的一些慷慨值]

    在按示例查询 (QBE) 网格中创建参数查询 qprmCashInflowSubcategory,以生成如下 SQL。

    SELECT CashInflowSubcategory.*
    FROM CashInflowSubcategory INNER JOIN CashInflowCategorySubcategory ON CashInflowSubcategory.CashInflowSubcategoryID = CashInflowCategorySubcategory.CashInflowSubcategoryID
    WHERE CashInflowCategorySubcategory.CashInflowCategoryID=[Forms]![frmCashbook]![sbctCashInflow].[Form]![cboCashInflowCategory];
    

    请注意,表单上的组合框cboCashInflowCategory 被引用。这就是我们的第二个组合框cboCashInflowSubcategory将其值限制为第一个组合框cboCashInflowCategory所选择的值的原因。

    frmCashflow 添加cboCashInflowSubcategory

      控制源:CashInflowSubcategoryID 行来源:qprmCashInflowSubcategory[临时设置,演示问题] 行源类型:表/查询 绑定列:1 限制列表:是 [尝试设置为“否”会导致各种冲突] 列数:2 列宽:0cm;1cm [我们隐藏了 ID,因为这是数字,对用户不友好] 列表宽度:8 厘米 [显示我们用户友好的类别名称的一些慷慨值]

    将以下内容添加到cboCashInflowSubcategoryOn Enter 事件中(在您可能会尝试执行重新查询的几个可能事件中)。

    Private Sub cboCashInflowCategory_AfterUpdate()
      Me.cboCashInflowSubcategory.Requery
    End Sub
    

打开frmCashflow(在数据表或连续表单视图中),从cboCashInflowCategory 中选择一个“过滤”值。即“Sales”或“ATO Refunds Received”。移动到cboCashInflowSubcategory 并观察值已成功过滤。例如。如果在cboCashInflowCategory 中您选择了“ATO Refunds Received”,那么在cboCashInflowSubcategory 中可用的选项只有“Notice of Assessment, Business Partion”和“Business Activity Statement”(我们看不到“Retained-copyright-software-复制销售”或“服务”)。

但是,您还会看到一个新问题。在整个数据表中,cboCashInflowSubcategory 中显示的唯一值将仅限于 cboCashInflowCategory 中最后选择的值。例如。你会得到...

| Date       | Category                                              | Subcategory                            | Amount (Inc. any GST) |
| :--------- | ----------------------------------------------------- | -------------------------------------- | --------------------- |
| 2020-07-28 | ATO Refunds Received                                  | Notice of Assessment, Business Portion | $70.00                |
| 2020-07-29 | ATO Refunds Received                                  | Business Activity Statement            | $2,000.00             |
| 2020-09-19 | Intangible Assets - Asset Disposal Sales              |                                        | $500.00               |
| 2021-01-26 | Property, Plant, and Equipment - Asset Disposal Sales |                                        | $100.00               |
| 2021-03-11 | Sales                                                 |                                        | $3,000.00             |
| 2021-04-17 | Sales                                                 |                                        | $1,000.00             |

.... 或者,如果最后在 cboCashInflowCategory 中选择了“销售”...

| Date       | Category                                              | Subcategory                            | Amount (Inc. any GST) |
| ---------- | ----------------------------------------------------- | -------------------------------------- | --------------------- |
| 2020-07-28 | ATO Refunds Received                                  |                                        | $70.00                |
| 2020-07-29 | ATO Refunds Received                                  |                                        | $2,000.00             |
| 2020-09-19 | Intangible Assets - Asset Disposal Sales              |                                        | $500.00               |
| 2021-01-26 | Property, Plant, and Equipment - Asset Disposal Sales |                                        | $100.00               |
| 2021-03-11 | Sales                                                 | Retained-copyright-software-copy-sales | $3,000.00             |
| 2021-04-17 | Sales                                                 | Services                               | $1,000.00             |

...而我们想要的是显示所有子类别...

| Date       | Category                                              | Subcategory                            | Amount (Inc. any GST) |
| ---------- | ----------------------------------------------------- | -------------------------------------- | --------------------- |
| 2020-07-28 | ATO Refunds Received                                  | Notice of Assessment, Business Portion | $70.00                |
| 2020-07-29 | ATO Refunds Received                                  | Business Activity Statement            | $2,000.00             |
| 2020-09-19 | Intangible Assets - Asset Disposal Sales              |                                        | $500.00               |
| 2021-01-26 | Property, Plant, and Equipment - Asset Disposal Sales |                                        | $100.00               |
| 2021-03-11 | Sales                                                 | Retained-copyright-software-copy-sales | $3,000.00             |
| 2021-04-17 | Sales                                                 | Services                               | $1,000.00             |

为了给我们想要的东西,既要根据cboCashInflowCategory 中选择的值来限制cboCashInflowSubcategory 的可能值,又要像上面那样显示所有选择的cboCashInflowSubcategory 值,我们执行以下操作...

    撤消上一步。即删除cboCashInflowSubcategoryOn Enter代码和事件。

    cboCashInflowSubcategory 的行源设置为CashInflowSubcategory(表)。这将是我们的“显示相关”数据集。

    暂时将cboCashInflowSubcategory的行源设置为“选择相关”数据集,然后恢复“显示相关”数据集。添加以下事件代码(验证它在组合框的属性表中正确连接)

    Private Sub cboCashInflowSubcategory_Enter()
      ' Temporarily set a "selection relevant" dataset
      Me.cboCashInflowSubcategory.RowSource = "qprmCashInflowSubcategory"
      Me.cboCashInflowSubcategory.Requery
      Me.cboCashInflowSubcategory.Dropdown ' Optional
    End Sub
    
    Private Sub cboCashInflowSubcategory_Exit(Cancel As Integer)
      ' Restore the "display relevant" relevant dataset
      Me.cboCashInflowSubcategory.RowSource = "CashInflowSubcategory"
      Me.cboCashInflowSubcategory.Requery
    End Sub
    

现在一切都应该在 UI 中按需要无缝运行。

编辑:添加了“唯一设置为“是”。为idxCashInflowCategorySubcategory

【讨论】:

以上是关于在数据表或连续表单视图中的表单上,我们如何将第二个组合框中的可能值基于第一个组合框中选择的值?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 表单从另一个视图获取数据

在 C# 中为表单创建保存按钮

使用 CBV 在 Django 中的一个视图/模板中的两个模型表单

如何将第二个表格视图的值与第一个表格视图的单击行的关系分开?

将第二个参数从视图中的模型传递给 AJAX 函数

第一个或第二个输入表单需要