View Full Version : One to Many Issues (I think)
airforceruss 01-25-2010, 01:30 AM Please bear with this question, as I know there is a simple solution, but I haven't jumped into an Access Database for a good year or so and my brain is having trouble figuring something out.
I have two tables (tblMembers and tblCrews). tblMembers list all of the members of an organization and tblCrews has a 4 fields that assigns 4 individual MemberID #'s to a single CrewID in a single row.
Now I'm wanting to display the names for each of the members belonging to a crew in a query but can't figure out how to do so in the query as I can't link the MemberID of the tblMembers table to each of the fields in the tblCrews table.
If this makes sense and anyone has any ideas to help me get past the "Access Developers Block" I'd appreciate it.
GalaxiomAtHome 01-25-2010, 01:43 AM The table structure is not ideal. Use three tables. Your query will be easy this way.
Members: MemberID (PK), MemberName, etc
Crews: CrewID (PK), CrewName
CrewMembers: CrewID (FK), MemberID (FK)
CrewMembers is a join table and allows Members to be in multiple teams and Teams to have any number of Members.
Otherwise you will need to join a separate copy of Members to each Crew field.
airforceruss 01-25-2010, 02:46 AM Alright I now have 3 tables (tblMembers, tblCrews, tblCrewMembers)
tblMembers
----------
MemberID (PK)
FirstName
LastName
PositionID
tblCrews
--------
CrewID (PK)
tblCrewMembers
--------------
CrewMembersID (PK)
CrewID (FK)
MemberID (FK)
As you can see there is only one field in the tblCrews table and acts as just that joining table.
What I'm trying to figure out now is how to display the names of the crew in a single row on a combobox identifying that crew with the last name of all of the members via an expression
pbaldy 01-25-2010, 07:02 AM I think this would work for you:
http://www.mvps.org/access/modules/mdl0004.htm
Air Force Dad
airforceruss 01-25-2010, 02:28 PM Hey Paul -
Thanks for the link. How have you been?
I was looking over it and I'm not so sure I have a 1:M relationship now that I've added the 3rd table in there. If I do (trying to knock the rust off), I'm struggling with getting the Public Function to display correctly. I've added it into a module and am able to call it but can't yield any results. I'm using currently:
Expr1: fConcatChild("tblCrewMembers","CrewID","LastName","Text","1")
pbaldy 01-25-2010, 03:26 PM Hey Russ, I'm doing great; hope you are too! I visited Air Force Daughter in England back in September. She'll be there for another couple of years, unless something changes.
For starters, I think you made the same mistake I made when I first experimented with it. I believe it wants "String", not "Text". Can you post a db with enough sample data in it to test with?
airforceruss 01-25-2010, 10:20 PM That's great. I take it you got to take in a good number of the sights and sounds while you were visiting?
I'm posting up a copy of the DB with some dummy data now.
I've got several questions, whatever you'd had time to look over:
1) Displaying each member of the crew in a drop down in the format "Member1LastName, Member2LastName, etc.)
2) How to break up the fields in the tblMissions Date fields on the Missions form so that the user can input/edit/view the date and time in two separate textboxes but have the value stored in one field in the table
3) Create a query that will display the number of hours since a crew that was assigned to a mission last had an ETATime. In other words, I need to use the most recent ETATime in the tblMissions table for each crew to the present time which will tell me how long it's been since they've completed a mission.
Those are the stumbling blocks I've ran into so far. Any help would, as always, be appreciated.
pbaldy 01-26-2010, 10:37 AM I'll get to these as I have time. Because your needs are a little customized (name in related table) I wrote my own function (I'll let you add error handling):
Public Function PaulConcat(CrewID As Long) As String
Dim strSQL As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb()
strSQL = "SELECT tblCrewMembers.CrewID, tblMembers.LastName " _
& "FROM tblCrewMembers INNER JOIN tblMembers ON tblCrewMembers.MemberID = tblMembers.MemberID " _
& "WHERE tblCrewMembers.CrewID = " & CrewID
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
Do While Not rs.EOF
PaulConcat = PaulConcat & rs!LastName & "; "
rs.MoveNext
Loop
If PaulConcat <> "" Then
PaulConcat = Left(PaulConcat, Len(PaulConcat) - 2)
End If
Set rs = Nothing
Set db = Nothing
End Function
then try this query:
SELECT tblCrews.CrewID, PaulConcat([crewid]) AS CrewNames
FROM tblCrews
pbaldy 01-26-2010, 01:17 PM Regarding number two, here's an example where I have two unbound textbox for date and time, and one hidden bound textbox. After update of the unbound textboxes:
If IsDate(Me.txtOutDate) And IsDate(Me.txtOutTime) Then
Me.OutDateTime = Me.txtOutDate + Me.txtOutTime
Else
Me.OutDateTime = Null
End If
In the current event:
If IsDate(Me.OutDateTime) Then
Me.txtOutDate = DateValue(Me.OutDateTime)
Me.txtOutTime = TimeValue(Me.OutDateTime)
End If
pbaldy 01-26-2010, 01:22 PM For number 3, I don't see a field in tblMissions for CrewID. Is that an oversight, or how would you determine which crew did the mission? If you add that field, a technique like this could be used:
http://www.baldyweb.com/LastValue.htm
pbaldy 01-27-2010, 12:57 PM I just noticed tblSchedule which addresses my question regarding number 3. Presuming each mission can only have one crew, I'd probably just have a field in the mission table for CrewID. If you keep this table, this query returns the last mission date for each crew:
SELECT tblSchedule.CrewID, Max(tblMissions.ETATime) AS LastETATime
FROM tblSchedule INNER JOIN tblMissions ON tblSchedule.MissionID = tblMissions.MissionID
GROUP BY tblSchedule.CrewID
That combined with the technique in the link above should get whatever related info you want.
airforceruss 01-28-2010, 06:31 PM I'll get to these as I have time. Because your needs are a little customized (name in related table) I wrote my own function (I'll let you add error handling):
Public Function PaulConcat(CrewID As Long) As String
Dim strSQL As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb()
strSQL = "SELECT tblCrewMembers.CrewID, tblMembers.LastName " _
& "FROM tblCrewMembers INNER JOIN tblMembers ON tblCrewMembers.MemberID = tblMembers.MemberID " _
& "WHERE tblCrewMembers.CrewID = " & CrewID
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
Do While Not rs.EOF
PaulConcat = PaulConcat & rs!LastName & "; "
rs.MoveNext
Loop
If PaulConcat <> "" Then
PaulConcat = Left(PaulConcat, Len(PaulConcat) - 2)
End If
Set rs = Nothing
Set db = Nothing
End Function
then try this query:
SELECT tblCrews.CrewID, PaulConcat([crewid]) AS CrewNames
FROM tblCrews
Amazing. Problem solved on that one. Thank you very much.
airforceruss 01-28-2010, 06:50 PM Regarding number two, here's an example where I have two unbound textbox for date and time, and one hidden bound textbox. After update of the unbound textboxes:
If IsDate(Me.txtOutDate) And IsDate(Me.txtOutTime) Then
Me.OutDateTime = Me.txtOutDate + Me.txtOutTime
Else
Me.OutDateTime = Null
End If
In the current event:
If IsDate(Me.OutDateTime) Then
Me.txtOutDate = DateValue(Me.OutDateTime)
Me.txtOutTime = TimeValue(Me.OutDateTime)
End If
Problem #2 also amazingly solved. The only way I could get the bound textbox to update however was to use:
Me.txtOutDate = Me.txtOutDate& " " & Me.txtOutTime
Otherwise I got a type mismatch. But, I can't complain as you pushed me 99.99% in the right direction so thank you once again.
pbaldy 01-28-2010, 08:07 PM Glad to help Russ. Post back if number 3 isn't resolved.
|
|