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

M

Marcia

You might consider making (WorsiteID, SessionTime) a unique key..

I tried this. I deleted the fldSessionID in tblWorksiteSessions, then
made the fldWorksiteID and fldSessionTime BOTH the primary key. It
wouldn't let me link them to the fldDailySessionID (in
tblDailySessions), though. Said.. "No unique index found for the
referenced field of the primary table." How do you link a combination
of TWO fields to ONE?

SELECT tblWorksites.fldWorskiteID,
tblDailySessions.fldResidentID
FROM tblWorksites
LEFT OUTER JOIN (tblWorksiteSessions
LEFT OUTER JOIN (tblDailySessions
ON tblDailySessions.fldDailySessionID
= tblWorksiteSessions.fldSessionID)
ON tblWorksiteSessions.fldWorksiteID = tblWorksites.fldWorksiteID)

This still gives me a Syntax error. (I did try it BEFORE I attempted
to re-work the tblWorksiteSessions primary keys).

If it doesn't work, then you should be able to build this bit
in the query grid by adding each table in turn: Worksites ->
WorksiteSessions -> DailySessions.

I have been able to do this part in the query design grid, though (I
posted a picture of the two query designs):

http://postedinfo.homestead.com/index.html

In my many previous attempts, I would then try to make this query the
basis of a third "crosstab" query so I could get the horizontal layout
they wanted; but when I tried to insert the crosstab query into my
report, I always got the error message about how I couldn't use a
"pass-through" query.
As an aside, if you had decided to use (Worksite, SessionTime) as the PK
for the WorksiteSessions table, and (Worksite, SessionTime, ResidentID) as
the PK for the DailySessions table, then this would not have required any
joins at all!

I'm all for making it simpler! <g> Tell me the process for linking
TWO primary keys to ONE primary key, and I'll do it.

Sorry so complicated,
Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
I tried this. I deleted the fldSessionID in tblWorksiteSessions, then
made the fldWorksiteID and fldSessionTime BOTH the primary key.

Mea culpa: I should have said unique index, as I was not intending at that
time to suggest major changes to the tables. Still, as we said further
down...
I'm all for making it simpler! <g> Tell me the process for linking
TWO primary keys to ONE primary key, and I'll do it.

You don't: you have to join a multi-field Foreign Key to a matched multi-
field Primary Key: as I pointed to above, you start with (by the way, do
this on a copy of your database, just in case!):-

tblWorksites(*fldWorksiteID, WSName, Home, etc)

This is linked to (the * means fields in the PK)

tblWorksiteSessions(*fldWorksiteID, *fldSessionTime)

.... where both fields individually are FKs into their tables: this is as
you already have it. Then you have

tblDailySessions(*fldWorksiteID, *fldSessionTime, *fldResidentID)

.... which you will need to populate with an update query. Next you make
(fldWorksiteID, fldSessionTime) a FK into the WorksiteSessions table, (but
don't bother with links direct into Worksites or SessionLookup) before
removing the fldSessionID column from both tables. To make a two-field
join, in the Relationships window, you click fldWorksiteID and then ctrl-
click fldSessionTime and drag them both toward the tblWorksiteSessions.

You can now do a single query on the DailySessions table

SELECT ALL fldWorksite, fldResidentID
FROM DailySessions
ORDER BY fldWorksite, fldResidentID

which should get all the residents that have any daily sessions at each
worksite, w^5.

I have been able to do this part in the query design grid, though (I
posted a picture of the two query designs):

http://postedinfo.homestead.com/index.html

Okay, but I think the sorting is wrong -- I planned to sort by Worksite
first, and then get a list of each resident daily-assigned to it; for now,
regardless of which session, so the WorksiteSession.SessionTime does not
need to be in the display at all.
In my many previous attempts, I would then try to make this query the
basis of a third "crosstab" query so I could get the horizontal layout
they wanted;

This is a wee bit more complex than that: it's probably possible with pure
SQL but we are going to cheat and do it in VBA. Sometimes execution
performance just has to give way to development time -- we can always do it
neater later on once the method is proven!
Sorry so complicated,

Well, if it was easy, everyone would be doing it!

All the best



Tim F
 
M

Marcia

Thanks for your help! I have classes the next two nights (and work
during the day), so I won't have time to digest your message for a day
or two.

Please don't think I've given up!

Many thanks,
Jessi
 
M

Marcia

I tried to follow this, but had problems. (Don't you just hate the
clueless"?! said:
you start with tblWorksites(*fldWorksiteID, WSName, Home, etc)...linked to:
tblWorksiteSessions(*fldWorksiteID, *fldSessionTime)

From your earlier post, I had made fldWorksiteID and fldSessionTime
multi-field primary keys in tblWorksiteSessions. I now linked
fldWorksiteID(from tblWorksites) over to the fldWorksiteID field
(only) in tblWorksiteSessions. (I tried to link it to BOTH fields
through the "Edit Relationships" box, but it said that "a field name
was missing in Row 1").

tblDailySessions(*fldWorksiteID, *fldSessionTime, *fldResidentID)
... which you will need to populate with an update query.

From the above, I added two fields to tblDailySessions (a
fldWorksiteID number field, and a fldSessionTime text field) to match
those in tblWorksiteSessions, but now have two problems:

1. Since you had asterisks beside all 3 field names, I assumed you
want to make all 3 fields in tblDailySessions a multi-field primary
key. I tried to do that, but I got an error message that "a primary
key cannot contain a null value." (see my attempt to fix it below.)

2. I then assumed that this is the reason you said I would need to
"populate it with an update query," so I tried to append the existing
data in fldSessiontime(tblWorksiteSessions) to the new fldSessionTime
field (in tblDailySessions) using an Append Query. It appended "0"
records, however. Did I understand this correctly? If so, I'll go
back and add the data by hand. Once I get the data in there, then I
will make all three fields in tblDailySessions a multi-field primary
key (of which two fields will be linked over to the matching fields in
tblWorksiteSessions. Right?)
Next you make
(fldWorksiteID, fldSessionTime) a FK into the WorksiteSessions table, (but
don't bother with links direct into Worksites or SessionLookup) before
removing the fldSessionID column from both tables. To make a two-field
join, in the Relationships window, you click fldWorksiteID and then ctrl-
click fldSessionTime and drag them both toward the tblWorksiteSessions.

Humor me, and let me repeat this back to you: I will select both
fldWorksiteID and fldSessionTime fields (in tblDailySesions) and drag
them over to the matching fields in tblWorksiteSessions, making a
two-field join. Right? But I'm not sure what you meant by: "Don't
bother with links direct...

I may have made a true mess of things if I didn't understand you
properly. If so, just tell me and I will happily re-do everything.
Once that is fixed, I look forward to trying your query:
You can now do a single query on the DailySessions table

SELECT ALL fldWorksite, fldResidentID
FROM DailySessions
ORDER BY fldWorksite, fldResidentID

which should get all the residents that have any daily sessions at each
worksite, w^5. http://postedinfo.homestead.com/index.html

Okay, but I think the sorting is wrong -- I planned to sort by Worksite
first, and then get a list of each resident daily-assigned to it; for now,
regardless of which session, so the WorksiteSession.SessionTime does not
need to be in the display at all.


This is a wee bit more complex than that: it's probably possible with pure
SQL but we are going to cheat and do it in VBA. Sometimes execution
performance just has to give way to development time -- we can always do it
neater later on once the method is proven!

Thanks for helping me, and please feel free to take your time!

Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
From your earlier post, I had made fldWorksiteID and fldSessionTime
multi-field primary keys in tblWorksiteSessions.
That should be a multifield PK in.. but good
I now linked
fldWorksiteID(from tblWorksites) over to the fldWorksiteID field
(only) in tblWorksiteSessions.

This is partly a problem with field names: if the
tblWorksiteSessions.fldWorksiteID had been called HostedAt or something,
then it would have been obvious said:
1. Since you had asterisks beside all 3 field names, I assumed you
want to make all 3 fields in tblDailySessions a multi-field primary
key.

Spot on: well done.
I tried to append the existing
data in fldSessiontime(tblWorksiteSessions) to the new fldSessionTime
field (in tblDailySessions) using an Append Query.

No: you need an update query to fill in the two new columns. In the query
designer, join the DailySessions table to the WorksiteSessions, using the
SessionID field (as it is at the moment). Set the query type to UPDATE, and
drag the new fields in the DailySessions table to the grid; then use the
Update To row to specify the equivalent fields from the WorksiteSessions
table. All this does is like this:

WorksiteSessions
WSSID Worksite SessionTime
56 A MondayAM
57 A MondayPM

DailySessions
WSSID Worksite SessionTime Resident
56 A MondayAM Eric
56 A MondayAM Jones
57 A MondayPM Eric
57 A MondayPM Geoffrey

now the WorksiteSessionID is completely redundant and you can remove it
from both tables, and then create the new relationship between (Worksite,
SessionTime)
But I'm not sure what you meant by: "Don't bother with links direct...

It's just a reminder not to make a relationship between
Worksites.WorksiteID and DailySessions.WorksiteID... if you hadn't thought
of doing it anyway, then just ignore me!

While we are doing table revising, there is one thing that is going to make
life easier later on. We will need to sort the SessionTimes, and
alphabetically is not going to do it (Friday comes before Wednesday, see?).
We will need an extra number column in the SessionTimes table that lists
Monday AM = 1, Monday PK = 2 etc.

Talk to you again soon.

Tim F
 
M

Marcia

Hi, again!

I renamed several fields in tblDailySessions by adding "DS" (to keep
me from confusing them with other fields of the same name in different
tables. <g>)

I have now been able to complete your update query... (I started over
from my backup copy of the file because my problem was that I had
gotten ahead of myself earlier by deleting the fldSessionIDs before
trying the update query. (so sorry). When I tried it this time, the
update query worked fine... THEN I deleted the fldSessionIDs. Backups
are wonderful.

I then created your query which gives me a list of all the
fldDS_WorksiteID and fldDS_ResidentID entries in tblDailySessions. It
works.

I have updated my relationship and query picture so that you can see
what I've done. Please let me know if I have misunderstood
something. Note: It wouldn't let me create "referential integrity
between tblWorksiteSessions and tblDailySessions because "No unique
index found for the referenced field of the primary table." Is that
okay?
While we are doing table revising, there is one thing that is going to make
life easier later on. We will need to sort the SessionTimes, and
alphabetically is not going to do it (Friday comes before Wednesday, see?).
We will need an extra number column in the SessionTimes table that lists
Monday AM = 1, Monday PK = 2 etc.

I had *sort of* thought of this already, but I did it a little
differently. I included the sort number as part of the Session Time,
thinking that I would remove the number later using the MID function
in my report. (1_MAM, 2_MPM, 3_TAM, etc.) If it is better to put
the sort-order in a separate field, I will be happy to do that. If
so, would it be better to add the new field in tblDailySessions or
tblWorksiteSessions?

Also, since we have now added fldDS_SessionTime to tblDailySessions,
should I also make this a "lookup" field on the tblSessionLookup
table? (Right now, it is only being used by fldSessionTime in
tblWorksiteSessions.)

Thanks so much! Hope I haven't been too much of a pain.

Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in

Hi Marcia
I have now been able to complete your update query...
Good.

I then created your query which gives me a list of all the
fldDS_WorksiteID and fldDS_ResidentID entries in tblDailySessions. It
works.

Cool -- I had not been able to test that!
Note: It wouldn't let me create "referential integrity
between tblWorksiteSessions and tblDailySessions because "No unique
index found for the referenced field of the primary table."

Can't see what is wrong with this. I would delete the two lines that are
there at the moment, and do it this way:

In the WorksiteSessions table, click WorksiteID and then ctrl-click the
SessionTime field, so that they are both highlighted. You should then be
able to drag both fields over to DailySessions, and then make the Ref
Integrity stick.

I guess you may be trying to draw the two lines in two operations, and
Access is quite right that one end of a relationship must involve a whole
primary key.
I included the sort number as part of the Session Time,
thinking that I would remove the number later using the MID function
in my report. (1_MAM, 2_MPM, 3_TAM, etc.)

Ummm, yes. The problem with this is when someone asks to introduce a
Wednesday Lunchtime session, and all your keys need to be changed. Still,
in the interests of getting this running, let's leave it alone and worry
about it another day!
If so, would it be better to add the new field in tblDailySessions
or tblWorksiteSessions?

As above, don't bother; but it would be SessionLookup. The entity is the
slot during the week, and where it comes in order during the week is an
attribute of the slot. The WorksiteSession entity represents the act of
people gathering in a place during a time slot -- presumably the sort order
is the same in all the places!
Also, since we have now added fldDS_SessionTime to tblDailySessions,
should I also make this a "lookup" field on the tblSessionLookup
table?

No: that is what I meant about not putting links directly from these fields
to (what look like) their parent tables. Relationships are about control:
there is no need to constrain DailySessions.SessionTime to be a valid
SessionTime, because the pair DailySessions(WorksiteID, SessionTime) is
already constrained to be a valid WorksiteSession, and WorksiteSessions
already have to be held during valid SessionTimes. It all comes back to
semantics, and I still hate these naming systems propounded by the text-
book writers which stress form rather than function. Still, I guess that's
my problem <g>.

All the best


Tim F
 
M

Marcia

Hi!
Can't see what is wrong with this. I would delete the two lines that are
there at the moment, and do it this way:

In the WorksiteSessions table, click WorksiteID and then ctrl-click the
SessionTime field, so that they are both highlighted. You should then be
able to drag both fields over to DailySessions, and then make the Ref
Integrity stick.

I am trying to create the relationship with both fields at the same
time, but I'm still getting the same error message: "No unique index
found..." Would it possibly be because fldDS_WorksiteID and
fldDS_SessionTime do not by themselves provide a unique key? (they
contain duplicate values which can only be distinguished as "unique"
if you add fldDS_ResidentID as the third multi-field PK). But if I
try to include fldDS_ResidentID in the third line of the "Edit
Relationships" box, it tells me that I must have the same number of
fields on both sides. It won't let me match up a two-field primary
key with a three-field primary key.


To recap, we have now created two queries that work:
1. HomeName, WorksiteName, WorksiteID (sorted by Home, then by
Worksite)
2. WorksiteID, ResidentID (from tblDailySession, sorted by
WorksiteID)

I assume these will be combined in some way to create the report?

Many thanks,
Marcia
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
I am trying to create the relationship with both fields at the same
time, but I'm still getting the same error message: "No unique index
found..." Would it possibly be because fldDS_WorksiteID and
fldDS_SessionTime do not by themselves provide a unique key?

No: it's the other end that is the PK (of the tblWorksites) -- this looks
right in the web page as it is at present. Try dragging the relationship in
the other direction (if you see wot I mean). From the schema, I can't see
any reason for this not to work.
To recap, we have now created two queries that work:
1. HomeName, WorksiteName, WorksiteID (sorted by Home, then by
Worksite)
2. WorksiteID, ResidentID (from tblDailySession, sorted by
WorksiteID)

I assume these will be combined in some way to create the report?

Kind of, yes. We will need a query that produces

Every Resident that has any session at...
Each Worksite
Grouped by the Home that sponsors it.

so you need tblDailySession joined to tblWorksites on
tblDailySessions.DS_WorksiteID = tblWorksites.WorksiteID; and then you can
use the tblWorksites.fldHomeID to group by the sponsoring Home. Make the
join "Use each record from DailySessions" although it probably doesn't
matter all that much.

The thing that will cause the most problem is the weekly schedule for each
Resident -- it occurs to me that there is a great deal of repetition as a
resident could appear in the final list up to ten times, if he should have
all his sessions in different worksites. It is probably a good idea,
therefore, to set up a temporary table to help run the report, which can be
removed afterwards. It would go something like this:

If the temptable exists, then
Remove It
End If

Create a new TempTable: looks like
(ResidentID, 1_MonAM, 2_MonPM, 3_TueAM, 4_TuePM....)

Open a query on the DailySessions table, _
sorted on Resident and SessionTime

For each resident in the query
Add a new record in the TempTable
Write the residentID in it

For each SessionTime for that resident
Write the WorksiteID into the correct SessionTime _
field in the TempTable record.

Next SessionTime

Save the TempTable record

Next resident


If you are happy with this logic, we can start to build in next time, and
then join the new temp table to the query above on ResidentID.

B Wishes


Tim F
 
M

Marcia

I am trying to create the relationship with both fields at the same
...From the schema, I can't see any reason for this not to work.

I never did get it to work... SOOOO, I recreated the database with no
data, made the necessary links, then added the data back in (phew!).
It is now linked!

We will need a query that produces
Every Resident that has any session at...
Each Worksite
Grouped by the Home that sponsors it.

so you need tblDailySession joined to tblWorksites on
tblDailySessions.DS_WorksiteID = tblWorksites.WorksiteID; and then you can
use the tblWorksites.fldHomeID to group by the sponsoring Home. Make the
join "Use each record from DailySessions" although it probably doesn't
matter all that much.

I think I did this right... you might want to look at the picture,
though.
I added tblDailySession and tblWorksites to the design grid, and made
a new relationship on the Worksite ID. I edited the relationship and
chose the second option (include ALL rows from tblDailySessions, and
only those records from tblWorksites where the joined fields are
equal).

I then added the following fields in this order:
fldWS_HomeID (from tblWorksites)
fldDS_ResidentID (from tblDailySessions)
fldDS_SessionTime (from tblDailySessions)
fldDS_WorksiteID (from tblDailySessions)

I named the query: qryResidentDailySessions_GroupedByHome

Right?

One thought... since I had to re-do the database, I added a new
fldSessionSort field to the tblSessionLookup to sort the session days
(as you mentioned earlier). Do I need to add that field in here
somewhere?

It is probably a good idea, therefore, to set up a temporary table to help
run the report, which can be removed afterwards. It would go
something like..

(snip)... lines of logic... (snip)
If you are happy with this logic, we can start to build it next time, and
then join the new temp table to the query above on ResidentID.

Happy? I'm thrilled! I have no idea how to do this, but it sounds
good to me!


Many, many thanks!
Marcia
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in

Hello again,
SOOOO, I recreated the database with no
data, made the necessary links, then added the data back in (phew!).
It is now linked!

Yuk: still, at least we are up and running now.
One thought... since I had to re-do the database, I added a new
fldSessionSort field to the tblSessionLookup to sort the session days
(as you mentioned earlier).

Okay fine.

I then added the following fields in this order:
fldWS_HomeID (from tblWorksites)
fldDS_ResidentID (from tblDailySessions)
fldDS_SessionTime (from tblDailySessions)
fldDS_WorksiteID (from tblDailySessions)

Don't need the fldDS_SessionTime column, because at this time we are only
interested in _who_ is an attender at each Worksite, not when. That comes
later... <g>

Do the data look right when you run it?
Do I need to add the tblSessionLookup.fldSessionSort in here somewhere?

Not yet.

Now, we do need to build up a table of Residents' weekly schedule. I cannot
test this here, so we'll do it bit by bit (this is great: I get someone
else to do my testing for me!)

If you haven't done any VBA programming before, this might look a bit heavy
so don't worry about asking questions. You need to enter the VBA editor,
select Insert...New...Module.

Any line that begins with an apostrophe ' is a comment, and is for
explanation. It's best to keep these in so that you can work out what on
earth we were doing after...

Try copying this into the new module

'' START OF CODE: COPY AND PASTE FROM HERE
'
' this line forces VBA to check the existence of all
' the variables
Option Explicit

'
' This is a little test programme 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

' Now we can try creating a new table
strSQL = "CREATE TABLE " & c_strTempTable & vbNewLine & _
"( fldResidentID LONG CONSTRAINT PRIMARY KEY," & vbNewLine & _
" fldMondayAM TEXT(1)" & vbNewLine & _
");"

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

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

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

' END OF CODE: STOP COPYING AND PASTING HERE

Try running this by getting the immediate window and typing

TryThis <enter>

All being well, you should get a couple of Message boxes and nothing else.
Check the Tables pane in the database window and you should see a new table
with two fields in it. Murphy's law being what it is, however, there will
be some error messages to come back to me with! Make a note of the error,
and which line is highlighted when you click "Debug".

That's enough for this evening. <g>
All the best


Tim F
 
M

Marcia

Hi!

Don't need the fldDS_SessionTime column, because at this time we are only
interested in _who_ is an attender at each Worksite, not when. That comes
later... <g>

Do the data look right when you run it?

It is the right data. It is sorting by the worksite's "Home" first
(which is what my report requires), but that means the set of a
resident's sessions are not listed together -- they are split up under
the home that sponsors the worksite. This is what I'm getting:

HomeID ResidentID WorksiteID
1 1 1
1 1 1
1 1 2
1 1 | 1
1 2 | 1
1 2 v 1
1 2 1
1 2 1
3 1 <-- 9

.... where Residents 1 and 2 attend worksites sponsored by Home 1;
EXCEPT for Resident 1's session in Worksite 9 (which is sponsored by
Home 3). This *IS* what you want, right?
Now, we do need to build up a table of Residents' weekly schedule.

Which "DAO" did you want? The items that were already selected were:
Visual Basic for Applications
Microsoft Access 10.0 Object Library
OLE Automation; and
Microsoft ActiveX Data Objects 2.1 Library

There WERE options for the following, but they were not selected:
Microsoft DAO 2.5/3.51 Compatibility Library
Microsoft DAO 3.51 Object Library
Microsoft DAO 3.6 Object Library

I initially selected all three, but got a compatibility error message.
Access deselected two of them, but retained: "Microsoft DAO 2.5/3.51
Compatibility Library." I kept it. Is that the right one?


I copied and pasted the code, then ran it. The error message I got
was:

A message box with 4 lines that said:

CREATE TABLE t_tblWeeklySchedule
(fldResidentID LONG CONSTRAINT PRIMARY KEY,
fldMondayAM TEXT(1)
);

When I clicked on the OK button, I got a second error message:

Run-time error '3292"
Syntax error in field definition

When I clicked "Debug," the following line was highlighted:

db.Execute strSQL, dbFailOnError

I checked, but no new tables were created.

Not bad for the first try, huh? I "re-pasted" the code below as it
looks in my screen so you can make sure that I didn't screw it up
somehow. (It pasted all the ">" marks when I pasted it into the
module)

Thanks!
Jessi


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

'This is a little test programme 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

' Now we can try creating a new table
strSQL = "CREATE TABLE " & c_strTempTable & vbNewLine & _
"( fldResidentID LONG CONSTRAINT PRIMARY KEY," & vbNewLine & _
" fldMondayAM TEXT(1)" & vbNewLine & _
");"

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

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

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
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
Hi!

It is the right data. It is sorting by the worksite's "Home" first
(which is what my report requires), but that means the set of a
resident's sessions are not listed together -- they are split up under
the home that sponsors the worksite.

Check out the order of the fields in the grid. Sorry I missed this: it
should be HomeID -> WorksiteID -> ResidentID.

Another thing, to get rid of the duplicates with the DISTINCT keyword:
right-click in the query window, get the Queries Properties page and change
the Unique Values to Yes. We want residents to re-appear in subsequent
Worksites, but not multiple times in the same worksite.
... where Residents 1 and 2 attend worksites sponsored by Home 1;
EXCEPT for Resident 1's session in Worksite 9 (which is sponsored by
Home 3).

Yes: if resident 1 has a session in WS 9, then he needs to reappear there.
Which "DAO" did you want? The items that were already selected were: .... all okay
Microsoft ActiveX Data Objects 2.1 Library
.... but uncheck this one (unless you use ADO, which I'm assuming you don't
for now)
There WERE options for the following, but they were not selected:
Microsoft DAO 3.6 Object Library

Sorry, it's this one you want! From memory, DAO 2.5/2.51 was for VBasic 4
and Access 97... we'll be doing things that need the most recent. Just
uncheck it and check the 3.6 instead.
A message box with 4 lines that said:

CREATE TABLE t_tblWeeklySchedule
(fldResidentID LONG CONSTRAINT PRIMARY KEY,
fldMondayAM TEXT(1)
);

My fault: all constraints must have names. The middle line of this should
read

(fldResidentID LONG CONSTRAINT pk PRIMARY KEY,

i.e. put "pk" after the CONSTRAINT keyword (without the quote marks). You
can change the appropriate line in the code I posted and it should be okay
now. Not too bad for first go, though!

Hope this is okay


Tim F
 
M

Marcia

Hi!
Another thing, to get rid of the duplicates with the DISTINCT keyword:
right-click in the query window, get the Queries Properties page and change
the Unique Values to Yes. We want residents to re-appear in subsequent
Worksites, but not multiple times in the same worksite.

Okay... I did that, but it still showed multiple instances of the same
resident in the same worksite in the same home. So I clicked on the
"Totals" icon and added "Group By" to all the fields, and it then gave
me unique values. Will that work for your purposes? Or will the
"Group By" function screw something else up later?


As for the foreign language... (grin)

The first error message continued:

CREATE TABLE t_tblWeeklySchedule
( fldResidentID LONG CONSTRAINT pk PRIMARY KEY,
fldMondayAM TEXT(1)
);"


But we did get a table out of it, because I am also now getting a
SECOND error message:

DROP TABLE t_tblWeeklySchedule

I looked, and Access DID create the above new table
(t_tblWeeklySchedule), but there is no data in it.


Once again, I will copy and paste the code in its entirety below.

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

' Now we can try creating a new table
strSQL = "CREATE TABLE " & c_strTempTable & vbNewLine & _
"( fldResidentID LONG CONSTRAINT pk PRIMARY KEY," & vbNewLine & _
" fldMondayAM TEXT(1)" & vbNewLine & _
");"

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

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

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
 
M

Marcia

I need to add an addendum to my previous post.

I manually deleted the temporary table, and tried to re-run the
procedure.

The first pass-through creates the first "CREATE TABLE" error message.
When I look in the Database Window, I do NOT see a new table. BUT,
if I close out the database and re-open it, the table is there.

If I run the procedure a *second* time, I get the SECOND "DROP TABLE"
error message, along with a repeat of the first "CREATE TABLE" error
message.

The new table (t_tblWeeklySchedule) is still there after the second
pass.

Thanks!!
Jessi
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in
Okay... I did that, but it still showed multiple instances of the same
resident in the same worksite in the same home. So I clicked on the
"Totals" icon and added "Group By" to all the fields, and it then gave
me unique values. Will that work for your purposes? Or will the
"Group By" function screw something else up later?

Probably..<g>. I wonder if you selected Unique Rows instead of Unique
Values-? Change the query back to normal by clicking the Totals button
again, then check the SQL view: View..SQL View. This is the query that the
grid is actually building. Don't get too worried because it does look
awful; the only think I am interested in is the first two words. It should
say

SELECT [tblDailySessions].[fldHomeID].....

or perhaps

SELECT DISTINCTROW [tblDailySessions].[fldHomeID].....

where I want it to say

SELECT DISTINCT [tblDailySessions].[fldHomeID].....

once you have added the DISTINCT word, return to the grid (View..Design
View) and make sure nothing else has changed. If it still refuses to squash
the duplicates, copy-and-paste the entire SQL text here (ugh).
As for the foreign language... (grin)

Hey, this is good stuff!!
The first error message continued:

It's not an error message: we put that in the program to show it's working
right. This time it does look fine.
But we did get a table out of it, because I am also now getting a
SECOND error message:

DROP TABLE t_tblWeeklySchedule

Actually this should come first. Again, not an error message just a
reminder that the procedure is getting rid of the table before re-making
it. This is good said:
I looked, and Access DID create the above new table
(t_tblWeeklySchedule), but there is no data in it.

Hooray: we haven't started on filling it (or even creating it completely)
yet. Creating the table goes like this: we will run through the
tblSessionLookup to create one column in the temp table for each Session.

Let's make a new procedure like this: copy all this text into the BOTTOM of
the module you have already (below the End Function)

' CODE STARTS HERE...

'
' 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 & _
" " & rs!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
rs.Close
Set rs = Nothing
Set db = Nothing

End Sub

' END OF CODE **********

As long as this pastes-in okay, then we'll build it into the original
procedure. Look down the TryThis procedure and delete these lines:

' Now we can try creating a new table
strSQL = "CREATE TABLE " & c_strTempTable & vbNewLine & _
"( fldResidentID LONG CONSTRAINT PRIMARY KEY," & vbNewLine & _
" fldMondayAM TEXT(1)" & vbNewLine & _
");"

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

and replace them all with

' Call a proc to create the new table
MakeTempTable c_strTempTable

how's that? Save it all and run it with TryThis in the immediate window
again. You should see the DROP TABLE message, and then a longer CREATE
TABLE one. Check that the second one looks like the correct SessionTimes,
and then let it run on.

One quirk: if the database window is open on the Tables page, you won't see
the new table until you go to another page (e.g Queries) and then back to
the Tables again. Open the new table and you should see the correct
columns, but again no data yet.

Fingers crossed!

Tim F
 
M

Marcia

Probably.. said:

I did change "Unique Values" to "Yes," so I don't know what went
wrong. But when I viewed the SQL, it said SELECT DISTINCTROW...

So I deleted the "ROW" part of the word, and it now WORKS: It
eliminates the duplicates as you wished. I have copied the SQL for
you anyway (it will wrap around, so I'll number the lines):

1
SELECT DISTINCT tblWorksites.fldWS_HomeID,
tblDailySessions.fldDS_WorksiteID, tblDailySessions.fldDS_ResidentID
2
FROM tblDailySessions LEFT JOIN tblWorksites ON
tblDailySessions.fldDS_WorksiteID = tblWorksites.fldWorksiteID
3
ORDER BY tblWorksites.fldWS_HomeID, tblDailySessions.fldDS_WorksiteID,
tblDailySessions.fldDS_ResidentID;

It's not an error message: we put that in the program to show it's working
right. This time it does look fine.

Oh! <red face>

Creating the table goes like this: we will run through the
tblSessionLookup to create one column in the temp table for each Session.

Let's make a new procedure like this: copy all this text into the BOTTOM of
the module you have already (below the End Function)

and replace them all with
' Call a proc to create the new table
MakeTempTable c_strTempTable
Save it all and run it with TryThis again.

I did this.

You should see the DROP TABLE message...

Yes.

But then it gave me a "Compile Error - Variable Not Defined" message.
When I clicked okay, the line:
Private Sub MakeTempTable(NewTableName As String)
was highlighted in yellow.

and in the following section:

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

the letters "rs" in the last line were highlighted in blue.


When I tried to run the procedure a second time (just to see what
happened), I no longer got the first DROP TABLE message, and there is
no table in the Database Window.

So... do we Dim "rs"?

Fingers crossed!
Oops! I forgot! (grin)

I have pasted the entire code below as it now stands.

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

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

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 & _
" " & rs!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
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub


End Sub
 
T

Tim Ferguson

(e-mail address removed) (Marcia) wrote in

So I deleted the "ROW" part of the word, and it now WORKS:
Hurray!

and in the following section:

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

the letters "rs" in the last line were highlighted in blue.

Aha: that should be rsSessions!fldSessionLookUp That's what comes when you
change your mind about a variable name half way through writing the thing.
So... do we Dim "rs"?

Good guess -- but we're meant to be using just the one recordset.
When I tried to run the procedure a second time (just to see what
happened), I no longer got the first DROP TABLE message, and there is
no table in the Database Window.

That's because the bit to remove the table worked, and the bit to re-create
it didn't.
Oops! I forgot! (grin)

Aha: so it _was_ your fault after all..!

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

All the best


Tim F
 
M

Marcia

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

Sure...Please take as long as you want (days, weeks, whatever)! I had
no idea this was going to be such a project!

Take care,
Jessi
 

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