Databases - Referencing Tables

How to reference tables and the fields they contain.

Paradox | MS Access 97 | MS Access XP | Delphi | ASP


Paradox

The following code steps through all the records in a table and then calls a context sensitive routine (subject.Determine_Age) that computes computes a persons age based on the specified dates.
method Check_Data()
var 
  testTableTC                TCursor
  DateOfBirth, AgeOnThisDate Date
  CalculatedAge              SmallInt
  Error_Count                SmallInt
endvar

testTableTC.open("testdate")
testTableTC.edit()

Error_Count = 0

scan testTableTC :    ; The colon is required!

  DateOfBirth   = testTableTC."Date of Birth"
  AgeOnThisDate = testTableTC."Age on This Date"

    ; Check for a valid comparison
  if DateOfBirth > AgeOnThisDate then 
    testTableTC."Computed Age" = blank()
    loop ; Get next record from table
  endif

  CalculatedAge = subject.Determine_Age(DateOfBirth, AgeOnThisDate)
  testTableTC."Computed Age" = CalculatedAge

  if testTableTC."Correct Age" <> CalculatedAge  then
    Error_Count = Error_Count + 1
  endif

endscan

  testTableTC.close()
  TESTDATE_UI_TableFrame.forceRefresh()

  Number_of_Errors_UI_Field = Error_Count

  if  Number_of_Errors_UI_Field = 0
    then  Number_of_Errors_UI_Field.Font.Color = Green
    else  Number_of_Errors_UI_Field.Font.Color = Red
  endif

endmethod Check_Data


MS Access 97

MS Access uses a Recordset to access data in a table. Methods are provided for First, Last, Next, Previous, and the like.

Individual fields are referenced via

Use CurrentDB to refer to the current database. In the following, the word Set is required. It causes a variable to point to (reference) the object. More Details


Example

The following code correctly computes a persons age based on the specified dates.
Private Sub Button20_Click()
Dim MyDB As Database, MyTable As Recordset
Dim iBDOY As Integer, iDOY As Integer, iAge As Integer
Set MyDB = DBEngine.Workspaces(0).Databases(0)              ' Older syntax
Set MyTable = MyDB.OpenRecordset("testdate", DB_OPEN_TABLE) ' Open table

MyTable.MoveFirst   ' Locate first record

Do Until MyTable.EOF    ' Begin loop
  MyTable.Edit          ' Enable editing
  iDOY = DateDiff("y", "1-Jan", Format$(MyTable.[Age on This Date], "dd-mmm")) + 1
  iBDOY = DateDiff("d", "1-Jan", Format$(MyTable.[Date of Birth], "dd-mmm")) + 1
  iAge = Year(MyTable.[Age on This Date]) - Year(MyTable.[Date of Birth])
  If iBDOY > iDOY Then iAge = iAge - 1
  MyTable.[Computed Age] = iAge
  MyTable.Update        ' Save changes
  MyTable.MoveNext      ' Locate next record
Loop                    ' End of loop
MyTable.Close           ' Close table

[Computed Age].Requery

End Sub
Note that instead of using
Set MyDB = DBEngine.Workspaces(0).Databases(0)              ' Older syntax
Set MyTable = MyDB.OpenRecordset("testdate", DB_OPEN_TABLE) ' Open table
with Access 97, you could use either
Set MyTable = CurrentDB.OpenRecordset("testdate", DB_OPEN_TABLE) ' Open table
Set MyTable = CurrentDB.OpenRecordset("testdate", dbOpenTable)   ' Open table

Here is an alternate method to walk through a table. However, there is no good way to determine when the last record has been processed. (BTW, this algorithm gives incorrect answers.)

DoCmd.GoToRecord , , A_FIRST ' Locate first record.

Do Until 1 = 0 ' Begin infinite loop
  If [Computed Age] = 0 Then Exit Do   ' Get out of the loop.
    [Computed Age] = _
       Int(([Age on This Date] - [Date of Birth]) / 365.25 + 0.5) - 1
    DoCmd.GoToRecord   ' Locate next record.
Loop     ' End of loop.


MS Access XP

Don't confuse MS Access 97 and MS Access XP - they are not the same products, any relationship is purely cosmetic.

In the help, all the old VisualBasic (ie, MS Access 97) commands are are still listed ... but don't try to use them - they don't work! For instance

produces Instead of the commands listed in the help, you have to use something like this.


A Fix

Well, there is a partial fix to this problem. In MS Access XP, This fixes MOST of the problems using the old examples ... but some variable declarations still cause a problem. In the following example, I've show 3 different ways to declare MyTable - in a real example, it should only be declared once. Of course, I have never found any documentation about this ... instead, one of the people who read these pages gave me the tip.


Delphi 5.0

Unless you have manually created field objects, you should use FieldByName to select each field. with Table1 do begin Close; Open; while not EOF do begin tempStr := FieldByName('LASTNAME').AsString; Next; end;


Blob Fields

Delphi provides 4 stream types that can be used to read and write blobs. (Remember, any time you use a stream, be sure to Free it in a try..finally block.) Delphi suggests using TDataSet.CreateBlobStream to create the streams ... but there are no examples.

Examples in the Delphi help

This reads data using a Memory stream


ASP

These examples show several ways to open an ADO connection to an MS Access database. Though it is not shown in every example, you must always explicitly close and set to nothing every variable initialized with Server.CreateObject.

This example uses a connection object to access an already defined ODBC connection.

This example uses a connection object to define a new ODBC connection This example uses a connection string to access an already defined ODBC connection. This example uses a connection string to define a new ODBC connection In practice, defining the ODBC connection in the ASP file is "better" because you do not need to be a system administrator on the remote web server (ie, it is usually easier to get it working). There may be other reasons not to do this.

If you are opening several recordsets on the same database, it is better to use a connection object than to define the parameters in the recordset.open command - it is better and faster to create one connection instead of 5.

This is an example of a processing loop. The 2 nested loops produce an interesting ouput - most of the code is omitted in this example, there is just enough to give you the idea. The html table is defined outside the loop, only the rows are generated inside the loop.

References:


Restarting IIS

Each time you modify an ASP page, you need to stop and restart IIS - otherwise you can not see your changes. How to Restart IIS explains how to do that. Notice that I have written a program (Replace_dll.exe is free for you to download) that will do this automatically on Windows XP, except that it occasionally hangs IIS (especially when you don't explicitly close the connections). When hung, you should use the Control Panel to restart IIS.


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Databases / TableRefence.html