Too MANY entities? Can't create a report that works.

T

Tim Ferguson

Let me just get my head round where we are at the moment, and then do
the code for putting in the records.

Okay: this should work. Put this code at the bottom of your module, again
below the last End Sub line:-

' CODE BEGINS HERE
'
' Read the DailySessions table and de-normalise it to
' get the weekly schedule for each resident
'
Public Sub FillTempTable(NewTableName As String)

' variables as usual
Dim db As Database ' currentdb
Dim rsDS As Recordset ' old DailySessions
Dim rsTT As Recordset ' new TempTable
Dim strSQL As String

' start as usual
Set db = CurrentDb()

' we need all the session allocations in order of resident
' and then by time of week
' Thinking about it, this could just be a querydef, but let's
' keep going for now
strSQL = "SELECT ds.fldDS_ResidentID, " & vbNewLine & _
"ds.fldDS_SessionTime, " & vbNewLine & _
"ds.fldDS_WorksiteID " & vbNewLine & _
"FROM tblDailySessions AS ds " & vbNewLine & _
" LEFT JOIN tblSessionLookup AS sl " & vbNewLine & _
" ON ds.fldDS_SessionTime = " & vbNewLine & _
" sl.fldSessionLookup " & vbNewLine & _
"ORDER BY ds.fldDS_ResidentID, " & vbNewLine & _
" sl.fldSessionSortNo; "

' this is another information window!
MsgBox strSQL

' get the recordset
Set rsDS = db.OpenRecordset(strSQL, dbOpenSnapshot, dbForwardOnly)

' open the new table
strSQL = "SELECT * FROM " & NewTableName & " WHERE FALSE;"
Set rsTT = db.OpenRecordset(strSQL, dbOpenDynaset)

' now go round each resident: outer loop
Do While Not rsDS.EOF
' create a new temp record and mark it with the resident
rsTT.AddNew
rsTT!fldResidentID = rsDS!fldDS_ResidentID

' go round each timeslot and put it in
' complex exit strategy needs to be done in order
Do While True
' end of input recordset: quit now
If rsDS.EOF Then Exit Do
' it's a different resident: finished with this temp record
If rsDS!fldDS_ResidentID <> rsTT!fldResidentID Then Exit Do

' okay, copy the worksite to the correct column
rsTT.Fields(rsDS!fldDS_SessionTime) = rsDS!fldDS_WorksiteID

' move to next daily session record
rsDS.MoveNext

Loop

' we have to save the temp record
rsTT.Update

' and go round again: we'll drop out of the top of the
' loop if that was the last resident.
Loop

rsTT.Close
rsDS.Close

' finished
End Sub

' *** CODE ENDS HERE

You call it by editing the bottom of the TryThis procedure, just below the
line you added last time. Look down the Public Sub TryThis code until you
get to the End If; and make rest of it look like this:

' Call a proc to create the new table
MakeTempTable c_strTempTable

' Call a proc to put in the records
FillTempTable c_strTempTable

End Sub


Incidentally, from your last post you seem to have a stray line in there:
if you see these here, they should be deleted:

'okay, run the command
db.Execute strSQL, dbFailOnError


Remember about those fingers this time!

All the best


Tim F
 
T

Tim Ferguson

Let me just get my head round where we are at the moment, and then do
the code for putting in the records.

Okay: this should work. Put this code at the bottom of your module, again
below the last End Sub line:-

' CODE BEGINS HERE
'
' Read the DailySessions table and de-normalise it to
' get the weekly schedule for each resident
'
Public Sub FillTempTable(NewTableName As String)

' variables as usual
Dim db As Database ' currentdb
Dim rsDS As Recordset ' old DailySessions
Dim rsTT As Recordset ' new TempTable
Dim strSQL As String

' start as usual
Set db = CurrentDb()

' we need all the session allocations in order of resident
' and then by time of week
' Thinking about it, this could just be a querydef, but let's
' keep going for now
strSQL = "SELECT ds.fldDS_ResidentID, " & vbNewLine & _
"ds.fldDS_SessionTime, " & vbNewLine & _
"ds.fldDS_WorksiteID " & vbNewLine & _
"FROM tblDailySessions AS ds " & vbNewLine & _
" LEFT JOIN tblSessionLookup AS sl " & vbNewLine & _
" ON ds.fldDS_SessionTime = " & vbNewLine & _
" sl.fldSessionLookup " & vbNewLine & _
"ORDER BY ds.fldDS_ResidentID, " & vbNewLine & _
" sl.fldSessionSortNo; "

' this is another information window!
MsgBox strSQL

' get the recordset
Set rsDS = db.OpenRecordset(strSQL, dbOpenSnapshot, dbForwardOnly)

' open the new table
strSQL = "SELECT * FROM " & NewTableName & " WHERE FALSE;"
Set rsTT = db.OpenRecordset(strSQL, dbOpenDynaset)

' now go round each resident: outer loop
Do While Not rsDS.EOF
' create a new temp record and mark it with the resident
rsTT.AddNew
rsTT!fldResidentID = rsDS!fldDS_ResidentID

' go round each timeslot and put it in
' complex exit strategy needs to be done in order
Do While True
' end of input recordset: quit now
If rsDS.EOF Then Exit Do
' it's a different resident: finished with this temp record
If rsDS!fldDS_ResidentID <> rsTT!fldResidentID Then Exit Do

' okay, copy the worksite to the correct column
rsTT.Fields(rsDS!fldDS_SessionTime) = rsDS!fldDS_WorksiteID

' move to next daily session record
rsDS.MoveNext

Loop

' we have to save the temp record
rsTT.Update

' and go round again: we'll drop out of the top of the
' loop if that was the last resident.
Loop

rsTT.Close
rsDS.Close

' finished
End Sub

' *** CODE ENDS HERE

You call it by editing the bottom of the TryThis procedure, just below the
line you added last time. Look down the Public Sub TryThis code until you
get to the End If; and make rest of it look like this:

' Call a proc to create the new table
MakeTempTable c_strTempTable

' Call a proc to put in the records
FillTempTable c_strTempTable

End Sub


Incidentally, from your last post you seem to have a stray line in there:
if you see these here, they should be deleted:

'okay, run the command
db.Execute strSQL, dbFailOnError


Remember about those fingers this time!

All the best


Tim F
 
M

Marcia

Well... we have the table and the column headings are properly sorted
by session! BUT... there's no data in it. I received no new
messages while running the procedure (just the "DROP TABLE" and
"CREATE TABLE" messages).

I should tell you that after changing the "rs" variable name to
"rsSessions" per your previous instructions, I received two more
variable error messages in the following lines:
' all well, tidy up
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

I figured that I should change these to "rsSessions" too, and I did.
The variable error messages stopped, but I thought you should know
just in case I wasn't supposed to do that.

Incidentally, from your last post you seem to have a stray line in there:
if you see these here, they should be deleted:
'okay, run the command
db.Execute strSQL, dbFailOnError

I deleted this line.

Remember about those fingers this time!
I did remember, but will also include the toes next time! Ha!

Again, I have pasted the current version of the code below.

Many, many thanks!
Jessi

____________________________

Option Compare Database

' this line forces VBA to check the existence of all the variables
Option Explicit

'This is a little test program just to get into things:

Public Sub TryThis()

'"dim" statements let VBA know what variables we need
'we are using DAO so make sure it is checked in Tools...References
'
Dim db As DAO.Database ' handle to the database engine
Dim strSQL As String ' a SQL command

'"const" statments are convenient ways to handle names etc.
'that might change but usually don't
Const c_strTempTable As String = "t_tblWeeklySchedule"

'set up the handles
Set db = CurrentDb()

'check if there is already a temp table
If TableExists(c_strTempTable) Then
'get rid of it
strSQL = "DROP TABLE " & c_strTempTable

'remove this line once we are happy it's working
MsgBox strSQL

'carry it out
'dbFailOnError makes an error if there was a problem with the SQL
db.Execute strSQL, dbFailOnError

End If

' Call a proc to create the new table
MakeTempTable c_strTempTable

End Sub

'Quick function to see if the table already exists
Private Function TableExists( _
TableName As String) As Boolean

'dim statements as above
Dim db As Database
Dim tdf As TableDef

'set up handles
Set db = CurrentDb()

'don't respond to the error
On Error Resume Next
'this will cause an error if the table does not exist
Set tdf = db.Tabledefs(TableName)

'now see if there _was_ an error
If Err.Number = 0 Then
'okay: the table was there
TableExists = True

Else
'not okay, it wasn't there
TableExists = False

End If

End Function

' Create a new temp table using columns from the SessionLookup table
'
Private Sub MakeTempTable(NewTableName As String)

' variables
Dim db As Database ' current db
Dim strSQL As String ' make a command

Dim rsSessions As Recordset ' sessionlookup table

' Handle to current database
Set db = CurrentDb()

' Get the sessions
strSQL = "SELECT fldSessionLookUp " & vbNewLine & _
"FROM tblSessionLookup" & vbNewLine & _
"ORDER BY fldSessionSortNo;"
' it's a ForwardOnly snapshot because it's fastest
Set rsSessions = db.OpenRecordset( _
strSQL, dbOpenSnapshot, dbForwardOnly)

' Now we start the new table
strSQL = "CREATE TABLE " & NewTableName & vbNewLine & _
"( fldResidentID LONG CONSTRAINT pk PRIMARY KEY"

' Add a column for every line in tblSessionLookup
Do While Not rsSessions.EOF
strSQL = strSQL & "," & vbNewLine & _
" " & rsSessions!fldSessionLookUp & " TEXT(1)"

' move to next one
rsSessions.MoveNext

Loop

' complete the command
strSQL = strSQL & ");"

' delete this too when it's all working: not for a while!!
MsgBox strSQL

' and try running it
db.Execute strSQL, dbFailOnError

' all well, tidy up
rsSessions.Close
Set rsSessions = Nothing
Set db = Nothing
End Sub

' Read the DailySessions table and de-normalise it to
' get the weekly schedule for each resident
'
Public Sub FillTempTable(NewTableName As String)

' variables as usual
Dim db As Database ' currentdb
Dim rsDS As Recordset ' old DailySessions
Dim rsTT As Recordset ' new TempTable
Dim strSQL As String

' start as usual
Set db = CurrentDb()

' we need all the session allocations in order of resident
' and then by time of week
' Thinking about it, this could just be a querydef, but let's
' keep going for now
strSQL = "SELECT ds.fldDS_ResidentID, " & vbNewLine & _
"ds.fldDS_SessionTime, " & vbNewLine & _
"ds.fldDS_WorksiteID " & vbNewLine & _
"FROM tblDailySessions AS ds " & vbNewLine & _
" LEFT JOIN tblSessionLookup AS sl " & vbNewLine & _
" ON ds.fldDS_SessionTime = " & vbNewLine & _
" sl.fldSessionLookup " & vbNewLine & _
"ORDER BY ds.fldDS_ResidentID, " & vbNewLine & _
" sl.fldSessionSortNo; "

' this is another information window!
MsgBox strSQL

' get the recordset
Set rsDS = db.OpenRecordset(strSQL, dbOpenSnapshot, dbForwardOnly)

' open the new table
strSQL = "SELECT * FROM " & NewTableName & " WHERE FALSE;"
Set rsTT = db.OpenRecordset(strSQL, dbOpenDynaset)

' now go round each resident: outer loop
Do While Not rsDS.EOF
' create a new temp record and mark it with the resident
rsTT.AddNew
rsTT!fldResidentID = rsDS!fldDS_ResidentID

' go round each timeslot and put it in
' complex exit strategy needs to be done in order
Do While True
' end of input recordset: quit now
If rsDS.EOF Then Exit Do
' it's a different resident: finished with this temp record
If rsDS!fldDS_ResidentID <> rsTT!fldResidentID Then Exit Do

' okay, copy the worksite to the correct column
rsTT.Fields(rsDS!fldDS_SessionTime) = rsDS!fldDS_WorksiteID

' move to next daily session record
rsDS.MoveNext

Loop

' we have to save the temp record
rsTT.Update

' and go round again: we'll drop out of the top of the
' loop if that was the last resident.
Loop

rsTT.Close
rsDS.Close

' finished
End Sub
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
Well... we have the table and the column headings are properly sorted
by session!

aha: you missed out this bit (from my last post:)

in particular the FillTempTable line -- this is the one that actually calls
the new subroutine!
I received two more
variable error messages in the following lines: ....

I figured that I should change these to "rsSessions" too, and I did.
The variable error messages stopped, but I thought you should know
just in case I wasn't supposed to do that.

Good catch!
strSQL = "DROP TABLE " & c_strTempTable

'remove this line once we are happy it's working
MsgBox strSQL

'carry it out
'dbFailOnError makes an error if there was a problem with the SQL
db.Execute strSQL, dbFailOnError

End If

' Call a proc to create the new table
MakeTempTable c_strTempTable
*** NEW LINE GOES HERE ****

End Sub

Hope that works now.
All the best


Tim
 
M

Marcia

aha: you missed out this bit (from my last post:)

So Sorry! (another red face!)


EXCELLENT NEWS!! The table works beautifully. You're very good at
this!

The first time I ran it, I did get an error message about the data
size being too large. When I looked at the results, it had stalled on
the resident who was enrolled in worksite number 13 (the unlucky
number - grin). So I changed the "Text(1)" to "Text(2)" in your code,
and it now accommodates the double-digit worksite numbers. I assume
that was okay?

Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
EXCELLENT NEWS!! The table works beautifully. You're very good at
this!

Tee hee... said:
the resident who was enrolled in worksite number 13 (the unlucky
number - grin). So I changed the "Text(1)" to "Text(2)" in your code,
and it now accommodates the double-digit worksite numbers. I assume
that was okay?

Yeah: spot on... you're getting good at this too! I think I thought that
the worksites were letters A, B, C, D, etc -- but that is fine. Does it
matter if the sites are sorted 1, 11, 12, 13, 2, 3, 4, etc? If it does,
you'll just need to go back and change them all to integers; otherwise
leave it alone.

Now, you should be able to put together the report. You'll need a query
that joins the query you did before (the one with all the SELECT DISTINCT
problems) to the new t_tblTempTable. That should give you

Home Red
Worksite 1
Fred 1, 1, 1, 2, 1, 1, 4, 5,13, 9
Joan 1, 1, 2, 1, 5, 6, 1, 1, 1, 9

Worksite 2
Andy 2, 2, 2, 3, 4, 5, 2, 2,11, 8
Fred 1, 1, 1, 2, 1, 1, 4, 5,13, 8
Joan 1, 1, 2, 1, 5, 6, 1, 1, 1, 8

Home Blue
Worksite 3
etc, etc.


and putting this into a report "is left as an exercise for the reader..."!
I know you'll get back to us here if you have problems with that.

Finally, you might want to create a little form, not bound to any table,
with a big command button that says, "Create Report". Use the wizard to
create a macro that calls

RunCode TryThis()
OpenReport rptMyHomesAndWorksiteReport

-- or, if you feel up to it, do the same thing in the VBA On Click() event!

Feels a bit like I've been on a journey :)
All the best


Tim F
 
M

Marcia

I created my report tonight, and it looks GREAT!! I can't thank you
enough. I really do appreciate everyone's patient efforts on the
NewsGroups. If it had not been for you guys, I would have given up
on Access a long time ago.

Many, many thanks,
Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
I created my report tonight, and it looks GREAT!! I can't thank you
enough. I really do appreciate everyone's patient efforts on the
NewsGroups. If it had not been for you guys, I would have given up
on Access a long time ago.

Many, many thanks,

Been a pleasure. Best of luck with the rest of the project.

Tim F
 
M

Marcia

If you're still watching this thread, Tim, I have one more problem.

When I tried to recreate the database tables and queries at work,
everything went just fine until I tried to run the TryThis procedure.

Then I got an error message: Runtime Error 13 - Datatype mismatch

When I clicked on Debug, it highlighted the following lines:

Set rsSessions = db.OpenRecordset( _
strSQL, dbOpenSnapshot, dbForwardOnly)

These lines are located at the end of the 'Get the Sessions' comments:
' Get the sessions
strSQL = "SELECT fldSessionLookUp " & vbNewLine & _
"FROM tblSessionLookup" & vbNewLine & _
"ORDER BY fldSessionSortNo;"
' it's a ForwardOnly snapshot because it's fastest
Set rsSessions = db.OpenRecordset( _
strSQL, dbOpenSnapshot, dbForwardOnly)

I have looked at the data types for the tblSessionLookup table, and
everything appears to be right... fldSessionLookUp is Text, and
fldSessionSortNo is a Number.

Do you have any idea what might be causing this error?

Thanks!
Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
When I clicked on Debug, it highlighted the following lines:

Set rsSessions = db.OpenRecordset( _
strSQL, dbOpenSnapshot, dbForwardOnly)

Yes. You need to remove the ADO (Active X Data Objects) reference and
insert one to the DAO 3.6 library. You will remember we did this at the
start of creating the first version.

The references are stored in the .mdb file, so once you have set them up
you don't have to do it again until you start over again with a new mdb.

Hope that helps

All the best


Tim F
 
M

Marcia

Although I did remember to select DAO 3.6 Library, I forgot to remove
the ADO Active X one.

Thanks!!

Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
Although I did remember to select DAO 3.6 Library, I forgot to remove
the ADO Active X one.

As you have probably realised, there is only a problem when the same name
is used for objects in both libraries. For example, there is no
ADODB.Database so that gets through easily. Both libraries, however, use
something called Recordset, so the VBA runtime has to decide which one to
use. You can either:

1) Remove the reference to ADO (if you don't need it)

2) Move DAO above ADO (if you're not sure, or you need both)

and/ or

3) Make all references absolutely explicit:

Dim rs As DAO.Recordset
Dim rng As Word.Range

Dim fld As Farming.Field

and so on. My preference is for (1) but that's simply because at my age it
is getting more difficult to adopt new ways of working <groaning /> :)

All the best

Tim F
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top