2012-04-24 191 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