2012-04-24 194 views
1

人 Person_Pet 宠物在Access中实现多对多,子窗体,复选框2007

我需要做一个数据输入表单。假设我们有一张名为Person的表格,并在其中包含适当的字段。在我的表格中,我需要允许用户从(一个或多个)复选框中选择代表所有可能的宠物(固定列表项目:狗,ser猫,美洲驼,jackalope,em,,龙,蜘蛛......) 。

对于表单,需要有一个复选框来表示每个可能的选择。如果那个人确实有一只宠物狗,那么该复选框必须是真实的,如果他们没有一只狗,它就需要是假的(我想我说的很明显,因为我试图做为一个子表单在“多对多”,并显示“假”价值的东西。他们可以选择不止一个。

最后,我需要作出新的形式或重用modificiations数据录入等形式

是这个一个子表单?我有一个Person表,Pet表,Person_Pet(id/joining)表。我试图用VBA去做所有这些,但我认为我选择了艰难的方式,但是,还不算太晚改变方向

编辑: 如果我从这开始怎么办?它会导致某些东西给我所有可能的宠物列表,如果p.personid为空,那么复选框不会被选中。如果它不是null,那么它会被检查。这可能吗? (原谅的格式,访问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宠物表中的相应字段.... so dog = chk1,serval = chk2 ... stuff
  3. 做这个vba(并从Form_Current()调用函数并将它传递给我。 ID):

功能update_checkboxes(issueID作为变型) 昏暗查询作为字符串 昏暗RS作为DAO.Recordset 昏暗分贝数据库 集分贝= CurrentDb 暗淡了作为字符串

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的东西是恨我。抱歉。 UM。 issue = person,payer = pet。我知道相应的复选框的东西是不是想法,我将不得不搜索/检查字符串字段,但这显示了我认为我可能最终会使用除非..........的概念。 .........

后续问题:是否有任何严重的时间限制问题/后果/ sumthing来运行这些vba查询每次记录被更改?

btw。仅供参考。希望通过选定的答案来展示可能的答案是因为有时候什么东西不是和事物一样重要。有些地区/县/市不会允许pitbulls。加利福尼亚州的整个州显然不敌雪貂。我确实有一个pitbull。我没有雪貂。我们都希望我们有宠物龙训练。所有这些都在一些地区的禁止宠物列表上,所以......这些东西都需要显示。一个列表框可以做到,但我觉得这有点尴尬。通过明显地列出我所有可能的宠物,我知道哪些人会举起旗帜。尽管最终只有真正重要的是我所拥有的.......仍然。但显然我并没有为人们和宠物做一个可爱的小访问数据库,以及他们可以在哪里生活。

+0

关于你的跟进:当你从一个数据集移动到另一个数据集时,幕后会发生很多事情,这个小小的vbacode并没有什么区别。真正耗时的部分是SQL - 并且扩展性好(即,如果在pet_person中有更多的数据集,则不需要更长的时间) - 并且贯穿整个petlistbox只会是一个问题,如果有数以千计的数据集宠物桌会让你的设计首先出现其他问题;) – Johanness 2012-04-27 22:14:15

+0

另一种想法是:有些人花时间思考你的问题,做出 - 有希望的 - 有价值的贡献,有时帮助你腾出时间免费。你可以在编辑你的问题时表现出他们的尊重,但你第一次没有把握的时候 - 或者甚至更好:把它写在你当地的编辑器中,并且在你拥有它的时候粘贴它......只是一句话 - 没有冒犯 – Johanness 2012-04-27 22:26:09

回答

1

使用VBA,您可以使用以下代码。有两个选项:

  1. 与“天然”访问列表框:这表明你的选择可 高亮线在传统的列表框

    选择多选= 1(单)在列表框属性/所有
    片和修改下面的代码 - > uncvomment注释行 和评论上述代替

  2. 与MSForms.Listbox的那些(选择在Formcreation的ActiveX插件)
    在这里你可以得到你想要的复选框。

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

而这里的代码:

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绑定到该表 - 但我没有尝试过(还)。

1

使用子窗体。在疯狂:)

多个复选框边框你需要一个表:

PersonID 
PetID 

PetID将与列出可能的宠物行源的组合框。 PersonID将是链接的子和主字段。

你不需要任何代码就可以做到这一点。

+0

OH。我懂了。我会让你知道它是怎么回事... – 2012-04-24 21:23:33

+0

这种方法的谜团是,你可能最终会让一个人与同一类宠物有多个关系。如果没关系,那么我会推荐这种方法。我在你的问题中看到的是,你只想陈述“是的 - 我有那个宠物”或“不,我没有它”。这将是Access自acc2007以来支持的多对多关系 - 但大多数专业人士建议不要使用它,因为它在隐藏表上中继,并且只要您想以编程方式访问数据或在非易失性存储器中使用它,访问解决方案变得很难看。 – Johanness 2012-04-25 12:02:05

+0

是的。我很擅长VBA,但我认为访问试图让我的工作“更容易”,但我现在必须在访问的上下文中学习所有这些绑定和子表单的东西,以便做出任何事情。我宁愿从后面进行攻击,但我敢打赌,如果我理解了wysiwyg组件/控件访问提供的内容,那么它最终会节省时间......我觉得我几乎使得它更难以定义我自己的加入id表有一个规范化的数据库,我可以看到所有使用的表...(隐藏的加入表让我感到困惑,当我修改了我的多对多关系) – 2012-04-25 13:53:36