I ended up creating a recursive VBA function kind of like what Ranman suggested. In my case I know the WBS_ID for the lowest level. That's what I plug into the formula. The top level would eventually stop with a blank Parent_WBS, but I decided to stop it sooner. The WBS_ID in the code below is the highest level anyone would want to use. I used this as a formula in my query and it seems to work well. The only thing I don't like is when the top level is reached, each level back down the chain has to assign the string "wbs" to the function over and over again until it gets back to the original call. I tried to figure out a way for the function to return a string that could be added to the previous function call, but I couldn't make it work. I don't think it is a big difference on the system resources. It would just be a little cleaner in my mind.
Anyway, here is the code that worked for me.
Code:
Function FullWBS(ID As Long, Optional wbs As String) As String
Dim rs As DAO.Recordset
Dim stQuery As String
If ID = Empty Then
Exit Function
Else: End If
stQuery = "SELECT WBS.WBS_ID, WBS.WBS_SHORT_NAME, WBS.PARENT_WBS_ID " & _
"FROM WBS " & _
"WHERE (((WBS.WBS_ID)= " & ID & "));"
Set rs = CurrentDb.OpenRecordset(stQuery)
If rs!PARENT_WBS_ID = 839358 Then
Exit Function
Else
ID = rs!PARENT_WBS_ID
End If
If wbs = Empty Then 'The first time through this should be empty
wbs = rs!WBS_SHORT_NAME
Else
wbs = rs!WBS_SHORT_NAME & "." & wbs
End If
Call FullWBS(ID, wbs)
FullWBS = wbs
End Function