【问题标题】:Using cascading combo boxes in a datasheet subform在数据表子表单中使用级联组合框
【发布时间】:2012-11-12 13:44:54
【问题描述】:

在 Access 2010 中,我有表 TaskAction,它们通过表 ActionTask 具有多对多关系。在Task 的表单中,我想通过ActionTask 联结表为所有与当前任务相关的Actions 放置一个子表单。

这本身,我可以做到。

诀窍在于Action 实际上是四层表的最底层。 每个Action属于一个Goal,每个Goal属于一个Theme,每个Theme属于一个Strategy

我想为Strategy/Theme/Goal/Action 使用级联组合框,而不仅仅是列出所有可用的Actions 的组合框。

这个我也可以。

问题是当我在数据表中使用此技术时,如果我选择给定行,则所选行显示正确的Strategy/Theme/Goal/Action,但在所有其他行中

  • Action 为空白
  • Strategy/Theme/Goal 设置为当前行的值,而不是该行的值

我尝试使用“连续表单”视图而不是“数据表”视图,但结果几乎相同。

我想我知道为什么(我的Form_Current 回调中的Me.StrategyCombo = ... 内容),但我不知道另一种实现方式。

如何让子表单正确显示所有行?


Here's the Access file,但所有相关细节都应该在下面。

Tables:
  Strategy   : (ID, Desc)
  Theme      : (ID, StrategyID, Desc)
  Goal       : (ID, ThemeID, Desc)
  Action     : (ID, GoalID, Desc)
  Task       : (ID, Desc, ...)
  ActionTask : (ActionID, TaskID)

Form Settings:

  [Forms]![Task]![ActionTaskSub]:
    Link Master Fields: ID
    Link Child Fields : TaskID

  [Forms]![Task]![ActionTaskSub].[Form]:
    On Current:
      Private Sub Form_Current()
          ' when the form loads a record, should reverse propegate
          ' action > goal > theme > strategy
          Dim goalID, themeID, strategyID

          ' figure out the goal, theme, and strategy that go with this action
          If (Me.ActionID) Then
            goalID = DLookup("[GoalID]", "Action", "[ID] = " & CStr(Me.ActionID))
            themeID = DLookup("[ThemeID]", "Goal", "[ID] = " & CStr(goalID))
            strategyID = DLookup("[StrategyID]", "Theme", "[ID] = " & CStr(themeID))
          End if

          ' populate the combo boxes and make the appropriate selections
          Me.StrategyCombo = strategyID
          Me.ThemeCombo.Requery
          Me.ThemeCombo = themeID
          Me.GoalCombo.Requery
          Me.GoalCombo = goalID
          Me.ActionCombo.Requery
          Me.ActionCombo = Me.ActionID
      End Sub

  [Forms]![Task]![ActionTaskSub].[Form]![StrategyCombo]:
    Row Source  : SELECT [Strategy].[ID], [Strategy].[Desc] FROM [Strategy];
    After Update:
      Private Sub StrategyCombo_AfterUpdate()
          Me.ThemeCombo = Null
          Me.ThemeCombo.Requery
          Call ThemeCombo_AfterUpdate
      End Sub

  [Forms]![Task]![ActionTaskSub].[Form]![ThemeCombo]:
    Row Source  : SELECT [Theme].[ID], [Theme].[Desc] FROM [Theme] WHERE 
                  [Theme].[StrategyID] = [Forms]![Task]![ActionTaskSub].[Form]![StrategyCombo];
    After Update:
      Private Sub ThemeCombo_AfterUpdate()
          Me.GoalCombo = Null
          Me.GoalCombo.Requery
          Call GoalCombo_AfterUpdate
      End Sub

  [Forms]![Task]![ActionTaskSub].[Form]![GoalCombo]:
    Row Source  : SELECT [Goal].[ID], [Goal].[Desc] FROM [Goal] WHERE 
                  [Goal].[ThemeID] = [Forms]![Task]![ActionTaskSub].[Form]![ThemeCombo];
    After Update:
      Private Sub GoalCombo_AfterUpdate()
          Me.ActionCombo = Null
          Me.ActionCombo.Requery
      End Sub

  [Forms]![Task]![ActionTaskSub].[Form]![ActionCombo]:
    Row Source  : SELECT [Action].[ID], [Action].[Desc] FROM [Action] WHERE 
                  [Action].[GoalID] = [Forms]![Task]![ActionTaskSub].[Form]![GoalCombo];

【问题讨论】:

    标签: forms ms-access vba


    【解决方案1】:

    我解决了数据表中依赖(级联)组合框的问题。 从本质上讲,如果组合框 1 依赖于组合框 2 中的值,它会将当前行中的“行源”应用于数据表中的所有行

    解决方案:

    1 在加载或设计器中,定义行源以包含所有行,以便其后面的数据值始终与行源中的选项匹配(否则显示空白值)

    即:

    Private Sub Form_Load()
        Me.cmbProjects.RowSource = "SELECT [Projects].[ProjectPK],  [Projects].[ProjectName], [Projects].[PI_ID] FROM [Projects]  ORDER BY  [ProjectName] "
    End Sub
    

    2 在从属组合框获取焦点事件中,将行源重新定义为基于前者所依赖的另一个组合框的值。重新查询控件

    Private Sub cmbProjects_GotFocus()
    Me.cmbProjects.RowSource = "SELECT [Projects].[ProjectPK],  [Projects].[ProjectName], [Projects].[PI_ID],  [Projects].[Status] FROM [Projects]  WHERE [PI_ID] = " + CStr(cmbPIs.Value) + " ORDER BY [PI_ID], [ProjectName] "
    cmbProjects.Requery
    End Sub
    

    3 在相关组合框失去焦点事件中,将行源重新定义为不基于前者所依赖的其他组合框的值。

    Private Sub cmbProjects_LostFocus()
    Me.cmbProjects.RowSource = "SELECT [Projects].[ProjectPK],  [Projects].[ProjectName], [Projects].[PI_ID],  [Projects].[Status] FROM [Projects]  ORDER BY [PI_ID], [ProjectName] "
    cmbProjects.Requery
    End Sub
    

    【讨论】:

    • 这非常有效,但是当我专注于 cmbProject 时,另一行中的所有其他 cmbProject 下拉列表都是空白的,直到我在 cmbProject 中选择某些内容然后移至下一个字段。当我移动到下一个字段时,所有其他 cmbProject 都会恢复它们的值。有什么办法可以阻止他们被屏蔽掉吗?
    • 没有。请参阅 LLS 答案。
    【解决方案2】:

    你不能。任何操作都适用于子表单当前记录,但似乎会影响所有控件。有各种变通方法。

    【讨论】:

    【解决方案3】:

    据我所知你不能,但你可以通过创建一个连续的表单来解决它,将你的字段放在表格布局中,然后为每个组合框添加一个文本框(如果字段是 prodID,那么我将文本框命名为txtprodID)。将文本框向右移动到组合框的顶部,但要窄一些,刚好靠近组合列表箭头,然后编写代码来更新文本框。

    【讨论】:

      猜你喜欢
      • 2019-07-26
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多