Relationships, forms and command buttons

S

Sue

I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different permutations of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
T

tina

whoa, stop and take a breath. forget forms, forget data entry. you need to
focus on tables and relationship, and make sure they're right BEFORE you go
on to *anything* else.
I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

here's your first and second problems. first, the purpose of normalization
isn't to reduce the number of fields in a table, that's just the usual
side-effect. the purpose of normalization is to ensure that each table
describes one entity, and each field holds atomic data that directly
describes the entity. next, Access does not support direct many-to-many
relationships. in the real world, a many-to-many relationship between two
entities is very common; in Access, these are expressed by two one-to-many
relationships, with each entity being the "one" side of a one-to-many
relationship with a common linking table.

recommend you study some more on relational design principles, to make sure
that your tables and relationships are optimized, before you go any further.
this is the most difficult part of building a relational database, and it's
the dullest - not fun like setting up forms and reports. but if you don't
invest the time and effort now, you'll pay a thousand-fold later in wasted
time and monumental frustration as you struggle to build queries, forms, and
reports on top of a flawed base structure. for more information, see
http://home.att.net/~california.db/tips.html#aTip1.

hth


Sue said:
I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different permutations of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
S

Sue

Hi Tina. Thanks. Maybe I wasn't being clear in my question. My many to many
tables are based on linking tables and, as I said, are working fine (in that
the forms and subforms built from them seem to do just what I want).

Having already done some reading on design principles I thought I was trying
to optimise the table relationships: ie. the one to one journalists table is
intended to remove data that relates only to a subset of the total data set
in the individuals table. So journalists' address details etc remain in the
main table containing address fields etc for all individuals, but fields
related to and only to journalists (for example journalists' areas of
interest re articles) have been removed to a separate one-to-one table as all
entries in here will related to a record in the main table for individuals,
but not all individuals in the main table will be journalists needing fields
relating to journalists interests.

When I say there are too many fields that is because some of them are only
relevant to subsets in that table ( so, based on the reading I've done so
far, I thought it would be good practice to move them into one-to-one tables.
Otherwise there will be lots of blank fields in the main table eg. where
journalists interests aren't completed for individuals who aren't
journalists).

I'm not creating forms for fun but because I've got a crazy short deadline
to write this database at work and thought the table structure I had in place
was fine. I'm not convinced the problem is my table structure, but the fact
I'm not sure how to work with PKs and FKs and whatever else is required when
I try to create forms based on a number of related tables. It's tempting to
put all the data back into just the main tables to avoid these problems but
I'm sure that's not a good solution in relation to the sort of issues you
raise in your response.
. . . . ?

Any additional comments much appreciated.

--
Many thanks,

Sue


tina said:
whoa, stop and take a breath. forget forms, forget data entry. you need to
focus on tables and relationship, and make sure they're right BEFORE you go
on to *anything* else.
I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

here's your first and second problems. first, the purpose of normalization
isn't to reduce the number of fields in a table, that's just the usual
side-effect. the purpose of normalization is to ensure that each table
describes one entity, and each field holds atomic data that directly
describes the entity. next, Access does not support direct many-to-many
relationships. in the real world, a many-to-many relationship between two
entities is very common; in Access, these are expressed by two one-to-many
relationships, with each entity being the "one" side of a one-to-many
relationship with a common linking table.

recommend you study some more on relational design principles, to make sure
that your tables and relationships are optimized, before you go any further.
this is the most difficult part of building a relational database, and it's
the dullest - not fun like setting up forms and reports. but if you don't
invest the time and effort now, you'll pay a thousand-fold later in wasted
time and monumental frustration as you struggle to build queries, forms, and
reports on top of a flawed base structure. for more information, see
http://home.att.net/~california.db/tips.html#aTip1.

hth


Sue said:
I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different permutations of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
T

tina

i can only refer you back to study of relational design principles, Sue.
primary and foreign keys are an integral part of relational design; when you
understand their role in the structure, you'll also understand how they
"fit" when you're building queries, forms, reports.

hth


Sue said:
Hi Tina. Thanks. Maybe I wasn't being clear in my question. My many to many
tables are based on linking tables and, as I said, are working fine (in that
the forms and subforms built from them seem to do just what I want).

Having already done some reading on design principles I thought I was trying
to optimise the table relationships: ie. the one to one journalists table is
intended to remove data that relates only to a subset of the total data set
in the individuals table. So journalists' address details etc remain in the
main table containing address fields etc for all individuals, but fields
related to and only to journalists (for example journalists' areas of
interest re articles) have been removed to a separate one-to-one table as all
entries in here will related to a record in the main table for individuals,
but not all individuals in the main table will be journalists needing fields
relating to journalists interests.

When I say there are too many fields that is because some of them are only
relevant to subsets in that table ( so, based on the reading I've done so
far, I thought it would be good practice to move them into one-to-one tables.
Otherwise there will be lots of blank fields in the main table eg. where
journalists interests aren't completed for individuals who aren't
journalists).

I'm not creating forms for fun but because I've got a crazy short deadline
to write this database at work and thought the table structure I had in place
was fine. I'm not convinced the problem is my table structure, but the fact
I'm not sure how to work with PKs and FKs and whatever else is required when
I try to create forms based on a number of related tables. It's tempting to
put all the data back into just the main tables to avoid these problems but
I'm sure that's not a good solution in relation to the sort of issues you
raise in your response.
. . . . ?

Any additional comments much appreciated.

--
Many thanks,

Sue


tina said:
whoa, stop and take a breath. forget forms, forget data entry. you need to
focus on tables and relationship, and make sure they're right BEFORE you go
on to *anything* else.
I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

here's your first and second problems. first, the purpose of normalization
isn't to reduce the number of fields in a table, that's just the usual
side-effect. the purpose of normalization is to ensure that each table
describes one entity, and each field holds atomic data that directly
describes the entity. next, Access does not support direct many-to-many
relationships. in the real world, a many-to-many relationship between two
entities is very common; in Access, these are expressed by two one-to-many
relationships, with each entity being the "one" side of a one-to-many
relationship with a common linking table.

recommend you study some more on relational design principles, to make sure
that your tables and relationships are optimized, before you go any further.
this is the most difficult part of building a relational database, and it's
the dullest - not fun like setting up forms and reports. but if you don't
invest the time and effort now, you'll pay a thousand-fold later in wasted
time and monumental frustration as you struggle to build queries, forms, and
reports on top of a flawed base structure. for more information, see
http://home.att.net/~california.db/tips.html#aTip1.

hth


Sue said:
I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the
info
on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different
permutations
of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
K

Ken Sheridan

Sue:

Your use of one-to-one relationship types appears to be quite correct in
principle as they are modelling types and sub-types (sometimes referred to as
classes and sub-classes). These are characterized by each sub-type sharing
all the attributes of its (super) type, but not of other sub-types. In your
example type Journalists shares the address attributes of (super) type
Individuals, but not the attributes of another sub-type which are specific to
that sub-type and thus represented by columns in the table which models that
sub-type. So I think that your are right in concluding that logical the
basis of your model is OK. One important point to note, however, is that
while the IDIndividual column of the (super) type table can be an autonumber,
the IDIndividual key of any sub-type tables must not be, but a
straightforward long integer number data type.

1. As far as your problem with the Journalists form is concerned, from the
error your are getting its sounds like you are not passing the value of the
current row in the tblAllIndividuals table (i.e. the Individuals form's
current record) when opening the Journalsists form. The sort of code you'd
need for the button would be:

Const conFORM = "frmJournalists"
Const conMESSAGE = "No current individual record."
Dim strCriteria As String
Dim varIDIndividual As Variant

varIDIndividual = Me.IDIndividual

If Not IsNull(varIDIndividual) Then
strCriteria = "IDIndividual = " & Me.IDIndividual
' ensure current Individuals record is saved
me.Dirty = False
' open journalists form
DoCmd.OpenForm conform, _
WhereCondition:=strCriteria, _
WindowMode:=acDialog, _
OpenArgs:=varIDIndividual
Else
MsgBox conMESSAGE, vbExclamation, "Invalid Operation"
End If


In the frmJournalists form's Open event procedure put:

If Not IsNull(Me.OpenArgs) Then
Me.IDIndividual.DefaultValue = """" & Me.OpenArgs & """"
End If

Some explanation: The code in the button's event procedure opens the
journalists form in dialogue mode. This means it has to be close before
returning to the individuals form, which prevents it being left open
inadvertently. If you don't want this, but prefer to be able to move back
and forth between the forms with the mouse then just take out the
'WindowMode:=acDialog, _' line.

The journalists form is opened filtered to the current individual by the
WhereCondition argument. The value of the key is also passed as the OpenArgs
property, and in the journalists form's Open event procedure this is then
used to set the DefaultValue property of the IDIndividual control (you can
set this control's Visible property to False if you don't want it to show,
which normally would be the case). By setting the DefaultValue property
rather than the Value this does not initiate a new journalists record if none
exists already until the user adds some other data, so they can back out
simply by closing the form if they decide not to add the new record.

2. As for tblBanks, I suspect you might not have things quite right here.
The relationship with tblAllIndividuals would be one-to-many if each
individual belongs to one bank only (or at least that's all you are
recording) and you don't need to record anything other than the fact that
they belong to that bank. For this you'd simply have a BankID foreign key
column in tblAllIndividuals referencing the primary key of tblBanks. You'd
not use a button to open a separate form, however, but a combo box on the
individuals form bound to the BankID column and set up along these lines:

ControlSource: BankID

RowSource: SELECT BankID, Bank FROM tblBanks ORDER BY Bank;

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.

RowSource: SELECT EmployeeID, FirstName & " " & LastName AS FullName
FROM tblEmployees ORDER BY LastName, FirstName;

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.

However, if you want to record more than one bank per individual and/or you
want to record details of their relationship with the bank, e.g. account
number(s) then you'd need a table to model the relationship type as it
includes other attributes (relationship type are really just a special kind
of entity type, so can also have attributes). For this you'd need a table
with foreign key columns IDIndividual and BankID referencing the keys of the
other two tables. Together these two columns make up the table's composite
primary key (unless you are recording several accounts per individual at one
bank, in which case the account number would also be part of the key). If
you are only recording one bank and one account per individual you should
also index the IDIndividual column uniquely as in this case the table is
modelling a one-to-many relationship type rather than many-to-many. You'd no
longer need the BankID foreign key in tblAllIndividuals of course.

With this scenario you could open a form bound to the new table modelling
the relationship type between individuals and banks in exactly the same way
as you opened the journalists form above, but a more usual scenario would be
to have the form as a subform within the individuals form, linked on the
IDIndividual column. The linked form or subform would contain a combo box
linked to the BankID column set up exactly as described above.

You could of course use a subform bound to the journalists table rather than
opening a separate linked form with code. To save space each subform could
be on separate pages of a tab control in the main individuals form.

I hope I've couched this in sufficiently layman's language, without
oversimplifying it and thereby losing clarity (I'm always mindful of
Einstein's answer when asked how simply one should explain the Theory of
General Relativity – 'As simply as possible, but no more so'). If there's
anything you are unsure of please post back.

Ken Sheridan
Stafford, England

Sue said:
Hi Tina. Thanks. Maybe I wasn't being clear in my question. My many to many
tables are based on linking tables and, as I said, are working fine (in that
the forms and subforms built from them seem to do just what I want).

Having already done some reading on design principles I thought I was trying
to optimise the table relationships: ie. the one to one journalists table is
intended to remove data that relates only to a subset of the total data set
in the individuals table. So journalists' address details etc remain in the
main table containing address fields etc for all individuals, but fields
related to and only to journalists (for example journalists' areas of
interest re articles) have been removed to a separate one-to-one table as all
entries in here will related to a record in the main table for individuals,
but not all individuals in the main table will be journalists needing fields
relating to journalists interests.

When I say there are too many fields that is because some of them are only
relevant to subsets in that table ( so, based on the reading I've done so
far, I thought it would be good practice to move them into one-to-one tables.
Otherwise there will be lots of blank fields in the main table eg. where
journalists interests aren't completed for individuals who aren't
journalists).

I'm not creating forms for fun but because I've got a crazy short deadline
to write this database at work and thought the table structure I had in place
was fine. I'm not convinced the problem is my table structure, but the fact
I'm not sure how to work with PKs and FKs and whatever else is required when
I try to create forms based on a number of related tables. It's tempting to
put all the data back into just the main tables to avoid these problems but
I'm sure that's not a good solution in relation to the sort of issues you
raise in your response.
. . . . ?

Any additional comments much appreciated.

--
Many thanks,

Sue


tina said:
whoa, stop and take a breath. forget forms, forget data entry. you need to
focus on tables and relationship, and make sure they're right BEFORE you go
on to *anything* else.
I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

here's your first and second problems. first, the purpose of normalization
isn't to reduce the number of fields in a table, that's just the usual
side-effect. the purpose of normalization is to ensure that each table
describes one entity, and each field holds atomic data that directly
describes the entity. next, Access does not support direct many-to-many
relationships. in the real world, a many-to-many relationship between two
entities is very common; in Access, these are expressed by two one-to-many
relationships, with each entity being the "one" side of a one-to-many
relationship with a common linking table.

recommend you study some more on relational design principles, to make sure
that your tables and relationships are optimized, before you go any further.
this is the most difficult part of building a relational database, and it's
the dullest - not fun like setting up forms and reports. but if you don't
invest the time and effort now, you'll pay a thousand-fold later in wasted
time and monumental frustration as you struggle to build queries, forms, and
reports on top of a flawed base structure. for more information, see
http://home.att.net/~california.db/tips.html#aTip1.

hth


Sue said:
I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different permutations of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
S

Sue

Hi Ken,

That was really helpful and clearly explained, albeit slightly over my head.
I may come back to you for clarification once I've tried to put it into
practice if that's ok.

A general question. As per my original post, I've been charged with creating
a reasonably complicated database with what I now realise is a level of
training fairly inadequate to the task in hand (eg. I don't know anything
about code). Given the fact I have an extremely short deadline which isn't
moveable, what do you think about the idea of keeping a lot of the data in
two large tables (plus a few many to manys linking to each of these) thereby
decreasing the need for code which I am unable to write? I've read a lot on
the site about people doing this and the consensus seems to be that if it
works, and you don't have the skills to do anything else, then fine albeit
there are much better ways of storing and managing data if you know how. If I
contravene some (not all) normalisation conventions in the interests of
pragmatism will I end up regretting it: for example, will the database be
really slow when we've entered lots of data in it. Will it be more or less
likely to throw up error messages if I keep things simple in this way? Do you
need more info to answer this question.

Your interest and time in helping out much appreciated!
--
Many thanks,

Sue


Sue said:
I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations - creating
the form from tables, creating it from queries, and different permutations of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to manage
data entry and viewing for banks to flag up if someone is the second person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
S

Sue

PS. Me again. I have couple more questions now if that's ok.

First, re the code you suggested for the command button to open
frmJournalists, does it replace all the existing code (shown below) or just
some of it. If just some of it, what does it replace and where is it inserted?

Const conFORM = "frmJournalists"
Const conMESSAGE = "No current individual record."
Dim strCriteria As String
Dim varIDIndividual As Variant

varIDIndividual = Me.IDIndividual

If Not IsNull(varIDIndividual) Then
strCriteria = "IDIndividual = " & Me.IDIndividual
' ensure current Individuals record is saved
Me.Dirty = False
' open journalists form
DoCmd.OpenForm conFORM, _
WhereCondition:=strCriteria, _
WindowMode:=acDialog, _
OpenArgs:=varIDIndividual
Else
MsgBox conMESSAGE, vbExclamation, "Invalid Operation"
End If



End Sub
Private Sub cmdOpenfrmJournalists_Click()
On Error GoTo Err_cmdOpenfrmJournalists_Click

Dim stDocName As String
Dim stLinkCriteria As String

stDocName = "frmJournalists"

stLinkCriteria = "[IDIndividual]=" & Me![IDIndividual]
DoCmd.OpenForm stDocName, , , stLinkCriteria

Exit_cmdOpenfrmJournalists_Click:
Exit Sub

Err_cmdOpenfrmJournalists_Click:
MsgBox Err.Description
Resume Exit_cmdOpenfrmJournalists_Click

End Sub

Re the question of banks, I am assuming that we will only record one bank
per individual to try and keep things simple. This will almost certainly be
the case. If they change their bank account, we'll just overwrite their bank
details as it won't be necessary to hold previous account details. Am I right
in assuming from your response that I will have a a linking table with
IDIndividual and IDBank as foreign keys (and in long integer number format)
and that tblBanks will contain the bank name, address details, sort code, ac
no and bank reference? I tend to give linking tables their own auto number
primary key (so they have 3 fields in total). Should I do that here? Should I
do it anywhere?

Related to setting up the relationship between individuals and banks, I've
already set up many to many tables (tblIndividuals and tblStandingOrders,
tblIndividuals and tblCAFGAYEDons) with linking tables with an autonumber PK
and FKs on the principles above. This allows a subform on the individuals
main form allowing viewing of each donation and automated subtotals. This all
works fine. Is it ok for the bank details to be in a separate many to many
relationship with tblIndividuals that the donations tables as above? Will
this cause any complications when I try to create a form to enter standing
orders using individuals's bank reference from the tblBanks to find their
record. (Don't want to use the existing subform for data entry of standing
orders, just for viewing, as too many clicks otherwise). Will a query bring
this all together for a data entry form without any complications or am I
likely to need more code if I take this approach?

I know this is a detailed question. Hope that's acceptable in this type of
forum . . .? Certainly it's invaluable for me if you are able to offer any
further tips.
--
Many thanks,

Sue


Ken Sheridan said:
Sue:

Your use of one-to-one relationship types appears to be quite correct in
principle as they are modelling types and sub-types (sometimes referred to as
classes and sub-classes). These are characterized by each sub-type sharing
all the attributes of its (super) type, but not of other sub-types. In your
example type Journalists shares the address attributes of (super) type
Individuals, but not the attributes of another sub-type which are specific to
that sub-type and thus represented by columns in the table which models that
sub-type. So I think that your are right in concluding that logical the
basis of your model is OK. One important point to note, however, is that
while the IDIndividual column of the (super) type table can be an autonumber,
the IDIndividual key of any sub-type tables must not be, but a
straightforward long integer number data type.

1. As far as your problem with the Journalists form is concerned, from the
error your are getting its sounds like you are not passing the value of the
current row in the tblAllIndividuals table (i.e. the Individuals form's
current record) when opening the Journalsists form. The sort of code you'd
need for the button would be:

Const conFORM = "frmJournalists"
Const conMESSAGE = "No current individual record."
Dim strCriteria As String
Dim varIDIndividual As Variant

varIDIndividual = Me.IDIndividual

If Not IsNull(varIDIndividual) Then
strCriteria = "IDIndividual = " & Me.IDIndividual
' ensure current Individuals record is saved
me.Dirty = False
' open journalists form
DoCmd.OpenForm conform, _
WhereCondition:=strCriteria, _
WindowMode:=acDialog, _
OpenArgs:=varIDIndividual
Else
MsgBox conMESSAGE, vbExclamation, "Invalid Operation"
End If


In the frmJournalists form's Open event procedure put:

If Not IsNull(Me.OpenArgs) Then
Me.IDIndividual.DefaultValue = """" & Me.OpenArgs & """"
End If

Some explanation: The code in the button's event procedure opens the
journalists form in dialogue mode. This means it has to be close before
returning to the individuals form, which prevents it being left open
inadvertently. If you don't want this, but prefer to be able to move back
and forth between the forms with the mouse then just take out the
'WindowMode:=acDialog, _' line.

The journalists form is opened filtered to the current individual by the
WhereCondition argument. The value of the key is also passed as the OpenArgs
property, and in the journalists form's Open event procedure this is then
used to set the DefaultValue property of the IDIndividual control (you can
set this control's Visible property to False if you don't want it to show,
which normally would be the case). By setting the DefaultValue property
rather than the Value this does not initiate a new journalists record if none
exists already until the user adds some other data, so they can back out
simply by closing the form if they decide not to add the new record.

2. As for tblBanks, I suspect you might not have things quite right here.
The relationship with tblAllIndividuals would be one-to-many if each
individual belongs to one bank only (or at least that's all you are
recording) and you don't need to record anything other than the fact that
they belong to that bank. For this you'd simply have a BankID foreign key
column in tblAllIndividuals referencing the primary key of tblBanks. You'd
not use a button to open a separate form, however, but a combo box on the
individuals form bound to the BankID column and set up along these lines:

ControlSource: BankID

RowSource: SELECT BankID, Bank FROM tblBanks ORDER BY Bank;

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.

RowSource: SELECT EmployeeID, FirstName & " " & LastName AS FullName
FROM tblEmployees ORDER BY LastName, FirstName;

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.

However, if you want to record more than one bank per individual and/or you
want to record details of their relationship with the bank, e.g. account
number(s) then you'd need a table to model the relationship type as it
includes other attributes (relationship type are really just a special kind
of entity type, so can also have attributes). For this you'd need a table
with foreign key columns IDIndividual and BankID referencing the keys of the
other two tables. Together these two columns make up the table's composite
primary key (unless you are recording several accounts per individual at one
bank, in which case the account number would also be part of the key). If
you are only recording one bank and one account per individual you should
also index the IDIndividual column uniquely as in this case the table is
modelling a one-to-many relationship type rather than many-to-many. You'd no
longer need the BankID foreign key in tblAllIndividuals of course.

With this scenario you could open a form bound to the new table modelling
the relationship type between individuals and banks in exactly the same way
as you opened the journalists form above, but a more usual scenario would be
to have the form as a subform within the individuals form, linked on the
IDIndividual column. The linked form or subform would contain a combo box
linked to the BankID column set up exactly as described above.

You could of course use a subform bound to the journalists table rather than
opening a separate linked form with code. To save space each subform could
be on separate pages of a tab control in the main individuals form.

I hope I've couched this in sufficiently layman's language, without
oversimplifying it and thereby losing clarity (I'm always mindful of
Einstein's answer when asked how simply one should explain the Theory of
General Relativity – 'As simply as possible, but no more so'). If there's
anything you are unsure of please post back.

Ken Sheridan
Stafford, England

Sue said:
Hi Tina. Thanks. Maybe I wasn't being clear in my question. My many to many
tables are based on linking tables and, as I said, are working fine (in that
the forms and subforms built from them seem to do just what I want).

Having already done some reading on design principles I thought I was trying
to optimise the table relationships: ie. the one to one journalists table is
intended to remove data that relates only to a subset of the total data set
in the individuals table. So journalists' address details etc remain in the
main table containing address fields etc for all individuals, but fields
related to and only to journalists (for example journalists' areas of
interest re articles) have been removed to a separate one-to-one table as all
entries in here will related to a record in the main table for individuals,
but not all individuals in the main table will be journalists needing fields
relating to journalists interests.

When I say there are too many fields that is because some of them are only
relevant to subsets in that table ( so, based on the reading I've done so
far, I thought it would be good practice to move them into one-to-one tables.
Otherwise there will be lots of blank fields in the main table eg. where
journalists interests aren't completed for individuals who aren't
journalists).

I'm not creating forms for fun but because I've got a crazy short deadline
to write this database at work and thought the table structure I had in place
was fine. I'm not convinced the problem is my table structure, but the fact
I'm not sure how to work with PKs and FKs and whatever else is required when
I try to create forms based on a number of related tables. It's tempting to
put all the data back into just the main tables to avoid these problems but
I'm sure that's not a good solution in relation to the sort of issues you
raise in your response.
. . . . ?

Any additional comments much appreciated.

--
Many thanks,

Sue


tina said:
whoa, stop and take a breath. forget forms, forget data entry. you need to
focus on tables and relationship, and make sure they're right BEFORE you go
on to *anything* else.

I am trying to normalise the database, and reduce the number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

here's your first and second problems. first, the purpose of normalization
isn't to reduce the number of fields in a table, that's just the usual
side-effect. the purpose of normalization is to ensure that each table
describes one entity, and each field holds atomic data that directly
describes the entity. next, Access does not support direct many-to-many
relationships. in the real world, a many-to-many relationship between two
entities is very common; in Access, these are expressed by two one-to-many
relationships, with each entity being the "one" side of a one-to-many
relationship with a common linking table.

recommend you study some more on relational design principles, to make sure
that your tables and relationships are optimized, before you go any further.
this is the most difficult part of building a relational database, and it's
the dullest - not fun like setting up forms and reports. but if you don't
invest the time and effort now, you'll pay a thousand-fold later in wasted
time and monumental frustration as you struggle to build queries, forms, and
reports on top of a flawed base structure. for more information, see
http://home.att.net/~california.db/tips.html#aTip1.

hth


I am building my first database. It has two main tables linked in many to
many relationship - tblIndividuals and tblOrganisations - and a number of
linked tables. I am trying to normalise the database, and reduce the
number
of fields in the main tables. However, I'm hitting up against a couple of
problems. Many to many relationships are working fine.

However, the individuals main table has far too many fields some of which
relate only to subsets; eg. journalists. I tried separating out the info
on
journalists and putting it into a separate tblJournalists in a one-to-one
join with tblAllIndividuals. I then tried creating a form for individuals
with a command button to open a separate form for entering/viewing info
specific to journalists. However, when I try to open the journalist form I
get an error message as follows: "Syntax error (missing operator) in query
expression '[IDIndividual]='. I tried using different combinations -
creating
the form from tables, creating it from queries, and different permutations
of
the matching fields - PK to PK, PK to FK, etc but I just get variations of
the same sytnax error.

Am I missing something obvious? Is it to do with the type of join between
the two tables? Or something else entirely?

It would be really good to understand this and make it work as the
principle
will hold good for removing other fields from both the main tables.

2. I created a tblBanks in a one to many relationship with
tblAllIndividuals, and then created a frmAllIndividuals and another form
frmBanks and a command button to open the latter from the former. However,
when I try to move from form to design view in the former, I get a message
saying "You cannot add or change a record because a related record is
required in tblBanks". Again have I missed something really obvious here?
What? And how should I remedy it?

Also, once that particular problem is sorted, what is the best way to
manage
data entry and viewing for banks to flag up if someone is the second
person
belonging to that particular bank??

Any tips much appreciated. In layman's language please as I am very new to
this.
 
K

Ken Sheridan

Sue:

I'll take your points one by one:
I know this is a detailed question. Hope that's acceptable in this type of
forum . . .? Certainly it's invaluable for me if you are able to offer any
further tips.

There's no extra charge for detailed questions ):> Obviously you should try
and work things out for yourself as much as possible as that way you'll learn
a lot more than merely repeating parrot fashion whatever we give you, and
once we've explained something in relation to a particular task you should
look for where else the same principles might apply. You'll find that some
respondents here will give short replies to a large number of posts, pointing
people in the right general direction. I on the other hand prefer to go into
more detail with a limited number of selected posts. Something which helps
us help you, though, is if you tell us what you are trying to achieve in
terms of the real world scenario which the database is modelling rather than
asking how to do a particular thing in terms of the database objects itself.
If you ask something 'how do I do A, B and C by means of a list box on a
form?' then this might well be a 'road to Dublin' question to which we would
answer, and I speak as an Irishman, 'If I were you, I wouldn't start from
here'.
A general question. As per my original post, I've been charged with creating
a reasonably complicated database with what I now realise is a level of
training fairly inadequate to the task in hand (eg. I don't know anything
about code). Given the fact I have an extremely short deadline which isn't
moveable, what do you think about the idea of keeping a lot of the data in
two large tables (plus a few many to manys linking to each of these) thereby
decreasing the need for code which I am unable to write? I've read a lot on
the site about people doing this and the consensus seems to be that if it
works, and you don't have the skills to do anything else, then fine albeit
there are much better ways of storing and managing data if you know how. If I
contravene some (not all) normalisation conventions in the interests of
pragmatism will I end up regretting it: for example, will the database be
really slow when we've entered lots of data in it. Will it be more or less
likely to throw up error messages if I keep things simple in this way? Do you
need more info to answer this question.

You won't get runtime errors but your are more likely to have inconsistent
data entered if the tables are not fully normalized. Normalization
eliminates redundancy so that each 'fact' is stated once only in the
database. That way the 'fact' cannot be inconsistently entered, whereas if
the same 'fact' is entered more than once there is the risk of it being
entered in different ways each time, either incorrectly or just differently
e.g. my name could be entered as Ken Sheridan, Kenneth Sheridan or K W
Sheridan, and I did in fact find myself in three separate guises in one
database as author of technical articles in my own sphere of work,
environmental planning. As far as the database is concerned there are three
different authors involved here!

However, many databases do exhibit a degree of redundancy, and you can see
an example in the case of the sample Northwind database which comes with
Access. An example of its lack of proper normalization can be found in its
Customers table. You'll see that this has City, Region and Country columns
so we are told numerous times that São Paulo is in SP region (as is Resende)
and that SP region is in Brazil. Not only does this require repetitive data
entry, but more importantly it opens up the risk of inconsistent data, e.g.
it would be perfectly possible to put São Paulo in California in one row and
California in Ireland! Proper normalization as I described above would
prevent this as the fact that São Paulo is in SP region would be stored only
once in the database as would the fact that SP region is in Brazil and
California is in the USA.

The Customers table from Northwind nevertheless 'works', of course, but it
is open to bad data being entered, so the same would be true with your
tables. It is best to aim for a normalized design, otherwise you are
sacrificing the advantages of a relational database compared with a
spreadsheet. At the end of the day its for you to decide to what degree you
want to pursue a well normalized model.
First, re the code you suggested for the command button to open
frmJournalists, does it replace all the existing code (shown below) or just
some of it. If just some of it, what does it replace and where is it inserted?

Const conFORM = "frmJournalists"
Const conMESSAGE = "No current individual record."
Dim strCriteria As String
Dim varIDIndividual As Variant

varIDIndividual = Me.IDIndividual

If Not IsNull(varIDIndividual) Then
strCriteria = "IDIndividual = " & Me.IDIndividual
' ensure current Individuals record is saved
Me.Dirty = False
' open journalists form
DoCmd.OpenForm conFORM, _
WhereCondition:=strCriteria, _
WindowMode:=acDialog, _
OpenArgs:=varIDIndividual
Else
MsgBox conMESSAGE, vbExclamation, "Invalid Operation"
End If



End Sub
Private Sub cmdOpenfrmJournalists_Click()
On Error GoTo Err_cmdOpenfrmJournalists_Click

Dim stDocName As String
Dim stLinkCriteria As String

stDocName = "frmJournalists"

stLinkCriteria = "[IDIndividual]=" & Me![IDIndividual]
DoCmd.OpenForm stDocName, , , stLinkCriteria

Exit_cmdOpenfrmJournalists_Click:
Exit Sub

Err_cmdOpenfrmJournalists_Click:
MsgBox Err.Description
Resume Exit_cmdOpenfrmJournalists_Click

End Sub

My code replaces your original code with the exception of the first two and
last six lines, so it goes between these:

Private Sub cmdOpenfrmJournalists_Click()
On Error GoTo Err_cmdOpenfrmJournalists_Click

'<<<my code goes in here>>>'

Exit_cmdOpenfrmJournalists_Click:
Exit Sub

Err_cmdOpenfrmJournalists_Click:
MsgBox Err.Description
Resume Exit_cmdOpenfrmJournalists_Click

End Sub

Essentially mine does the same thing as the wizard generated code, but with
a few extra whistles and bells. The code I gave you for the frmJournalists
form's Open event procedure goes into new procedure in that form's module of
course as currently it won't have any code.
Re the question of banks, I am assuming that we will only record one bank
per individual to try and keep things simple. This will almost certainly be
the case. If they change their bank account, we'll just overwrite their bank
details as it won't be necessary to hold previous account details. Am I right
in assuming from your response that I will have a a linking table with
IDIndividual and IDBank as foreign keys (and in long integer number format)
and that tblBanks will contain the bank name, address details, sort code, ac
no and bank reference? I tend to give linking tables their own auto number
primary key (so they have 3 fields in total). Should I do that here? Should I
do it anywhere?

Related to setting up the relationship between individuals and banks, I've
already set up many to many tables (tblIndividuals and tblStandingOrders,
tblIndividuals and tblCAFGAYEDons) with linking tables with an autonumber PK
and FKs on the principles above. This allows a subform on the individuals
main form allowing viewing of each donation and automated subtotals. This all
works fine. Is it ok for the bank details to be in a separate many to many
relationship with tblIndividuals that the donations tables as above? Will
this cause any complications when I try to create a form to enter standing
orders using individuals's bank reference from the tblBanks to find their
record. (Don't want to use the existing subform for data entry of standing
orders, just for viewing, as too many clicks otherwise). Will a query bring
this all together for a data entry form without any complications or am I
likely to need more code if I take this approach?

Its in this part of the database where I think you are going astray. Now,
you already know that each table represents an 'entity type' and each column
in a table represents an 'attribute type' of that entity type, for instance
Sue and ken are attributes of type FirstName (i.e., a column) of entity type
People (i.e. a table). Banks is an entity type, so you correctly have a
table tblBanks. Each row represents one bank. Attributes of the entity type
are things like its name and address, so there'd be columns for these. Each
bank will have many customers, so the relationship with tblIndividuals is
one-to-many. In the jargon the table on the 'one' side is known as the
'referenced table' and that on the 'many' side as the 'referencing' table.
Sometimes folksy terms like 'parent' and 'child' are used instead, but I
prefer the more formal terms because they tell you exactly how the
relationship works, the tblIndividuals table 'refernces' the tblBanks table,
which it does by having a foreign key column BankID in tblIndividuals which
refernces the primary key column BankID in tblBanks. You have it the other
way around, which as you've discovered means that a bank can have only one
customer. Now this would cut down the queues at the teller's window but
would not be good business.

Now you could simply put a BankID column in tblIndividuals to act as a
foreign key, along with other columns like AccountNumber etc., but even
though this is a one-to-many relationship type, as you only want to record
one set of bank details per person, I'd model it in the same way as if it
were a many-to-many relationship type by having a 'linking' table (again
while folksy terms like this are OK, try and think of these sort of tables as
what they really are, models of a relationship type). Although a one-to-many
relationship is not normally modelled by a table, but by a foreign key column
in the referencing table, there is absolutely no reason why they should not
be, and their use in this way is recommended by Chris date, one of the
greatest of the great and the good of the relational database world, as a
means of avoiding Null foreign keys (in your case if an individual has no
bank account).

The relationship type between individuals and banks is really 'Accounts' as
its through their account that a person is related to a bank, so the table
could be called BankAccounts say. Once we understand that a person's account
is the relationship with the bank its clear where things like the sort code,
account number etc go. These are of course attributes of the account so they
are columns in the BankAccounts table along with the two foreign key columns
IDIndividual and BankID. If you definitely only want to record one bank
account per individual then index the IDIndividual column in BankAccounts
uniquely. Neither tblIndividuals nor tblBanks will have a foreign key
referencing the other of course as the relationship is via the BankAccounts
table.

When it comes to things like standing orders etc I can't be absolutely
categoric about how these should be handled on the basis of the information
you've so far provided. I'm Irish remember, and you are asking me which way
is the road to Dublin! Might there be multiple standing order per
individual? Do you need to record that they've been paid and on which dates?
The same sort of questions apply to other financial instruments. I'd need
to know in a lot more detail how such things fit in to the real world
business model in which the database will operate. From what you say,
however, I think you've probably got it right. Should you decide to record
more than one bank account per person, though, you'd need to add a column for
the account number to each of the tables which model the relationships
between standing orders and individuals. In fact the relationship is really
with BankAccounts rather than tblIndividuals as an individual can only set
up a standing order if they have an account to draw on. So if you do decide
to record more than one account per person the relationship would be on both
the IDIndividual and AccountNumber columns, rather than solely on the
IDIndividual column as at present.

Ken Sheridan
Stafford, England
 
S

Sue

Ken, if no-one has ever told you before (and I am pretty certain they have)
you are a shining star!!

I'm not very good at sifting through the mass of theoretical info out there
and figuring out which bits apply in a specific situation. In all honesty,
it's rather overwhelming for a beginner. But with a couple of detailed
practical examples it all starts to come together in a way that allows me to
start experimenting a little more. I appreciate your approach to this.
Cheers!!
--
Many thanks,

Sue


Ken Sheridan said:
Sue:

I'll take your points one by one:
I know this is a detailed question. Hope that's acceptable in this type of
forum . . .? Certainly it's invaluable for me if you are able to offer any
further tips.

There's no extra charge for detailed questions ):> Obviously you should try
and work things out for yourself as much as possible as that way you'll learn
a lot more than merely repeating parrot fashion whatever we give you, and
once we've explained something in relation to a particular task you should
look for where else the same principles might apply. You'll find that some
respondents here will give short replies to a large number of posts, pointing
people in the right general direction. I on the other hand prefer to go into
more detail with a limited number of selected posts. Something which helps
us help you, though, is if you tell us what you are trying to achieve in
terms of the real world scenario which the database is modelling rather than
asking how to do a particular thing in terms of the database objects itself.
If you ask something 'how do I do A, B and C by means of a list box on a
form?' then this might well be a 'road to Dublin' question to which we would
answer, and I speak as an Irishman, 'If I were you, I wouldn't start from
here'.
A general question. As per my original post, I've been charged with creating
a reasonably complicated database with what I now realise is a level of
training fairly inadequate to the task in hand (eg. I don't know anything
about code). Given the fact I have an extremely short deadline which isn't
moveable, what do you think about the idea of keeping a lot of the data in
two large tables (plus a few many to manys linking to each of these) thereby
decreasing the need for code which I am unable to write? I've read a lot on
the site about people doing this and the consensus seems to be that if it
works, and you don't have the skills to do anything else, then fine albeit
there are much better ways of storing and managing data if you know how. If I
contravene some (not all) normalisation conventions in the interests of
pragmatism will I end up regretting it: for example, will the database be
really slow when we've entered lots of data in it. Will it be more or less
likely to throw up error messages if I keep things simple in this way? Do you
need more info to answer this question.

You won't get runtime errors but your are more likely to have inconsistent
data entered if the tables are not fully normalized. Normalization
eliminates redundancy so that each 'fact' is stated once only in the
database. That way the 'fact' cannot be inconsistently entered, whereas if
the same 'fact' is entered more than once there is the risk of it being
entered in different ways each time, either incorrectly or just differently
e.g. my name could be entered as Ken Sheridan, Kenneth Sheridan or K W
Sheridan, and I did in fact find myself in three separate guises in one
database as author of technical articles in my own sphere of work,
environmental planning. As far as the database is concerned there are three
different authors involved here!

However, many databases do exhibit a degree of redundancy, and you can see
an example in the case of the sample Northwind database which comes with
Access. An example of its lack of proper normalization can be found in its
Customers table. You'll see that this has City, Region and Country columns
so we are told numerous times that São Paulo is in SP region (as is Resende)
and that SP region is in Brazil. Not only does this require repetitive data
entry, but more importantly it opens up the risk of inconsistent data, e.g.
it would be perfectly possible to put São Paulo in California in one row and
California in Ireland! Proper normalization as I described above would
prevent this as the fact that São Paulo is in SP region would be stored only
once in the database as would the fact that SP region is in Brazil and
California is in the USA.

The Customers table from Northwind nevertheless 'works', of course, but it
is open to bad data being entered, so the same would be true with your
tables. It is best to aim for a normalized design, otherwise you are
sacrificing the advantages of a relational database compared with a
spreadsheet. At the end of the day its for you to decide to what degree you
want to pursue a well normalized model.
First, re the code you suggested for the command button to open
frmJournalists, does it replace all the existing code (shown below) or just
some of it. If just some of it, what does it replace and where is it inserted?

Const conFORM = "frmJournalists"
Const conMESSAGE = "No current individual record."
Dim strCriteria As String
Dim varIDIndividual As Variant

varIDIndividual = Me.IDIndividual

If Not IsNull(varIDIndividual) Then
strCriteria = "IDIndividual = " & Me.IDIndividual
' ensure current Individuals record is saved
Me.Dirty = False
' open journalists form
DoCmd.OpenForm conFORM, _
WhereCondition:=strCriteria, _
WindowMode:=acDialog, _
OpenArgs:=varIDIndividual
Else
MsgBox conMESSAGE, vbExclamation, "Invalid Operation"
End If



End Sub
Private Sub cmdOpenfrmJournalists_Click()
On Error GoTo Err_cmdOpenfrmJournalists_Click

Dim stDocName As String
Dim stLinkCriteria As String

stDocName = "frmJournalists"

stLinkCriteria = "[IDIndividual]=" & Me![IDIndividual]
DoCmd.OpenForm stDocName, , , stLinkCriteria

Exit_cmdOpenfrmJournalists_Click:
Exit Sub

Err_cmdOpenfrmJournalists_Click:
MsgBox Err.Description
Resume Exit_cmdOpenfrmJournalists_Click

End Sub

My code replaces your original code with the exception of the first two and
last six lines, so it goes between these:

Private Sub cmdOpenfrmJournalists_Click()
On Error GoTo Err_cmdOpenfrmJournalists_Click

'<<<my code goes in here>>>'

Exit_cmdOpenfrmJournalists_Click:
Exit Sub

Err_cmdOpenfrmJournalists_Click:
MsgBox Err.Description
Resume Exit_cmdOpenfrmJournalists_Click

End Sub

Essentially mine does the same thing as the wizard generated code, but with
a few extra whistles and bells. The code I gave you for the frmJournalists
form's Open event procedure goes into new procedure in that form's module of
course as currently it won't have any code.
Re the question of banks, I am assuming that we will only record one bank
per individual to try and keep things simple. This will almost certainly be
the case. If they change their bank account, we'll just overwrite their bank
details as it won't be necessary to hold previous account details. Am I right
in assuming from your response that I will have a a linking table with
IDIndividual and IDBank as foreign keys (and in long integer number format)
and that tblBanks will contain the bank name, address details, sort code, ac
no and bank reference? I tend to give linking tables their own auto number
primary key (so they have 3 fields in total). Should I do that here? Should I
do it anywhere?

Related to setting up the relationship between individuals and banks, I've
already set up many to many tables (tblIndividuals and tblStandingOrders,
tblIndividuals and tblCAFGAYEDons) with linking tables with an autonumber PK
and FKs on the principles above. This allows a subform on the individuals
main form allowing viewing of each donation and automated subtotals. This all
works fine. Is it ok for the bank details to be in a separate many to many
relationship with tblIndividuals that the donations tables as above? Will
this cause any complications when I try to create a form to enter standing
orders using individuals's bank reference from the tblBanks to find their
record. (Don't want to use the existing subform for data entry of standing
orders, just for viewing, as too many clicks otherwise). Will a query bring
this all together for a data entry form without any complications or am I
likely to need more code if I take this approach?

Its in this part of the database where I think you are going astray. Now,
you already know that each table represents an 'entity type' and each column
in a table represents an 'attribute type' of that entity type, for instance
Sue and ken are attributes of type FirstName (i.e., a column) of entity type
People (i.e. a table). Banks is an entity type, so you correctly have a
table tblBanks. Each row represents one bank. Attributes of the entity type
are things like its name and address, so there'd be columns for these. Each
bank will have many customers, so the relationship with tblIndividuals is
one-to-many. In the jargon the table on the 'one' side is known as the
'referenced table' and that on the 'many' side as the 'referencing' table.
Sometimes folksy terms like 'parent' and 'child' are used instead, but I
prefer the more formal terms because they tell you exactly how the
relationship works, the tblIndividuals table 'refernces' the tblBanks table,
which it does by having a foreign key column BankID in tblIndividuals which
refernces the primary key column BankID in tblBanks. You have it the other
way around, which as you've discovered means that a bank can have only one
customer. Now this would cut down the queues at the teller's window but
would not be good business.

Now you could simply put a BankID column in tblIndividuals to act as a
foreign key, along with other columns like AccountNumber etc., but even
though this is a one-to-many relationship type, as you only want to record
one set of bank details per person, I'd model it in the same way as if it
were a many-to-many relationship type by having a 'linking' table (again
while folksy terms like this are OK, try and think of these sort of tables as
what they really are, models of a relationship type). Although a one-to-many
relationship is not normally modelled by a table, but by a foreign key column
in the referencing table, there is absolutely no reason why they should not
be, and their use in this way is recommended by Chris date, one of the
greatest of the great and the good of the relational database world, as a
means of avoiding Null foreign keys (in your case if an individual has no
bank account).

The relationship type between individuals and banks is really 'Accounts' as
its through their account that a person is related to a bank, so the table
could be called BankAccounts say. Once we understand that a person's account
is the relationship with the bank its clear where things like the sort code,
account number etc go. These are of course attributes of the account so they
are columns in the BankAccounts table along with the two foreign key columns
IDIndividual and BankID. If you definitely only want to record one bank
account per individual then index the IDIndividual column in BankAccounts
uniquely. Neither tblIndividuals nor tblBanks will have a foreign key
referencing the other of course as the relationship is via the BankAccounts
table.

When it comes to things like standing orders etc I can't be absolutely
categoric about how these should be handled on the basis of the information
you've so far provided. I'm Irish remember, and you are asking me which way
is the road to Dublin! Might there be multiple standing order per
individual? Do you need to record that they've been paid and on which dates?
The same sort of questions apply to other financial instruments. I'd need
to know in a lot more detail how such things fit in to the real world
business model in which the database will operate. From what you say,
however, I think you've probably got it right. Should you decide to record
more than one bank account per person, though, you'd need to add a column for
the account number to each of the tables which model the relationships
between standing orders and individuals. In fact the relationship is really
with BankAccounts rather than tblIndividuals as an individual can only set
up a standing order if they have an account to draw on. So if you do decide
to record more than one account per person the relationship would be on both
the IDIndividual and AccountNumber columns, rather than solely on the
IDIndividual column as at present.

Ken Sheridan
Stafford, England
 

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