Firstly I'll explain how you can do it your way, then why you
shouldn't and finally how it should be done.
With your current set-up you'll find it a lot easier to do it with VBA
code than macro. You'd put exactly the same code in the AfterUpdate
event procedure of each of the Subject 1 Achieved, Subject 2 Achieved,
Subject 3 Achieved etc check box controls on the form. I'm guessing
that you are not too familiar with entering code in event procedures,
so here is how its done:
Select the control in form design view and open its properties sheet
if its not already open. Then select the AfterUpdate event property
in the properties sheet. Click on the 'build' button; that's the one
on the right with 3 dots. Select 'Code Builder' in the dialogue, and
click OK. The VBA window will open at the event procedure with the
first and last lines already in place. Enter the lines of code
between these two existing lines. To do this select the control in
form design view and open its properties sheet if its not already
open. Then select the relevant event property in the properties
sheet. Click on the 'build' button; that's the one on the right with
3 dots. Select 'Code Builder' in the dialogue, and click OK. The VBA
window will open at the event procedure with the first and last lines
already in place. Enter the lines of code between these two existing
lines.
The code for each event procedure would be as follows. For this
example I'm assuming that there are only 3 subjects involved, but
you'll be able to expand the code easily enough:
If Not(Me.[Subject 1 Achieved] =False_
Or Me.[Subject 2 Achieved] =False _
Or Me.[Subject 3 Achieved] =False) Then
Me.[Diploma Achieved] = True
Else
Me.[Diploma Achieved] = False
End If
However, the Diploma Achieved field in the underlying table is
redundant here as its value is computed from the values of the Subject
# Achieved fields. So you can do without the Diploma Achieved field
completely and put an unbound check box control on the form with a
ControlSource property of:
=[Subject 1 Achieved] And [Subject 2 Achieved] And [Subject 3
Achieved]
But that's not the end of the story as the table underlying your form
suffers from a fundamental design flaw. By having multiple fields for
the different subjects you are doing what's known as 'encoding data as
column headings'. A fundamental rule of the relational database model
is that data is stored as values at column positions in tables and in
no other way – its called the 'information principle'.
What you should have are separate tables for each 'entity type'. So
you'd have tables Students and Subjects to start with. The Students
table would have a StudentID primary key column (an autonumber is fine
for this) and columns such as FirstName, LastName, DateOfBirth etc.
Each column represents an 'attribute' of the students entity type.
The Subjects table would have columns SubjectID and Subject. Again an
autonumber is fine for the SubjectID column.
SubjectsAchieved is another entity type, but in this case its a
special kind of entity type as it is also a many-to-many relationship
type between Students and Subjects, i.e. each student can take more
than one subject and each subject is taken by more than one student.
A many-to-many relationship type is modelled by a third table, which
would have columns StudentID, SubjectID (not autonumbers in this case,
just straightforward long integer number data types), DateAchieved
(don't use Date as column name as it’s the name of a built in function
inn Access), SubjectAchieved (a Yes/No (Boolean) column).
The StudentID and SubjectID columns of the SubjectsAchieved table are
foreign key columns which reference the primary keys of the Students
and Subjects table, mapping a row in Students to a row in Subjects.
The DateAchieved and DiplomaAchieved columns represent other
attributes of this entity type.
For data entry you'd use a Students form with a SubjectsAchieved
subform embedded in it, the form and subform being linked on the
StudentID fields. The subform would be in continuous form or
datasheet view and would have control bound to the SubjectID,
DateAchieved and SubjectAchieved fields. The DateAchieved and
SubjectAchieved controls would be a text box and check box
respectively, the SubjectID control a combo box set up as follows:
ControlSource: SubjectID
RowSource: SELECT SubjectID, Subject, FROM Subjects ORDER BY
Subject;
BoundColum: 1
ColumnCount: 2
ColumnWidths: 0cm;8cm
If your units of measurement are imperial rather than metric Access
will automatically convert the last one. The important thing is that
the first dimension is zero to hide the first column and that the
second is at least as wide as the combo box.
To add a subject for a student is simple a case of inserting a new
record in the subform, selecting the subject from the combo box's list
in each case.
Again you don't need a Diploma Achieved field in any of the tables.
You can put an unbound combo box on the Students form with a
ControlSource property such as:
=(DCount("*", "SubjectsAchieved", "Not SubjectAchieved And StudentID =
" & [StudentID]) = 0) And (DCount("*", "SubjectsAchieved", "StudentID
= " & [StudentID]) > 0)
Ken Sheridan
Stafford, England
I have following fields on 1 form:
date ___ Diploma Achieved: [ ] (Yes/No type field)
date ___ Subject 1 Achieved: [ ] (Yes/No type field)
date ___ Subject 2 Achieved: [ ] (Yes/No type field)
date ___ Subject 3 Achieved: [ ] (Yes/No type field)
etc.
What I would like to do is:
When ever a subject achieved is clicked as True, I want a macro to run
which will:
-- Set Diploma Achieved as True if all Subjects are set to True
-- Set the Diploma Achieved date as the maximum of the other `dates,
if Diploma Achieved is True
I know this should be straightforward, but I am new to Access. I have
tried using SetValue without success and have not been able to find
examples similar to what I want to do.
Any hints or links for similar examples?
Regards..- Hide quoted text -
- Show quoted text -