Looping An SQL Statement

G

Guest

For a timesheet application, I am using un-normalized Timesheet and Timesheet
Detail tables on a form that shows 2 weeks of data in a grid format. This is
done to simplify the data entry. Rather than forcing the user to enter a
projectnumber, date, and hours, each row represents a given project, and the
user can cursor to one of 14 columns (DayHours1, DayHours2, etc.)and enter
the hours worked that day. There are 14 StatusID fields as well.

The user, when the timesheet is complete, posts the data to normalized
tables from which aggregate reporting and billing are done. All of these
functions have been tested thoroughly.

It is unlikely but possible, however, that a user will accidentally post an
incomplete or inaccurate sheet. In this case, I want him or her to
immediately contact the Office Manager so that no further billing is done and
so that the timesheet can be restored from the normalized tables.

Several steps of this process are now debugged. The current step is
generating a syntax error. I started the query in Query Design View on a
single day in which I new test data existed, DayHours9:

UPDATE (TSHistory INNER JOIN Timesheet
ON TSHistory.StaffID = Timesheet.StaffID)
INNER JOIN (TimeRecords INNER JOIN TimeSheetDetail
ON TimeRecords.ProjectNumber = TimeSheetDetail.ProjectNumber)
ON (Timesheet.StaffID = TimeSheetDetail.StaffID)
AND (TSHistory.TSID = TimeRecords.TSID)
SET TimeSheetDetail.DayHours9 = TimeRecords.Hours, TimeSheetDetail.Status9 =
IIf(TimeRecords.StatusID=2,1,TimeRecords.StatusID)
WHERE
((TSHistory.PeriodBeginning)=[Forms]![RestoreTimesheet]![txtPeriodStartDate])
AND ((TSHistory.StaffID)=[Forms]![RestoreTimesheet]![cboStaffID])
AND ((TimeRecords.PeriodDay)=9));

This runs and updates the TimeRecordsDetail table as expected.

I brought the SQL into my code and built an SQL string in steps, replacing
references that Jet will not recognize on executing db.Execute, for example,

[Forms]![RestoreTimesheet]![cboStaffID]
became
Forms("RestoreTimesheet").Controls("cboStaffID")

I then ran the code, using:

db.Execute strSQL, dbFailOnError

It executed successfully.

Now that I've changed the code to loop for all 14 sets of fields. The first
iteration of strSQL as printed to the Immediate Window is:

UPDATE (TSHistory INNER JOIN Timesheet
ON TSHistory.StaffID =Timesheet.StaffID)
INNER JOIN (TimeRecords INNER JOIN TimeSheetDetail
ON TimeRecords.ProjectNumber = TimeSheetDetail.ProjectNumber)
ON (Timesheet.StaffID = TimeSheetDetail.StaffID)
AND (TSHistory.TSID = TimeRecords.TSID)
SET TimeSheetDetail.DayHours1= TimeRecords.Hours, TimeSheetDetail.Status1=
IIf(TimeRecords.StatusID=2,1,TimeRecords.StatusID)
WHERE (((TSHistory.PeriodBeginning)=#12/31/2006#)
AND ((TSHistory.StaffID)=8) AND ((TimeRecords.PeriodDay)=1)

This generates a "Missing ), ], or Item in query expression" error on the
WHERE clause at:

(((TSHistory.PeriodBeginning) = #12/31/2006#)

Can anyone figure out what's happening? I've stared at it for a half hour
without understanding.

Thank you.
Sprinks
 
G

Guest

Spinks, I'm not sure without the ability to test, but a visual scan makes me
think you are missing one ) in the Where clause.

WHERE (((TSHistory.PeriodBeginning)=#12/31/2006#)
AND ((TSHistory.StaffID)=8) AND ((TimeRecords.PeriodDay)=1)

I count 7 ( and only 6 )

Try adding one ) at the end
WHERE (((TSHistory.PeriodBeginning)=#12/31/2006#)
AND ((TSHistory.StaffID)=8) AND ((TimeRecords.PeriodDay)=1))

Hope this works for you.


Sprinks said:
For a timesheet application, I am using un-normalized Timesheet and Timesheet
Detail tables on a form that shows 2 weeks of data in a grid format. This is
done to simplify the data entry. Rather than forcing the user to enter a
projectnumber, date, and hours, each row represents a given project, and the
user can cursor to one of 14 columns (DayHours1, DayHours2, etc.)and enter
the hours worked that day. There are 14 StatusID fields as well.

The user, when the timesheet is complete, posts the data to normalized
tables from which aggregate reporting and billing are done. All of these
functions have been tested thoroughly.

It is unlikely but possible, however, that a user will accidentally post an
incomplete or inaccurate sheet. In this case, I want him or her to
immediately contact the Office Manager so that no further billing is done and
so that the timesheet can be restored from the normalized tables.

Several steps of this process are now debugged. The current step is
generating a syntax error. I started the query in Query Design View on a
single day in which I new test data existed, DayHours9:

UPDATE (TSHistory INNER JOIN Timesheet
ON TSHistory.StaffID = Timesheet.StaffID)
INNER JOIN (TimeRecords INNER JOIN TimeSheetDetail
ON TimeRecords.ProjectNumber = TimeSheetDetail.ProjectNumber)
ON (Timesheet.StaffID = TimeSheetDetail.StaffID)
AND (TSHistory.TSID = TimeRecords.TSID)
SET TimeSheetDetail.DayHours9 = TimeRecords.Hours, TimeSheetDetail.Status9 =
IIf(TimeRecords.StatusID=2,1,TimeRecords.StatusID)
WHERE
((TSHistory.PeriodBeginning)=[Forms]![RestoreTimesheet]![txtPeriodStartDate])
AND ((TSHistory.StaffID)=[Forms]![RestoreTimesheet]![cboStaffID])
AND ((TimeRecords.PeriodDay)=9));

This runs and updates the TimeRecordsDetail table as expected.

I brought the SQL into my code and built an SQL string in steps, replacing
references that Jet will not recognize on executing db.Execute, for example,

[Forms]![RestoreTimesheet]![cboStaffID]
became
Forms("RestoreTimesheet").Controls("cboStaffID")

I then ran the code, using:

db.Execute strSQL, dbFailOnError

It executed successfully.

Now that I've changed the code to loop for all 14 sets of fields. The first
iteration of strSQL as printed to the Immediate Window is:

UPDATE (TSHistory INNER JOIN Timesheet
ON TSHistory.StaffID =Timesheet.StaffID)
INNER JOIN (TimeRecords INNER JOIN TimeSheetDetail
ON TimeRecords.ProjectNumber = TimeSheetDetail.ProjectNumber)
ON (Timesheet.StaffID = TimeSheetDetail.StaffID)
AND (TSHistory.TSID = TimeRecords.TSID)
SET TimeSheetDetail.DayHours1= TimeRecords.Hours, TimeSheetDetail.Status1=
IIf(TimeRecords.StatusID=2,1,TimeRecords.StatusID)
WHERE (((TSHistory.PeriodBeginning)=#12/31/2006#)
AND ((TSHistory.StaffID)=8) AND ((TimeRecords.PeriodDay)=1)

This generates a "Missing ), ], or Item in query expression" error on the
WHERE clause at:

(((TSHistory.PeriodBeginning) = #12/31/2006#)

Can anyone figure out what's happening? I've stared at it for a half hour
without understanding.

Thank you.
Sprinks
 
G

Guest

Klatuu,

Thanks for your response; there were actually TWO missing right parentheses.
The code then executed without error, but did not update my table as I'd
expected. I don't really understand why. I was able though to simplify the
query by first getting the primary key from the TSHistory table, and it now
works:

' Get TSID Number, unique for every combination of StaffID and
PeriodStartDate
intTSID = DLookup("[TSID]", "TSHistory", "[StaffID]=" &
Me![cboStaffID] & _
" AND [PeriodBeginning]=#" & Me![txtPeriodStartDate] & "#")

For i = 1 To 14

' Update Timesheet Detail Records
strSQL = "UPDATE TSHistory INNER JOIN (TimeRecords"
strSQL = strSQL & " INNER JOIN TimeSheetDetailONâ€
strSQL = strSQL & “ TimeRecords.ProjectNumber"
strSQL = strSQL & " = TimeSheetDetail.ProjectNumber)"
strSQL = strSQL & " ON (TSHistory.StaffID = TimeSheetDetail.StaffID)"
strSQL = strSQL & " AND (TSHistory.TSID = TimeRecords.TSID)"
strSQL = strSQL & " SET TimeSheetDetail.DayHours"
strSQL = strSQL & Trim(str(i)) & "= [Hours],"
strSQL = strSQL & " TimeSheetDetail.Status" & Trim(str(i))
strSQL = strSQL & "= IIf([StatusID]=2,1,[StatusID])"
strSQL = strSQL & " WHERE (((TimeRecords.TSID)=" & intTSID
strSQL = strSQL & ") AND ((TimeRecords.PeriodDay)=" & Trim(str(i)) & "));"

db.Execute strSQL, dbFailOnError

Next i

Thanks for your help.

BTW, I'm "Sprinks". Spinks was the guy with no teeth who beat Ali. ;)

Sprinks
 
G

Guest

Sorry for the typo, Sprinks
One thing I do when I am modifiying the SQL created by the Access query
builder is to remove all the (). I don't know why Access puts all those
parenthises in. They are not (in most cases) necessary. So, I take them
out, test the query, and put some back in if Access complains.
 
G

Guest

Although I wish I understood SQL well enough to know WHICH parentheses were
important, I think your suggestion is a very good and practical one. Thanks.

Sprinks

Klatuu said:
Sorry for the typo, Sprinks
One thing I do when I am modifiying the SQL created by the Access query
builder is to remove all the (). I don't know why Access puts all those
parenthises in. They are not (in most cases) necessary. So, I take them
out, test the query, and put some back in if Access complains.

Sprinks said:
Klatuu,

Thanks for your response; there were actually TWO missing right parentheses.
The code then executed without error, but did not update my table as I'd
expected. I don't really understand why. I was able though to simplify the
query by first getting the primary key from the TSHistory table, and it now
works:

' Get TSID Number, unique for every combination of StaffID and
PeriodStartDate
intTSID = DLookup("[TSID]", "TSHistory", "[StaffID]=" &
Me![cboStaffID] & _
" AND [PeriodBeginning]=#" & Me![txtPeriodStartDate] & "#")

For i = 1 To 14

' Update Timesheet Detail Records
strSQL = "UPDATE TSHistory INNER JOIN (TimeRecords"
strSQL = strSQL & " INNER JOIN TimeSheetDetailONâ€
strSQL = strSQL & “ TimeRecords.ProjectNumber"
strSQL = strSQL & " = TimeSheetDetail.ProjectNumber)"
strSQL = strSQL & " ON (TSHistory.StaffID = TimeSheetDetail.StaffID)"
strSQL = strSQL & " AND (TSHistory.TSID = TimeRecords.TSID)"
strSQL = strSQL & " SET TimeSheetDetail.DayHours"
strSQL = strSQL & Trim(str(i)) & "= [Hours],"
strSQL = strSQL & " TimeSheetDetail.Status" & Trim(str(i))
strSQL = strSQL & "= IIf([StatusID]=2,1,[StatusID])"
strSQL = strSQL & " WHERE (((TimeRecords.TSID)=" & intTSID
strSQL = strSQL & ") AND ((TimeRecords.PeriodDay)=" & Trim(str(i)) & "));"

db.Execute strSQL, dbFailOnError

Next i

Thanks for your help.

BTW, I'm "Sprinks". Spinks was the guy with no teeth who beat Ali. ;)

Sprinks
 
J

John Nurick

If I've got to deal with a long SQL statement, I often paste it into a
decent text editor with a fixed width font, and then do a lot of
indenting and line-breaking so I can really see how the thing is
structured and what (if anything) the parentheses are doing.

When I've got it neatly laid out I paste it back into the SQL view of
the query, save it, and in due course Access screws up the layout again.

Although I wish I understood SQL well enough to know WHICH parentheses were
important, I think your suggestion is a very good and practical one. Thanks.

Sprinks

Klatuu said:
Sorry for the typo, Sprinks
One thing I do when I am modifiying the SQL created by the Access query
builder is to remove all the (). I don't know why Access puts all those
parenthises in. They are not (in most cases) necessary. So, I take them
out, test the query, and put some back in if Access complains.

Sprinks said:
Klatuu,

Thanks for your response; there were actually TWO missing right parentheses.
The code then executed without error, but did not update my table as I'd
expected. I don't really understand why. I was able though to simplify the
query by first getting the primary key from the TSHistory table, and it now
works:

' Get TSID Number, unique for every combination of StaffID and
PeriodStartDate
intTSID = DLookup("[TSID]", "TSHistory", "[StaffID]=" &
Me![cboStaffID] & _
" AND [PeriodBeginning]=#" & Me![txtPeriodStartDate] & "#")

For i = 1 To 14

' Update Timesheet Detail Records
strSQL = "UPDATE TSHistory INNER JOIN (TimeRecords"
strSQL = strSQL & " INNER JOIN TimeSheetDetailON”
strSQL = strSQL & “ TimeRecords.ProjectNumber"
strSQL = strSQL & " = TimeSheetDetail.ProjectNumber)"
strSQL = strSQL & " ON (TSHistory.StaffID = TimeSheetDetail.StaffID)"
strSQL = strSQL & " AND (TSHistory.TSID = TimeRecords.TSID)"
strSQL = strSQL & " SET TimeSheetDetail.DayHours"
strSQL = strSQL & Trim(str(i)) & "= [Hours],"
strSQL = strSQL & " TimeSheetDetail.Status" & Trim(str(i))
strSQL = strSQL & "= IIf([StatusID]=2,1,[StatusID])"
strSQL = strSQL & " WHERE (((TimeRecords.TSID)=" & intTSID
strSQL = strSQL & ") AND ((TimeRecords.PeriodDay)=" & Trim(str(i)) & "));"

db.Execute strSQL, dbFailOnError

Next i

Thanks for your help.

BTW, I'm "Sprinks". Spinks was the guy with no teeth who beat Ali. ;)

Sprinks
 
G

Guest

John,

Thanks for an additional helpful strategy.

Sprinks

John Nurick said:
If I've got to deal with a long SQL statement, I often paste it into a
decent text editor with a fixed width font, and then do a lot of
indenting and line-breaking so I can really see how the thing is
structured and what (if anything) the parentheses are doing.

When I've got it neatly laid out I paste it back into the SQL view of
the query, save it, and in due course Access screws up the layout again.

Although I wish I understood SQL well enough to know WHICH parentheses were
important, I think your suggestion is a very good and practical one. Thanks.

Sprinks

Klatuu said:
Sorry for the typo, Sprinks
One thing I do when I am modifiying the SQL created by the Access query
builder is to remove all the (). I don't know why Access puts all those
parenthises in. They are not (in most cases) necessary. So, I take them
out, test the query, and put some back in if Access complains.

:

Klatuu,

Thanks for your response; there were actually TWO missing right parentheses.
The code then executed without error, but did not update my table as I'd
expected. I don't really understand why. I was able though to simplify the
query by first getting the primary key from the TSHistory table, and it now
works:

' Get TSID Number, unique for every combination of StaffID and
PeriodStartDate
intTSID = DLookup("[TSID]", "TSHistory", "[StaffID]=" &
Me![cboStaffID] & _
" AND [PeriodBeginning]=#" & Me![txtPeriodStartDate] & "#")

For i = 1 To 14

' Update Timesheet Detail Records
strSQL = "UPDATE TSHistory INNER JOIN (TimeRecords"
strSQL = strSQL & " INNER JOIN TimeSheetDetailONâ€
strSQL = strSQL & “ TimeRecords.ProjectNumber"
strSQL = strSQL & " = TimeSheetDetail.ProjectNumber)"
strSQL = strSQL & " ON (TSHistory.StaffID = TimeSheetDetail.StaffID)"
strSQL = strSQL & " AND (TSHistory.TSID = TimeRecords.TSID)"
strSQL = strSQL & " SET TimeSheetDetail.DayHours"
strSQL = strSQL & Trim(str(i)) & "= [Hours],"
strSQL = strSQL & " TimeSheetDetail.Status" & Trim(str(i))
strSQL = strSQL & "= IIf([StatusID]=2,1,[StatusID])"
strSQL = strSQL & " WHERE (((TimeRecords.TSID)=" & intTSID
strSQL = strSQL & ") AND ((TimeRecords.PeriodDay)=" & Trim(str(i)) & "));"

db.Execute strSQL, dbFailOnError

Next i

Thanks for your help.

BTW, I'm "Sprinks". Spinks was the guy with no teeth who beat Ali. ;)

Sprinks
 

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

Similar Threads


Top