PK & FK problems in data consolidation

F

Frank Situmorang

Hello,

Here is the membership data from Church A looks like:

MemberID(PK) MemberName AddressID(FK)
========== ========== ===========
1 Ujang 1
2 Bambang 1
3 Tuti 1

from Church B looks like:
MemberID(PK) MemberName AddressID(FK)
========== ========== ===========
1 Horas 1
2 Frank 1
3 Mona 1

Suppose I receive these data in the Regional office
and I want to combine it in order to have consolidated data

What happens with the MemberID, If I already have data from
Chruch A, now I want to append data from church B, Will the
memberID continue to the next sequence number 4, 5, 6??

What should I best use Append or import it from excel

Thanks for any idea. I already desingend for standalone database,
When I come to improve it to be used by manya churches of my denomination
I have problems. Like the above in each church the FK of member is already
correct to show its address, but if the memberID changed or the addressID(PK)
change, the address will not show the correctly in the consolidated member
data.

I hope someone in this forum can help me
 
T

Tom van Stiphout

On Wed, 29 Oct 2008 21:16:00 -0700, Frank Situmorang

No; to consolidate this data appropriately you would need an extra
column: ChurchID. This will be a foreign key value from tblChurches:
ChurchID(PK) ChurchName
1000 ChurchA
1001 ChurchB

Your membership table will have a compound PK:
ChurchID PK
MemberID PK
MemberName
AddressID

-Tom.
Microsoft Access MVP
 
F

Frank Situmorang

Tom...my problem is quite complex chruchID within the region yess. it is not
duplicate, but as I said in my other postings, that our organization is is a
multilevel,
The highest is GC ( General Conference) which is a world office which is
consist of 13 Division, then Division consists of Union and Union consits of
Region. Like us in Indonesia is part of West Indonesia Union, and Union
consits of Region, the Region consists of Churchses

Yes your suggestion could be right if the churches for the region, but if
the church is in another region, of course their churchid sould start also
from No.1

The same is true fo the RegionID, if it is in the other Union, the RegionID
should start also from no.1, so there will be a duplicate regionID from other
Union (upper level). The same is true also for the UnionID, will duplicate
with the other UnionID from other DiVisions, This is not the case with the
Division because only one office for the world level, and I have got its
Acronym and can be used as it's ID

I do knot know if Access database can handle this kind of hirarchy, each
herachy will consolidate the data from it's lower offices.

Thanks for any idea
 
M

Michael Gramelspacher

Tom...my problem is quite complex chruchID within the region yess. it is not
duplicate, but as I said in my other postings, that our organization is is a
multilevel,
The highest is GC ( General Conference) which is a world office which is
consist of 13 Division, then Division consists of Union and Union consits of
Region. Like us in Indonesia is part of West Indonesia Union, and Union
consits of Region, the Region consists of Churchses

Yes your suggestion could be right if the churches for the region, but if
the church is in another region, of course their churchid sould start also
from No.1

The same is true fo the RegionID, if it is in the other Union, the RegionID
should start also from no.1, so there will be a duplicate regionID from other
Union (upper level). The same is true also for the UnionID, will duplicate
with the other UnionID from other DiVisions, This is not the case with the
Division because only one office for the world level, and I have got its
Acronym and can be used as it's ID

I do knot know if Access database can handle this kind of hirarchy, each
herachy will consolidate the data from it's lower offices.

Thanks for any idea

You are running around in a circle like a dog chasing its tail and getting nowhere.

Members table and Addresses table at all levels can have the same structure. The key will be
MemberID, ChurchID, RegionID, UnionID, DivisionID, that is, a multi-column primary key. Everyone is
happy. Everyone's member table structure is the same as everyone else's. Same goes for addresses.

I assume each church is not making up their own RegionID, UnionID and DivisionID numbers. Do
regions make up numbers for their churches? Do unions make up the numbers for their regions, etc.?
 
F

Frank Situmorang

Thanks Michael, yes I understand a bit aobut your jargon...he...he..he.I am
not an English speaker...so maybe that is one reason that I run in the circle.

I agree with you that it should be using a multi field primary key, but
what bothers me I think it is difficult to operate.

Rignt now I have an input form of a member and in this form I have a combo
box to choose his address. With this 4 field PK of address, how can I make it.

When I input the member ID with the 4 field PK, how can I do it. Isn't it
too complicated for a church secretary to operate?



Thanks for your advice
H. Frank Situmorang
 
M

Michael Gramelspacher

Thanks Michael, yes I understand a bit aobut your jargon...he...he..he.I am
not an English speaker...so maybe that is one reason that I run in the circle.

I agree with you that it should be using a multi field primary key, but
what bothers me I think it is difficult to operate.

Rignt now I have an input form of a member and in this form I have a combo
box to choose his address. With this 4 field PK of address, how can I make it.

When I input the member ID with the 4 field PK, how can I do it. Isn't it
too complicated for a church secretary to operate?



Thanks for your advice
H. Frank Situmorang


Here are my tables:

CREATE TABLE Churches (
ChurchID LONG,
ChurchName TEXT(50) NOT NULL,
PRIMARY KEY (ChurchID)
);
CREATE TABLE Regions (
RegionID LONG,
RegionName TEXT(50) NOT NULL,
PRIMARY KEY (RegionID)
);
CREATE TABLE Unions (
UnionID LONG,
UnionName TEXT(50) NOT NULL,
PRIMARY KEY (UnionID)
);
CREATE TABLE Divisions (
DivisionID LONG,
DivisionName TEXT(50) NOT NULL,
PRIMARY KEY (DivisionID)
);
CREATE TABLE Affiliations (
ChurchID LONG
REFERENCES Churches (ChurchID),
RegionID LONG
REFERENCES Regions (RegionID),
UnionID LONG
REFERENCES Unions (UnionID),
DivisionID LONG
REFERENCES Divisions (DivisionID),
PRIMARY KEY (ChurchID, RegionID, UnionID, DivisionID)
);
CREATE TABLE Defaults (
Church LONG,
Region LONG,
Union LONG,
Division LONG
);
CREATE TABLE Members (
MemberID LONG NOT NULL,
ChurchID LONG NOT NULL,
RegionID LONG NOT NULL,
UnionID LONG NOT NULL,
DivisionID LONG NOT NULL,
FOREIGN KEY (ChurchID, RegionID, UnionID, DivisionID)
REFERENCES Affiliations (ChurchID, RegionID, UnionID, DivisionID)
ON UPDATE CASCADE
FirstName TEXT(50) NOT NULL,
LastName TEXT(50) NOT NULL,
PRIMARY KEY (MemberID, ChurchID, RegionID, UnionID, DivisionID)
);

I have an Affiliations Form which is a continuous form. The form has a command button so you can
make the current church the default church. The form has four comboboxes for church, region, union
and division.

Private Sub cmdDefault_Click()

Dim s As String

' if nothing is blank
If Not (IsNull(cbo_ChurchID) Or IsNull(cbo_RegionID) Or _
IsNull(cbo_UnionID) Or IsNull(cbo_DivisionID)) Then

' delete old defaults
CurrentDb.Execute "DELETE * FROM Defaults", dbFailOnError

' insert new defaults
s = "INSERT INTO Defaults VALUES(" & cbo_ChurchID & "," & _
cbo_RegionID & "," & cbo_UnionID & "," & cbo_DivisionID & ");"

CurrentDb.Execute s, dbFailOnError

End If

End Sub

Next there is a Members Form. It also has comboboxes for church, region, union and division.
The default values are set in the form Open event.

Private Sub Form_Open(Cancel As Integer)

Dim rst As DAO.Recordset

Set rst = CurrentDb.OpenRecordset("SELECT * FROM Defaults")

With rst
Me.cbo_ChurchID.DefaultValue = !Church
Me.cbo_RegionID.DefaultValue = !Region
Me.cbo_UnionID.DefaultValue = !Union
Me.cbo_DivisionID.DefaultValue = !Division
End With

rst.Close
Set rst = Nothing

End Sub

The secretary never has to mess with this information. If more than one, or several, churches are
managed by one secretary, then there will be problems
 
F

Frank Situmorang

Yhanks Michael for your comprehensive explanation, I have those tables in my
database except the affiliation table what is that for.

I have sent you my database thru your email and explained my problems,
thanks for your helps
 
M

Michael Gramelspacher

Yhanks Michael for your comprehensive explanation, I have those tables in my
database except the affiliation table what is that for.

I have sent you my database thru your email and explained my problems,
thanks for your helps

You have a complete functioning database program with multiple forms and reports. Now you want to
expand the usage of this database throughout the church hierarchy. The problem is that the database
uses an autonumber key unique to each church. You are looking for an easy fix which will allow you
to basically keep things about as they are. I do not see how you can avoid redesigning the
database.

I do not understand your table structure and cannot read the table names, because they are in a
foreign language. I see only two defined relationships in the relationship window, and they are
defined in the front end.

The Affiliation table brings ChurchID, RegionID, UnionID and DivisionID together. It defines the
allowable combinations of Church, Region, Union and Division. Member table is joined to the
Affiliation table. This is for data integrity so as to define valid combinations.

I really do not know where you can go with this. Maybe there are still other ideas out there.
 
F

Frank Situmorang

Thanks Michael for your input. I am still open for redesigning it, since I
just finished it recently, is it a big job?. The relationsip is all the same
I think except that instead of surrogate PK, now we want to make it the even
5 field PK ?(member,church,Regional, Union,Division) of member table and 5
field PK (address,church,Regional,Union,Division) of household address table.

My question is should we make also the 5 FK of this?. HouseholdAddress table
related to member table as one to many. Should we have 5 FK also in
membertable?.
In order to have a memership report by church, by regional, by Union, by
Division), I have related the following tables with One to many relationship:
1. Church to member
2. Regional to Church
3. Union to REgional
4. Division to Union

Should we have a 5 field FK in member,church, regional, division tables?.
Does affiliation table will take care the combination of the FK too?. Address
and member ID since it will be increasing as we enter the data, column should
also be primary key too?.

Thanks for your kind help.
 
F

Frank Situmorang

Hi...Michael...

I have an idea for always keeping it to 1 field primary key although it is
not necessarily an Autonumber.

The target is to keep the membersID and Address ID unique for this are the
data that will be consolidated upto the higher level.

From our organization website we know there are 13 divisions, ok we input
that into our division table, let's say Indonesia is part of the Southern
Asia Pasific Division which is number 8.

All the rest, Union, regional, chruch id, we do not know so , we have to ask
them the name when they ordered the software. Members and addresses can be
input on it's own with the following rules shuold apply before we send them
the software:

1. They have to ask us we can call it affiliation number, so they will tell
us name of his Division, Union, and Regional and Church.

2. Then we input that in our tables and our database shows now that
Divisonnumber is 8 Union number 2, Regional is 3 and Church is no. 1

3. So software developper have to assign affiliation nubmer is 8231 to lets
say to Kebayoran SDA church.

Now my question is can we make the member PK of our Kebayoran SDA church
with the rule in table that it will start with 8231 and the next digits will
be incremented by 1 for PK of the member... The same rule is also true for
addresss ( or household address

As long as the user will ask the affiliation number to us, I think the
number will be always unique.

Plese help us Michael, what is the calculation or VBA in the PK table should
we make.

So all the input of the hierarchy office wich is not so much will be made by
us as a software developper.
 
M

Michael Gramelspacher

Hi...Michael...

I have an idea for always keeping it to 1 field primary key although it is
not necessarily an Autonumber.

The target is to keep the membersID and Address ID unique for this are the
data that will be consolidated upto the higher level.

From our organization website we know there are 13 divisions, ok we input
that into our division table, let's say Indonesia is part of the Southern
Asia Pasific Division which is number 8.

All the rest, Union, regional, chruch id, we do not know so , we have to ask
them the name when they ordered the software. Members and addresses can be
input on it's own with the following rules shuold apply before we send them
the software:

1. They have to ask us we can call it affiliation number, so they will tell
us name of his Division, Union, and Regional and Church.

2. Then we input that in our tables and our database shows now that
Divisonnumber is 8 Union number 2, Regional is 3 and Church is no. 1

3. So software developper have to assign affiliation nubmer is 8231 to lets
say to Kebayoran SDA church.

Now my question is can we make the member PK of our Kebayoran SDA church
with the rule in table that it will start with 8231 and the next digits will
be incremented by 1 for PK of the member... The same rule is also true for
addresss ( or household address

As long as the user will ask the affiliation number to us, I think the
number will be always unique.

Plese help us Michael, what is the calculation or VBA in the PK table should
we make.

So all the input of the hierarchy office wich is not so much will be made by
us as a software developper.

I think your idea is to encode 4 pieces of information into a single number. It will actually be a
text data type. I guess that is not uncommon, but most people would recommend not to do it. The
only reason you are considering it is that your application is finished and you do not want to redo
it now. So, as I understand, the top level organization furnishes this number to each church. Now
for each membership record this church number is combined with the MemberID to make a new key.

You basically have arrived back where you started with a unique ChurchID and a MemberID. What is
new is that the churchID is now unique system wide and the MemberID and ChurchID are combined to
make one field. It seems that that is the solution you are looking for.
 
F

Frank Situmorang

Michael, basically I want to re do it, but since multiple PK will also have
multi field FK too, while in the form like you see there we use combo, I do
know how to match the PK to the FK of the many relationship. If you think it
is easy, please help me.

Thanks in advance
 
M

Michael Gramelspacher

Michael, basically I want to re do it, but since multiple PK will also have
multi field FK too, while in the form like you see there we use combo, I do
know how to match the PK to the FK of the many relationship. If you think it
is easy, please help me.

Thanks in advance

Are you asking how to join two tables using a multiple column key? It is done in the relationships
window. Highlight the fields in one table and drag them over to the other table. Then in the Edit
Relationships window which pops up, check Enforce Referential Integrity and Cascade Update Related
Fields.

Take a look at this: http://www.psci.net/gramelsp/temp/db1.zip

It merely shows a relationship based upon multiple columns. Not that if you change a column in the
Affiliation Form, the linked records in Members Form automatically changes also. This is due to
cascading updates.

Now add a new record in the Members Form. You will notice the the ChurchID, RegionID, UnionID and
DivisionID fill in automatically. Code in the Open event pulls the data from the Defaults table.
For the user at the church level it is utterly simple. You can probably lock the fields on the
form.

One issue is where will the ID numbers come from. There are 13 Divisions, but are the Divisions
numbered. And where do the Union numbers come from? And the Region numbers? It looks like church
numbers are unique only within Regions. Likewise Region numbers are unique only within Unions, and
Unions only within Divisions. Probably all these numbers should be unique systemwide otherwise
there will be problems. I think I might just consider dropping the ID and using the actual name as
a key. What does an actual church name and an actual region name, etc., look like. In plain words,
what does some actual data look like?
 
F

Frank Situmorang

Thanks Michael for your explanation. My concern is what is the impact in the
forms and reports that I desingned. Like you can see in menu number 2, in the
member update form, there is a combo to choose the address. If it is 5 field
primary key, it takes a wider combo and can not accomodate anymore in the
form. Also in the Notes of each member, there is a parent-child relation
from form and sub form. Can we only relate 1 column of these 5 field PK?. All
the queries know I have to redesign again for the 5 field PK?.

Yes, the number of the Division comes from me as a Developer, since I can
input these 13 Division and it's names in my table. may be upto Union, I can
still input in my talbes, for all the rest, I will input as I ask them to
tell me the name of their regional and churces and when I input it, I take
these numbers to put as default value in the text control of single field PK,
like I mentioned in my previous emai.

As long as the numbers comes from us ( upon they told and input in table),
we can keep it's uniqueness I think. The problem may be it is not so
practical.

We appreciate your comment on having a combo in the member form to choose
the address, and what is the impact of multi-field PK in my current reports
and forms.

Thanks in advance
 
M

Michael Gramelspacher

Thanks Michael for your explanation. My concern is what is the impact in the
forms and reports that I desingned. Like you can see in menu number 2, in the
member update form, there is a combo to choose the address. If it is 5 field
primary key, it takes a wider combo and can not accomodate anymore in the
form. Also in the Notes of each member, there is a parent-child relation
from form and sub form. Can we only relate 1 column of these 5 field PK?. All
the queries know I have to redesign again for the 5 field PK?.

Yes, the number of the Division comes from me as a Developer, since I can
input these 13 Division and it's names in my table. may be upto Union, I can
still input in my talbes, for all the rest, I will input as I ask them to
tell me the name of their regional and churces and when I input it, I take
these numbers to put as default value in the text control of single field PK,
like I mentioned in my previous emai.

As long as the numbers comes from us ( upon they told and input in table),
we can keep it's uniqueness I think. The problem may be it is not so
practical.

We appreciate your comment on having a combo in the member form to choose
the address, and what is the impact of multi-field PK in my current reports
and forms.

Thanks in advance

My view is that you precisely model a problem and then worry about implementing the model using
queries,forms and reports.

My understanding is that you do not know about churches, regions and perhaps unions until a church
contacts you to order the software. At that time you assign a church number, region number and a
union number. If, for example, a church is the second church from a region to order, then the
region already has a number. You only need to give the church a number. The effect is that church
numbers are made unique system wide. That is, the church number alone uniquely identifies the
church worldwide for users of the software.

We now have:

CREATE TABLE Churches (
ChurchID LONG,
ChurchName TEXT(50) NOT NULL,
PRIMARY KEY (ChurchID)
);
CREATE TABLE Regions (
RegionID LONG,
RegionName TEXT(50) NOT NULL,
PRIMARY KEY (RegionID)
);
CREATE TABLE Unions (
UnionID LONG,
UnionName TEXT(50) NOT NULL,
PRIMARY KEY (UnionID)
);
CREATE TABLE Divisions (
DivisionID LONG,
DivisionName TEXT(50) NOT NULL,
PRIMARY KEY (DivisionID)
);
CREATE TABLE Affiliations (
ChurchID LONG
REFERENCES Churches (ChurchID),
RegionID LONG
REFERENCES Regions (RegionID),
UnionID LONG
REFERENCES Unions (UnionID),
DivisionID LONG
REFERENCES Divisions (DivisionID),
PRIMARY KEY (ChurchID)
);
CREATE TABLE Defaults (
Church LONG
);
CREATE TABLE Members (
MemberID LONG NOT NULL,
ChurchID LONG NOT NULL
REFERENCES Affiliations (ChurchID)
ON UPDATE CASCADE
FirstName TEXT(50) NOT NULL,
LastName TEXT(50) NOT NULL,
PRIMARY KEY (MemberID, ChurchID)
);


Now you are down to a two column key. If you wanted, you could concatenate in code the value of
default church and a sequential number to obtain a single column key.

Frankly though, I am at the end of the line trying to solve this problem. I am just too far removed
from the situation.
 
F

Frank Situmorang

Thanks very much Michael for your help. Yes, you help me very much. I will
still prefer the one field Primary key of member and address because in
practice, all this additional is for the upper office level, not in the
church. So we will not show like affiliation form in the church secretary.
This can be possible if I make a default value of text control data property
of the memberform this function:
=Nz(DMax("[YourField]","[YourTable]"),82310000) + 1.

I will try to change my member Autonumber PK as well as address autonumber
PK with just number.

8231(example) comes from affiliation form, the 8 divison no,2 Union no,
3,regional no. 1, chruch no, while the other 000, suppose the number of the
member maximum 9999 members which never reach this number in SDA church for
one church.

This is because I have not understand how can we apply this multiple field
PK in a from, report and other.
 
M

Michael Gramelspacher

Thanks very much Michael for your help. Yes, you help me very much. I will
still prefer the one field Primary key of member and address because in
practice, all this additional is for the upper office level, not in the
church. So we will not show like affiliation form in the church secretary.
This can be possible if I make a default value of text control data property
of the memberform this function:
=Nz(DMax("[YourField]","[YourTable]"),82310000) + 1.

I will try to change my member Autonumber PK as well as address autonumber
PK with just number.

8231(example) comes from affiliation form, the 8 divison no,2 Union no,
3,regional no. 1, chruch no, while the other 000, suppose the number of the
member maximum 9999 members which never reach this number in SDA church for
one church.

This is because I have not understand how can we apply this multiple field
PK in a from, report and other.

I would keep the Affiliation table and put Church 1, Region 3, Union 2 and Division 8 in the
Affiliation table.

I would have a table Defaults with one column named Church, which holds the ChurchID.
This churchID will be unique. Since you distribute the software, you are the one who assigns the
unique ChurchID. You actually unpdate the Affiliation and Defaults table before sending the
software.

You can automatically create the concatenated MemberID in the BeforeInsert event of the Members
Form. Lock the MemberID Field and give it Tab stop = No. As soon as the user atempts to type the
member's name, the key will be filled in.

Private Sub Form_BeforeInsert(Cancel As Integer)

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String

On Error GoTo Err_Form_BeforeInsert

Set db = DBEngine(0)(0)

' built query string to sort MemberID in descending oder
' where the first part of MemberID matches default church number

strSQL = "SELECT MemberID FROM Members "
strSQL = strSQL & "WHERE (((Left([MemberID], 4)) = """
strSQL = strSQL & Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & """))"
strSQL = strSQL & "ORDER BY MemberID DESC;"

'DoCmd.Hourglass True
Set rst = db.OpenRecordset(strSQL)
'DoCmd.Hourglass False

If rst.BOF Then
MsgBox "Initial entry!"
Me!MemberID = Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & "0001"
Else
rst.MoveFirst

' add 1 to MemberID and add leading zeros
Me!MemberID = Right("000" & (rst(0) + 1), 4)

' combine default church number with sequence number
' from previous line
Me!MemberID = Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & Me.MemberID
End If
DoCmd.GoToControl "FirstName"

rst.Close

Set rst = Nothing
Set db = Nothing

Exit_Form_BeforeInsert:
Exit Sub

Err_Form_BeforeInsert:
Select Case Err.Number
Case Else
'Call LogError(Err.Number, Err.Description, _
"Form_Members Form." & "Form_BeforeInsert")
Resume Exit_Form_BeforeInsert
End Select

End Sub


Another way is to have the user type the church number 0001 and then after the 4th character add the
sequence part.

Private Sub MemberID_Change()

' examine each character as it is entered and if it is not an acceptable
' character then ignore it and leave string as it was before

On Error GoTo Err_MemberID_Change

If InStr(1, "0123456789", Right(Me!MemberID.Text, 1)) = 0 Then
Me!MemberID.Text = Left(Me!MemberID.Text, Len(Me!MemberID.Text) - 1)
End If


' automatically increment the member number. The member number is
' formed by using the church number and adding a sequence number,
' ex., 08930008. Get the church number after user enters 4 numbers,
' find the highest number used for that year, and then add 1.
' If starting anew, add 0001. (This allows a church to have a maxium
' of 9999 members.)

' the user types the first 4 characters, which represents the
' church number

If Len(Me!MemberID.Text) = 4 Then

' if church number typed is different than default church
' number, then tell the user

If Me!MemberID.Text <> Right("000" & DLookup("Church", _
"Defaults"), 4) Then
If vbNo = MsgBox("This is not the default church ID! " _
& "Do you wish to continue", vbQuestion + vbYesNo, "Warning!") Then
Exit Sub
End If
End If

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String

Set db = DBEngine(0)(0)

' built query string to sort MemberID in descending oder
' where the first part of MemberID matches characters typed

strSQL = "SELECT MemberID FROM Members "
strSQL = strSQL & "WHERE (((Left([MemberID], 4)) = """
strSQL = strSQL & Me!MemberID.Text & """))"
strSQL = strSQL & "ORDER BY MemberID DESC;"

'DoCmd.Hourglass True
Set rst = db.OpenRecordset(strSQL)
'DoCmd.Hourglass False

If rst.BOF Then
MsgBox "Initial entry!"
Me!MemberID.Text = Me!MemberID.Text & "0001"
Else
rst.MoveFirst
Me!MemberID.Text = Right("000" & (rst(0) + 1), 8)
End If
DoCmd.GoToControl "FirstName"

rst.Close

Set rst = Nothing
Set db = Nothing
End If

Exit_MemberID_Change:
Exit Sub

Err_MemberID_Change:
Select Case Err.Number
Case Else
'Call LogError(Err.Number, Err.Description, _
"Form_Members Form." & "MemberID_Change")
Resume Exit_MemberID_Change
End Select

End Sub

Having a MemberID made by combining two values is only for expediency.

SELECT Members.LastName,
Members.FirstName,
Regions.RegionName
FROM Members,
Regions
INNER JOIN Affiliations
ON Regions.RegionID = Affiliations.RegionID
WHERE (((Affiliations.ChurchID) = CINT(LEFT([Members].[MemberID],4))))
ORDER BY Members.LastName,
Members.FirstName;

Members and their regions

OK, I do not think I know anything more. You should be able to take it from here.
 
F

Frank Situmorang

Thanks very much Michael, your are awesome on all these VBA. I have to study
it slowly. But if you could do me a favor by sending the link like the one
you sent me. It's easier for me to understand it with the actual dbase.

I prefer the first one you suggested, but anyway will it not confilict with
the following VBA in the member form too? for making registrationnumber, not
the record id/memberID:
Public Function GetNextNumber1()
'Function to generate the next number
Dim sSQL As String
Dim r As DAO.Recordset
Dim s As Byte

'create a recordset
sSQL = "select top 1 bukuangkby.noin + 1 as NN,"
sSQL = sSQL & " (select min(t.noin) - 1 from bukuangkby as t "
sSQL = sSQL & " Where t.noin > bukuangkby.noin)"
sSQL = sSQL & " from bukuangkby"
sSQL = sSQL & " Where not exists (select t.noin from bukuangkby as t "
sSQL = sSQL & " Where t.noin = bukuangkby.noin + 1)"
sSQL = sSQL & " AND bukuangkby.noin< "
sSQL = sSQL & " (select Max(s.noin)+1 from bukuangkby as s)"
sSQL = sSQL & " Order By noin;"

Set r = CurrentDb.OpenRecordset(sSQL)
If r.RecordCount = 1 Then
r.MoveFirst
'return the number
GetNextNumber1 = r.Fields(0)
Else
' no number - let them know
MsgBox "ERROR! Number not generated!!"
End If

'clean up
r.Close
Set r = Nothing

End Function

Thanks and greetings from Jakarta, Indonesia.


--
H. Frank Situmorang


Michael Gramelspacher said:
Thanks very much Michael for your help. Yes, you help me very much. I will
still prefer the one field Primary key of member and address because in
practice, all this additional is for the upper office level, not in the
church. So we will not show like affiliation form in the church secretary.
This can be possible if I make a default value of text control data property
of the memberform this function:
=Nz(DMax("[YourField]","[YourTable]"),82310000) + 1.

I will try to change my member Autonumber PK as well as address autonumber
PK with just number.

8231(example) comes from affiliation form, the 8 divison no,2 Union no,
3,regional no. 1, chruch no, while the other 000, suppose the number of the
member maximum 9999 members which never reach this number in SDA church for
one church.

This is because I have not understand how can we apply this multiple field
PK in a from, report and other.

I would keep the Affiliation table and put Church 1, Region 3, Union 2 and Division 8 in the
Affiliation table.

I would have a table Defaults with one column named Church, which holds the ChurchID.
This churchID will be unique. Since you distribute the software, you are the one who assigns the
unique ChurchID. You actually unpdate the Affiliation and Defaults table before sending the
software.

You can automatically create the concatenated MemberID in the BeforeInsert event of the Members
Form. Lock the MemberID Field and give it Tab stop = No. As soon as the user atempts to type the
member's name, the key will be filled in.

Private Sub Form_BeforeInsert(Cancel As Integer)

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String

On Error GoTo Err_Form_BeforeInsert

Set db = DBEngine(0)(0)

' built query string to sort MemberID in descending oder
' where the first part of MemberID matches default church number

strSQL = "SELECT MemberID FROM Members "
strSQL = strSQL & "WHERE (((Left([MemberID], 4)) = """
strSQL = strSQL & Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & """))"
strSQL = strSQL & "ORDER BY MemberID DESC;"

'DoCmd.Hourglass True
Set rst = db.OpenRecordset(strSQL)
'DoCmd.Hourglass False

If rst.BOF Then
MsgBox "Initial entry!"
Me!MemberID = Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & "0001"
Else
rst.MoveFirst

' add 1 to MemberID and add leading zeros
Me!MemberID = Right("000" & (rst(0) + 1), 4)

' combine default church number with sequence number
' from previous line
Me!MemberID = Right("000" & Nz(DLookup("Church", _
"Defaults"), "9999"), 4) & Me.MemberID
End If
DoCmd.GoToControl "FirstName"

rst.Close

Set rst = Nothing
Set db = Nothing

Exit_Form_BeforeInsert:
Exit Sub

Err_Form_BeforeInsert:
Select Case Err.Number
Case Else
'Call LogError(Err.Number, Err.Description, _
"Form_Members Form." & "Form_BeforeInsert")
Resume Exit_Form_BeforeInsert
End Select

End Sub


Another way is to have the user type the church number 0001 and then after the 4th character add the
sequence part.

Private Sub MemberID_Change()

' examine each character as it is entered and if it is not an acceptable
' character then ignore it and leave string as it was before

On Error GoTo Err_MemberID_Change

If InStr(1, "0123456789", Right(Me!MemberID.Text, 1)) = 0 Then
Me!MemberID.Text = Left(Me!MemberID.Text, Len(Me!MemberID.Text) - 1)
End If


' automatically increment the member number. The member number is
' formed by using the church number and adding a sequence number,
' ex., 08930008. Get the church number after user enters 4 numbers,
' find the highest number used for that year, and then add 1.
' If starting anew, add 0001. (This allows a church to have a maxium
' of 9999 members.)

' the user types the first 4 characters, which represents the
' church number

If Len(Me!MemberID.Text) = 4 Then

' if church number typed is different than default church
' number, then tell the user

If Me!MemberID.Text <> Right("000" & DLookup("Church", _
"Defaults"), 4) Then
If vbNo = MsgBox("This is not the default church ID! " _
& "Do you wish to continue", vbQuestion + vbYesNo, "Warning!") Then
Exit Sub
End If
End If

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String

Set db = DBEngine(0)(0)

' built query string to sort MemberID in descending oder
' where the first part of MemberID matches characters typed

strSQL = "SELECT MemberID FROM Members "
strSQL = strSQL & "WHERE (((Left([MemberID], 4)) = """
strSQL = strSQL & Me!MemberID.Text & """))"
strSQL = strSQL & "ORDER BY MemberID DESC;"

'DoCmd.Hourglass True
Set rst = db.OpenRecordset(strSQL)
'DoCmd.Hourglass False

If rst.BOF Then
MsgBox "Initial entry!"
Me!MemberID.Text = Me!MemberID.Text & "0001"
Else
rst.MoveFirst
Me!MemberID.Text = Right("000" & (rst(0) + 1), 8)
End If
DoCmd.GoToControl "FirstName"

rst.Close

Set rst = Nothing
Set db = Nothing
End If

Exit_MemberID_Change:
Exit Sub

Err_MemberID_Change:
Select Case Err.Number
Case Else
'Call LogError(Err.Number, Err.Description, _
"Form_Members Form." & "MemberID_Change")
Resume Exit_MemberID_Change
End Select

End Sub

Having a MemberID made by combining two values is only for expediency.

SELECT Members.LastName,
Members.FirstName,
Regions.RegionName
FROM Members,
Regions
INNER JOIN Affiliations
ON Regions.RegionID = Affiliations.RegionID
WHERE (((Affiliations.ChurchID) = CINT(LEFT([Members].[MemberID],4))))
ORDER BY Members.LastName,
Members.FirstName;

Members and their regions

OK, I do not think I know anything more. You should be able to take it from here.
 
M

Michael Gramelspacher

Thanks very much Michael, your are awesome on all these VBA. I have to study
it slowly. But if you could do me a favor by sending the link like the one
you sent me. It's easier for me to understand it with the actual dbase.

I prefer the first one you suggested, but anyway will it not confilict with
the following VBA in the member form too? for making registrationnumber, not
the record id/memberID:
Public Function GetNextNumber1()
'Function to generate the next number
Dim sSQL As String
Dim r As DAO.Recordset
Dim s As Byte

'create a recordset
sSQL = "select top 1 bukuangkby.noin + 1 as NN,"
sSQL = sSQL & " (select min(t.noin) - 1 from bukuangkby as t "
sSQL = sSQL & " Where t.noin > bukuangkby.noin)"
sSQL = sSQL & " from bukuangkby"
sSQL = sSQL & " Where not exists (select t.noin from bukuangkby as t "
sSQL = sSQL & " Where t.noin = bukuangkby.noin + 1)"
sSQL = sSQL & " AND bukuangkby.noin< "
sSQL = sSQL & " (select Max(s.noin)+1 from bukuangkby as s)"
sSQL = sSQL & " Order By noin;"

Set r = CurrentDb.OpenRecordset(sSQL)
If r.RecordCount = 1 Then
r.MoveFirst
'return the number
GetNextNumber1 = r.Fields(0)
Else
' no number - let them know
MsgBox "ERROR! Number not generated!!"
End If

'clean up
r.Close
Set r = Nothing

End Function

Thanks and greetings from Jakarta, Indonesia.

I uploaded a new db1.zip
http://www.psci.net/gramelsp/temp/db1.zip

RegistrationNumber seems like it would be all right.
 
F

Frank Situmorang

Thanks very much Michael, I hope that my dream comes true. As I mentioned in
my denomination mailing list, most of the sale proceeds of this will be used
to help the poor in my almamateur University at Pematang Siantar, North
Sumatra. We hope if this is successful, many financially poor students can be
helped to pay their tuitions.

After this I will post on separate thread on how to make in the form and
report caption foreingn languages. because customized it manually is not
practical.

Thanks & Regards
 

Ask a Question

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

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

Ask a Question

Top