1

人Person_Pet Pet

我需要制作一个数据输入表格。假设我们有一个名为 Person 的表,其中包含适当的字段。在我的表单上,我需要允许用户从(一个或多个)复选框中选择代表他们可能拥有的所有可能的宠物(固定的项目列表:狗、薮猫、美洲驼、鹿角羚、鸸鹋、龙、蜘蛛......) .

对于表单,需要有一个复选框来代表每个可能的选择。如果该人确实有一只宠物狗,那么该复选框必须为真,如果他们没有狗,则该复选框必须为假(我想我说的是显而易见的,因为我试图将其作为子表单执行“多对多”和显示“假”值的东西。他们可以选择不止一个。

最终我需要制作一个新表格或重新使用数据输入表格进行修改等。

这是一个子窗体吗?我有一个 Person 表、Pet 表、Person_Pet(id/joining)表。我正在尝试使用 VBA 完成这一切,但我认为我选择了艰难的方式,但是,现在改变方向还为时不晚。

编辑:如果我从这个开始呢?这将导致给我所有可能宠物的列表,如果 p.personid 为空,则不选中该复选框。如果它不为空,则对其进行检查。这可能吗?(请原谅格式,访问 sql 编写器显然不知道选项卡是什么,请原谅 sytanx 错误,因为我必须快速查找和替换表名)

select pet.*, p.personid
from pet pet 
left outer join
(select pi.petID, pi.personid
from    person,
        pet_person pi,
        pet 
where   person.id = pi.personID and
        pet.id = pi.petID) as p
on p.petID = pet.id

编辑:

好的。那里有一个巨大的答案。我也解决了。我还没有看过你的答案,但我会稍微看一下。这是我的答案...(没有子表单,只在主表单上,“人”表单)

  1. 制作复选框......并将它们命名为chk1,chk2,chk3......等等。
  2. 确保它们对应于我的 lil pet 表中的适当字段....所以 dog = chk1, serval = chk2 ... stuff
  3. 执行此 vba(并从 Form_Current() 调用函数并将其传递给 me.id):

Function update_checkboxes(issueID As Variant) Dim query As String Dim rs As DAO.Recordset Dim db As Database Set db = CurrentDb Dim a As String

If Not IsNull(issueID) Then
    query = "SELECT iif(joined.issueid is null, 0, 1) as binval, payer.* " & _
            "FROM payer AS payer LEFT JOIN (select ri.issueid, ri.payerid " & _
                    "from  issue i, payer r, payer_issue ri " & _
                    "where i.id = ri.issueid and r.id = ri.payerid and ri.issueid = " & issueID & _
                    ")  AS joined ON joined.payerid = payer.id;"
Else
    query = "select 0 as binval, payer.* from payer"
End If

Set rs = db.OpenRecordset(query)
rs.MoveFirst

Do While Not rs.EOF
    s = rs.Fields("CorrespondingChkboxNumber")
    Me.Controls("chk" & s).Value = rs.Fields("binval")
    rs.MoveNext
Loop

rs.Close
End Function

是的。复制粘贴代码格式stackoverflow的东西讨厌我。对不起。嗯。问题=人,付款人=宠物。我知道相应的复选框的东西不是主意,我将不得不搜索/检查一个字符串字段,但这显示了我认为我最终可能会使用的概念,除非............ …………

后续问题:每次更改记录时运行这些 vba 查询是否存在严重的时间限制问题/后果/总结?

顺便提一句。供参考。用选定的答案展示可能的答案的愿望是因为有时事物不是什么与事物是什么同样重要。一些地区/县/市不允许比特犬。整个加利福尼亚州显然取缔了雪貂。我确实有一只比特犬。我没有雪貂。我们都只希望我们有宠物龙可以训练。所有这些都在某些地区的禁止宠物清单上,所以......这两个东西都需要展示。一个列表框可以做到这一点,但我觉得它看起来有点尴尬。通过明显列出我所有可能的宠物,我知道哪些会升旗。虽然最后只有我所拥有的才是真正重要的......仍然。但显然我并没有为人和宠物以及他们可以居住的地方制作一个可爱的小访问数据库。

4

2 回答 2

1

使用子表单。疯狂的多个复选框边框:)

你需要一张桌子:

PersonID
PetID

PetID 将是一个组合框,其中包含列出可能宠物的行源。PersonID 将是链接子字段和主字段。

您不需要任何代码来执行此操作。

于 2012-04-24T20:53:17.543 回答
1

使用 VBA,您可以使用以下代码。有两种选择:

  1. 使用“本机”访问列表框:这会将您的选择显示为常规列表框中的突出显示行

    在列表框属性/所有工作表中选择 multiselect=1 (Single)
    并修改以下代码 -> 取消注释行并注释上面的行

  2. 使用 MSForms.Listbox(在 Formcreation 中选择 activeX 插入)
    ,您可以获得所需的复选框。

    选择了 Multiselect:multi 和 ListStyle:option。这里没有点击事件,所以我选择了退出事件。到目前为止我还没有遇到任何问题,但是有条不紊地点击事件会更好。

这是代码:

Option Compare Database
Option Explicit

Dim pPetListBox As MSForms.ListBox

Private Sub FillPetListbox() 
  pPetListBox.Clear
  Dim rst As DAO.Recordset
  Set rst = CurrentDb.OpenRecordset("select * from pet order by id")
  While Not rst.EOF
    pPetListBox.AddItem rst!ID
    pPetListBox.List(pPetListBox.ListCount - 1, 1) = rst!petname
    rst.MoveNext
  Wend
  rst.Close
End Sub

Private Sub Form_Current()
  Dim rst As DAO.Recordset
  Dim indx As Long
  Set rst = CurrentDb.OpenRecordset("select * from person_pet where personid=" & Me.ID)
  For indx = 0 To pPetListBox.ListCount - 1
    rst.FindFirst "petID = " & pPetListBox.Column(0, indx)
'    rst.FindFirst "petID = " & petList.ItemData(indx)
    pPetListBox.Selected(indx) = Not rst.NoMatch
  Next
  rst.Close
End Sub

Private Sub UpdateLinkTable()
  Dim rst As DAO.Recordset
  Dim indx As Long
  Set rst = CurrentDb.OpenRecordset("select * from person_pet where personid=" & Me.ID)
  indx = pPetListBox.ListIndex
  rst.FindFirst "petID = " & pPetListBox.List(indx, 0)
  'rst.FindFirst "petID = " & petList.ItemData(indx)
  If (pPetListBox.Selected(indx) And rst.NoMatch) Then
    rst.AddNew
    rst!personID = Me.ID
    rst!petID = pPetListBox.Column(0, indx)
    rst.Update
  Else
    If ((Not pPetListBox.Selected(indx)) And (Not rst.NoMatch)) Then
      rst.Delete
    End If
  End If
  rst.Close
End Sub

Private Sub Form_Load()
  Set pPetListBox = Me.msfPetListBox.Object
  FillPetListbox
End Sub

Private Sub msfPetListBox_Exit(Cancel As Integer)
'Private Sub petList_Click()
  UpdateLinkTable
End Sub

如果您使用本机访问列表框,则不必以编程方式加载列表框内容 (FillPetListBox)。相反,您可以将 rowsource-property 设置为 pet-table。我认为甚至可以将 MSForms.listbox 绑定到该表 - 但我还没有尝试过(还)。

于 2012-04-25T15:59:21.057 回答