Microsoft Access Frequently Asked Questions (FAQ) Listing
Compiled by Mike Gunderloy [72271,275]
Release 5
April 1994

Introduction:
============

        The purpose of this document is to help new Access users
find pointers to helpful information quickly.  Rather than answer
all the questions here, we often point you to a sample or source for
more information.  Our intent is to cut down a bit on the need to
compose new responses to common questions that we all seem to run
into, and perhaps cut down on the increasing traffic on the
CompuServe MSACCESS forum. For many of us, the MSACCESS forum is
"home," and we're determined to keep it a friendly home, even if it is
a crowded one!

        If we didn't answer your question here, please ask it on the
forum.  Questions to "All" or "Sysop" will get plenty of answers.
You should also feel free to direct specific questions to any of the
people listed in the "Credits" section below.  Suggestions for
changes to this file should be sent to Mike Gunderloy via CompuServe
email.  Updated versions of this file are posted on CompuServe
approximately once a month on the MSACCESS forum. This FAQ is not
currently posted to the Internet, due to its heavy reliance on
other files found on CompuServe.

>	This is the last release of this file that will concentrate on
>Access 1.1. The first release of ACFAQ2.ZIP, with changes for Access
>2.0 questions, is currently targeted for late May or early June 1994.

>       New and changed material is indicated in the left margin, as shown
> on this paragraph.

Credits:
=======

        Initial draft by Mike Gunderloy [72771,275].  Helpful
suggestions and additions from Jim Ferguson [71477,2345], Ken Getz
[76137,3650] and Chris St.  Valentine [72702,724].  Some chunks of
the text are borrowed from frequent answers posted by members of
Microsoft's Access PSS team, who deserve a lot of credit for
consistently making MSACCESS one of the best forums on CompuServe.
Thanks to Tom Lucas [72114,3552] for contributing the section on
Access security.

Using the MSACCESS forum on CompuServe:
======================================

        You'll find a lot of material about Access on CompuServe in
the MSACCESS forum.  If you're not already using one, we strongly
suggest investigating an off-line reader to manage your MSACCESS (and
other CompuServe) interaction.  Off-line readers store messages and
let you read them and compose replies at your leisure, helping
reduce your CompuServe bill.  There are a number of competing
packages, most of them shareware: TAPCIS, WINCIS, DOSCIM, WINCIM,
NAVCIS and OZCIS are probably the best known. QMODEM has also
recently added support for CompuServe to their built-in off-line reader.
All have support forums of their own on CompuServe.

How to retrieve Knowledge Base articles:
================================

        When referred to Microsoft Knowledge Base (MSKB) articles,
you have two choices.  You can either GO MSKB from any Compuserve
prompt, and follow the prompts once there to download the
appropriate article (usually listed by article number), or you can
download the entire Access Knowledge Base from Library 1 in the
MSACCESS area.  There are two very large files involved (each is
over 1 megabyte, but the download time is worth the cost if you are
using Access extensively).  The two files are ACC-KB.ZIP and
ACC-IN.ZIP. The Knowledgebase is also available also on Microsoft's
anonymous ftp server on the Internet. Log on to ftp.microsoft.com 
and look under SoftLib\MSLFiles.

Index:
=====
General:
1. I get a General Protection Fault trying to run Access. What 
do I do?
2. What can I do to try and make Access run faster on my computer?
3. How do I use a ZIP file?
4. How does Access compare to Foxpro?
5. Is Microsoft removing Access Basic from the next version of 
Access?
6. Why do I get "Out of Date Database Format" when I try to open a
database I downloaded from CompuServe?
7. What is the current version of Access? When will Access 2.0 
be released? What features will it have?
8. When will Access for the MacIntosh be released?
9. How do I convert my application from dBase to Access?
10. What should I name my Access objects?
11. Is there any way to change the size of the font in the Zoom 
window?
12. When I hit shift-F2 to open the Zoom Box, nothing happens. Why?
13. What are .LDB files?
14. How do I change the text of the Access title bar?
15. How do I get a complete list of Access error numbers and their messages?
Databases:
16. How do I get a list of all the objects in my database?
17. Is there a pre-made Access database to do my inventory/sales/
order-tracking/grading/etc.?
18. How and why can I keep my data in one database and my code in 
another database?
19. How do I see the code in the PIM database, or some other 
example database?
Tables:
20. Suddenly all my databases have six extra tables starting 
with "Msys" in them. What are these and how do I get rid of 
them?
21. How do I import Paradox for Windows files to Access?
22.  How do I get a list of all the "description" entries in my
table definitions?
23. How do I create a table programmatically?
24. How can I see all of the table relationships in my database?
25. How do I reset the value of a counter field?
26. Can text stored in a memo field be formatted with different
fonts or attributes such as boldface or underlining?
27. How can I set referential integrity between my tables and tables
in attached databases? 
Queries:
28. Can I export a query directly without having to do a Make 
Table query first ?
29. How do I find duplicate key values?
30. How do I find all the records that are in one table but do 
not have matches in another table?
31. Why do large queries cause my Novell Netware file server to crash?
32. How can I set up a Query By Form (QBF)?
Forms:
33. Why do I get a #NAME error for a calculated control on a 
form or a report?
34.  When I Tab past the last control on a form, how can I keep Access
from going to the next record (or backwards when I Shift+Tab back
from the first control)?
35.  How do I write information to the status bar and gas-gauge
indicator at the bottom of the screen?  
36. How do I add my own record navigation (first/last/next/previous)
to a form?
37. How do I tell when the user has moved to the blank record at the
end of a table by pressing the Next button on my form?
38. How do I select a control on a form without accidentally moving it?
39. How do I copy all the information from the previous record on a
form to a new record?
40. How do I incorporate photos in my forms, as Microsoft did in the
Employees for Northwinds?
41. How do I display a form without the caption bar at the top?
42. How can I change the cursor on my forms to something bolder?
43. Is there a tool or method to convert Visual Basic forms to Access
forms or vice versa?
Reports:
44. How do I print reports to a file?
45. Why do I get extra blank pages between each page?
46. How do I print a certain number of labels based on a "count" 
field in a record?
47. How do I avoid "Out of Memory" errors on my report?
48. How do I print headers of the form "Page 1 of 12" on my report?
> 49. Where do I find more information on report techniques?
Macros:
50. How do I temporarily comment out a line in a macro?
51. Why aren't there more questions about macros here?
Modules:
52. Why does Access put "Option Compare Database" at the top 
of every module I create?
53. Is there a way in Access Basic to determine the current 
record number so that the record number can be used in a 
GoToRecord action?
54. How do I change a field to Proper Case (first letter of each 
word capitalized)?
55. How do I calculate elapsed business days between two dates?
56. How do I dial a modem from Access?
57. How do I display system information in an About box?
58. How do I play a sound file?
59. How do I set and retrieve global variables?
60. How do I send messages via Microsoft Mail?
61. How do I search by Soundex codes?
62. How do I spell out numbers for check printing?
63. Where are there more functions for string manipulation?
64. How do I make certain events happen at certain times?
65. How do I use the standard Windows File Open and File Save 
dialog boxes?
66. How do I execute an internal DOS command such as COPY?
67. How do I copy a file directly under control fo Access?
68. How do I read and write information from .INI files?
69. How do I send a fax from Access using WinFax?
70. How do I calculate someone's age from their birthdate?
71. How do I get the fully qualified path and file name of the currently-
open Access database?
Wizards & Tools:
72. How do I export multiple objects at once?
73. How do I change all references to the names of Access 
objects?
74. Where do I find more information on the Access Distribution 
Kit?
75. How do I convert macros to modules?
76. How do I create a Help File to use with Access?
77. Is there any way to have access link to MS Word 6.0 to do spell
checking on text or memo fields?
> 78. How do I use DDE to poke information into an Access table?
SQL and ODBC:
79. How do I talk directly to a SQL backend without involving 
the Access parser?
80. What do I need to use Btrieve files via ODBC?
81. How can I make my SQL application run faster?
Security:
82. Why is it that after securing my application following the manual, 
anyone with another copy of Access can still get in?
83. How do I secure an Access database?
84. After securing a database, what are some methods to assign
permissions to users?
85. How should I secure databases on a network?
> Access 2.0:
> 86. What's new in Access 2.0?
> 87. How much will it cost to upgrade my copy of Access?
> 88. Will Access 2.0 work with Access 1.1 files?

General:
=======

1. I get a General Protection Fault trying to run Access. What 
do I do?

        This problem is often related to incomplete implementations
        of video drivers.  Try switching Windows to the standard VGA
        video driver.  If the problem goes away, contact your video
        board vendor for their latest drivers.

2. What can I do to try and make Access run faster on my computer?

        Although a faster CPU will contribute to enhanced Access
        performance, the single best thing you can do is boost your
        machine to 8MB of memory.  Although Microsoft Access will
        run in 4MB, it will run significantly better in 8MB.  A math
        coprocessor will have little or no effect.

        SEE ALSO: PERFORM.TXT on the Access release disks.

3. How do I use a ZIP file?

        ZIP files are compressed files that you need to unpack
        before using.  You can download the standard shareware for
        this as PK204G.EXE in Lib 15.You might also want to
        investigate Windows shell programs for PKZIP.  For example,
        both Central Point Tools for Windows and Norton Desktop for
        Windows include support for ZIPped files.  In addition, the
        excellent shareware utility WinZip (by Nico Mak) is
        available for trial use in the IBMSYS forum.  Of course, if
        you use either PKZIP or WINZIP you need to pay the
        registration fee for the shareware involved.


4. How does Access compare to Foxpro?

        See DBBKGR.ZIP in Lib 14 and CHOOSE.ZIP in Lib 14.

5. Is Microsoft removing Access Basic from the next version of 
Access?

        In a word, No. A Fall 1993 article in InfoWorld misquoted Bill
        Gates. But it is true that current plans are to not include
        the printed Language Reference in the retail package; it
        will be available separately, however.

6. Why do I get "Out of Date Database Format" when I try to open a
database I downloaded from CompuServe?

	Most likely you still have Access 1.0 and are trying to open
	a database created with Access 1.1. The simplest solution is
	to spend the $14.95 necessary to upgrade your copy of Access.
	Alternatively, you can have someone who owns a copy of 1.1 
	compact the database back to 1.0 format for you.
        
7. What is the current version of Access? When will Access 2.0 
be released? What features will it have?

        The current version of Access is 1.1. Microsoft has
        posted two updated drivers in Lib 11: ORA110.EXE for
        access to Oracle files, and BTR110.EXE for access to Btrieve
        files. There are no other patches available to 1.1.
>       Access 2.0 is currently scheduled to be released on
>	May 6, 1994. There is some brief discussion of its new
>	features in the Access 2.0 section below.

8. When will Access for the MacIntosh be released?

       	Here's the current word on Mac Access, from one of the
       	Microsoft reps on the forum: "There is no indication of a 
       	version of Access for the Macintosh being released in the 
       	near future.  We see there is some interest for this product,
       	and it is noted by development.  But the Macintosh environment 
       	poses several issues making it difficult to bring Access 
       	"over" easily.  For example, many parts of Access are written 
       	in 80x86 assembly code that doesn't easily transfer over to 
       	the Mac environment."

9. How do I convert my application from dBase to Access?

        See DBTIPS.ZIP in Lib 8.

10. What should I name my Access objects?

        See CSVSTY.EXE in Lib 15, LRSTYW.ZIP in Lib 15 and 
        NAM_MS.DOC in Lib 7.

11. Is there any way to change the size of the font in the Zoom 
window?

        First make a COPY of your UTILITY.MDA file. For 
        example, call it UTILITYX.MDA. The OPEN this .mda file just 
        like you would any other Access .mdb file. You will get two
        warnings about duplicate definitions, but just ignore them. 
        Then find the form called ZoomBox. You can change the font
        to anything that looks good to you. The Lucida Sans Typewriter 
        font from the MS TrueType font pack works well. Save the 
        UTILITYX.MDA file. Exit Access. Open up your MSACCESS.INI
        file (found in the \windows directory) with a text editor
        such as Notepad. Change the line that says

        UtilityDB=utility.mda 

        to say 

        UtilityDB=utilityx.mda.

        Access will now use your modified Zoom Box whenever you hit
        Shift-F2.

12. When I hit shift-F2 to open the Zoom Box, nothing happens. Why?

	The Zoom Box is displayed by a function in UTILITY.MDA, and as
	with other functions, if there are syntax errors elsewhere in
	your Access Basic code it won't run. Open up any module in your
	database, select Run|Compile All from the menus, and you will
	most likely find an erroneous line highlighted. If your code
	is error-free and you still can't use the Zoom Box, check to make
	sure that your UTILITY.MDA file is present and properly referred
	to in your MSACCESS.INI file. Some people have also reported
	trouble with the Zoom Box when their Windows Free Resources have
	fallen very low.

13. What are .LDB files?

        .LDB files are associated with the .MDB files with the 
        same name. They are used to control file locking when you are
        using Access in non-exclusive mode with sharing enabled. You
        can safely delete these files if the database is not currently 
        open. If you copy the .MDB file you do not need to copy the 
        associated .LDB file because Access will automatically rebuild 
        the .LDB file as needed. Microsoft has not documented the 
        format of LDB files in multi-user situations and you should not
        attempt to modify their internal structure.

14. How do I change the text of the Access title bar?

        Function csvSetTitleBar (MyForm As Form, ByVal MyTitle As String)
        -> As Integer

            ' From the "Access Basic Cookbook"
            ' 
        ' Declare Sub csvSetWindowText Lib "User" Alias "SetWindowText"
        ' -> (ByVal WindowHandle As Integer, ByVal Title As String)

        csvSetWindowText MyForm.hWnd, MyTitle

        End Function
    
        Also see MSKB article number Q92684.

15. How do I get a complete list of Access error numbers and their messages?

          Function csvUserErrors () As Integer

        ' From the "Access Basic Cookbook"
        ' 
        Dim FileNumber As Integer, T As String, X As Long

        T = Chr$(9)
        X = 0
        FileNumber = FreeFile
        On Error Resume Next
        Open "ERRORS.TXT" For Output As FileNumber
        If Err Then
            csvUsedErrors = False
        Else
            Do While True
                X = X + 1
                If Left$(Error(X), 10) <> "User-defined error" Then
                    If Err Then
                            Exit Do
                    End If
                    Print #FileNumber, X; T; Error(X)
                End If
            Loop
            Close FileNumber
            csvUsedErrors = True
        End If
        On Error GoTo 0
        End Function

Databases:
=========

16. How do I get a list of all the objects in my database?

        Access ships with a tool called the Analyzer, which 
        will collect information about all of your Access objects 
        into a series of tables. For instructions on installing and 
        using the Analyzer, read the PSSKB.TXT file in your Access 
        directory. If you need more detail than Analyzer will 
        provide, check into Total Access, from FMS, Inc., 8027 
        Leesburg Pike #410, Vienna, VA 22182, (703) 356-4700.

17. Is there a pre-made Access database to do my inventory/sales/
order-tracking/grading/etc.?

        Probably not. There are various sample databases in the 
        MSACCESS Forum library, but most are intended to demonstrate 
        a technique rather than to provide a full application. We
        encourage you to design and build your own application. If you
        run into problems, there are plenty of people who will help you
        out via CompuServe. You can also contact professional database
        developers via the forum if you would rather pay for work than
        do it yourself. Another useful reference is MSKB article number
	Q100139, "Database Normalization Basics".

18. How and why can I keep my data in one database and my code in 
another database?

        Professional Access developers often split their designs into
        two databases, with all of the data residing in one and all
        other objects (forms, queries, reports, macros, modules) in the
        other. This allows easy updating by simply replacing the "code"
        database while leaving the "data" database intact.

        There are several examples of this in the Forum 
        libraries: NWLOCL.ZIP in Lib 6, ATTMGR.ZIP in Lib 2,
        ATTMNG. in Lib 9 and MULTDB.ZIP in Lib 2 will get you 
        started.
 
        You'll also find another viewpoint in the November 1993
        issue of Smart Access journal.  Paul Litwin (editor) wrote a
        more complete application to handle attachments and supplied
        it with the issue on disk.

19. How do I see the code in the PIM database, or some other 
example database?

        When you first open an MS Access database Access 
        executes a macro called "AutoExec" if it is present. The PIM 
        database is loading some forms and changing some menu items 
        when it first opens by executing various statements in its 
        autoexec macro file. In order to bypass running the autoexec 
        macro when you first open the database you can hold down the 
        SHIFT key. If this technique is ineffective, you are most likely
        running an application that was compiled with the ADK.


Tables:
======

20. Suddenly all my databases have six extra tables starting 
with "Msys" in them. What are these and how do I get rid of 
them?

        These are the system tables, and you don't want to get 
        rid of them because they are necessary for Access to 
        function. You can hide them by choosing Options from the 
        View menu, selecting the General category, and setting "Show 
        System Objects" to "No".

21. How do I import Paradox for Windows files to Access?

        Although Access can't read Paradox for Windows files directly,
        you can use PFW to save them as Paradox 3.x files; Access can 
        import Paradox 3.x files.  There is a third-part ODBC driver
        available that can read Paradox 4.0 files directly; for more
        information contact Q&E Software at 919-859-2220.
        
22.  How do I get a list of all the "description" entries in my
table definitions?

        Access does not provide a direct means of accessing the
        description strings.  You can work around this by using the
        Form Wizard to create a default form based on each table and
        using the Analyzer tool to produce a list of the Status Line
        Text entries for these forms.
        
23. How do I create a table programmatically?

        See DDL100.EXE in Lib 7 (for Access 1.0) or DDL110.EXE 
        in Lib 7 (for Access 1.1).

24. How can I see all of the table relationships in my database?

        Drag all of your tables to a new, blank query. Access will draw
        lines between all of the related tables.

25. How do I reset the value of a counter field?

        If you do a File, Compact Database command the counter 
        will be reset. It will not change any existing records that
        might be in the table, but the next available counter number
        will be 1 greater than the current highest value.

26. Can text stored in a memo field be formatted with different
fonts or attributes such as boldface or underlining?

        Text displayed on a form or report can be formatted, but
        only with one style per field; you can't mix bold and
        regular text, for example, in the same field. If you need
        to do more flexible formatting, you should probably
        investigate using Microsoft Word to extract the fields
        from your database and format them there.

27. How can I set referential integrity between my tables and tables
in attached databases? 

       	Access won't set up default relationships or check
        referential integrity between attached databases of any sort.
        You'll have to handle any such requirements in code, or import the
        files instead of attaching them.  Note that you can set up
        "on-the-fly" relationships in queries involving attached tables as
        necessary, just by dragging the linking fields from one table to
        another.
 
Queries:
=======

28. Can I export a query directly without having to do a Make 
Table query first ?

        Although it is not documented anywhere that I know of 
        you actually can export directly from a query rather than 
        having to do a Make-Table query first. The trick is to do the
        export via a TransferDatabase (or TransferText or 
        TransferSpreadsheet) macro action. In the field where you 
        specify "table:" you can just go ahead and enter the name of 
        your query. When you run the macro your query will run and will
        be exported in the appropriate format

29. How do I find duplicate key values?

        See MSKB article number Q98230.

30. How do I find all the records that are in one table but do 
not have matches in another table?

        See MSKB article number Q95326.

31. Why do large queries cause my Novell Netware file server to crash?

        There is a bug in Netware 3.11 TTS (Transaction Tracking 
        System) which can result in a server abending when running 
        certain Access queries. Access locks records in 2K chunks 
        called pages. Each such locked chunk grabs one lock from the 
        Netware TTS. The defaults in Netware allow a single workstation
        to have 500 locks at any given time. This results in a limit of
        1M of data which Access can deal with in a single transaction. 
        Since Access tries to lock every record involved in either an 
        update or a delete query before actually carrying out the update
        or delete, it is quite possible to bump into this limit on a 
        moderately large database.

        The problem is that Netware 3.11 reacts rather poorly to having 
        its lock limit exceeded. It appears to count a lock violation 
        every time it looks at the connection in question, which is still 
        trying to lock more records. Eventually (3-5 minutes) some internal
        table overflows, and the entire server goes down, with a 
        frightening message that instructs you to cycle the power. Doing
        this during working hours on large networks tends to result in
        unhappy users. There are two things you can do if this happens 
        to you. The first is to increase the number of locks available,
        and the second is to apply the Netware patch that prevents the
        abend of the server (humungous queries can still fail, but at
        least the server doesn't fail along with them). To increase the
        number of locks available, enter the following commands at the
        file server console or in your AUTOEXEC.NCF file:

        set maximum record locks per connection=10000
        set maximum record locks=200000

        The first parameter is the most locks any single connection can
        have, and the second is the most the entire server can keep 
        track of. These values (10,000 and 200,000) are the maximums
        that Netware 3.11 can accomodate. By setting the maximum record
        locks per connection to 10,000, Access can handle a transaction
        up to 20 MB. To fix the server abend problem, you need to 
        download the latest Netware 3.11 patch file. It can be found on
        CompuServe in the NOVFILES section; as of this writing, the
        current version is 311PTD.ZIP. You will need to load two of the
        NLMs from this file, either directly from the server console or
        in your AUTOEXEC.NCF file:

        load patchman.nlm
        load ttsfix.nlm 

>	Also See MSKB Article number Q102522

32. How can I set up a Query By Form (QBF)?

        See MSKB Article number Q105523.
        
Forms:
=====

33. Why do I get a #NAME error for a calculated control on a 
form or a report?

        You are probably using the same name for a calculated text box
        as one of the terms in the expression. In the following example,
        Access produces a #NAME error if you enter the expression in a
        control named City, State, or ZIP:

        =[City] & ", " & [State] & "  " & [ZIP]

        This creates a circular reference that may be resolved by
        changing the name of the control that contains this expression
        to something (anything) other than City, State, or ZIP.

34.  When I Tab past the last control on a form, how can I keep Access
from going to the next record (or backwards when I Shift+Tab back
from the first control)?

        A) Create two small, transparent buttons (set their Transparent
           property to Yes). Be careful that you don't make them
           invisible by setting their Visible properties to No.
        B) place one of the buttons just to the left of the first
           user-editable control on the form, and place the other just to
           the right of the last user-editable control.
        C) Create two macros that you will assign to the buttons' OnEnter 
           events:
           i)  For the first button, use GotoControl to go to the FIRST
               control on your form.
          ii) For the other button, use GotoControl to go to the LAST
              control on your form.
        D) Choose the Tab Order command from the Edit menu and place the 
           the button at the bottom of the tab order; place the last button
           at the top of the tab order.
        
        HOW IT WORKS: As you tab through the controls and reach the
        last editable control, pressing Tab again enters the new,
        transparent button.  Since its OnEnter event triggers a
        macro that sends you back to the first editable control, it
        has the effect of keeping you on the same record.  Pressing
        Shft+Tab from the first control has the opposite effect.

35.  How do I write information to the status bar and gas-gauge
indicator at the bottom of the screen?  

        You can use the semi-documented SysCmd() function to do this.
        See MSKB article number Q103404.

36. How do I add my own record navigation (first/last/next/previous)
to a form?

    Function csvGoToRecord (ByVal Direction As String) As Variant

        ' From the "Access Basic Cookbook"
        ' 
        Const FUNCTIONNAME = "GoToRecord"
        Const csvMB_ICONEXCLAMATION = 48
        Const csvCASEINSENSITIVE = 1
        Dim X As Integer

        X = (InStr(1, "First   Last    PreviousNext    New     ", Direction, 
        -> csvCASEINSENSITIVE) + 7) \ 8
        If X <> 0 Then
            X = Choose(X, A_FIRST, A_LAST, A_PREVIOUS, A_NEXT, A_NEWREC)
            On Error Resume Next
            DoCmd GoToRecord A_FORM, Screen.ActiveForm.FormName, X
            On Error GoTo 0
            csvGoToRecord = X
        Else
            MsgBox "Invalid direction argument.", csvMB_ICONEXCLAMATION, 
            -> FUNCTIONNAME
            csvGoToRecord = Null
        End If

    End Function
                
37. How do I tell when the user has moved to the blank record at the
end of a table by pressing the Next button on my form?

        Here's a function that you can call to tell you if you're on 
        the new record or not:

        Function AtNewRecord(frm as Form)
            Dim varTemp as Variant
            On Error Resume Next
            varTemp = frm.Bookmark
            AtNewRecord = (Err <> 0)
            On Error Goto 0
        End Function

        This works because attempting to get the bookmark for the new 
        record triggers an error.

38. How do I select a control on a form without accidentally moving it?

       	1.)  Change the grid size on the form so it's got a little 
       	larger granularity (select the form, and look for the gridX 
       	and gridY properties).  Also, make sure that Snap To Grid is 
       	On in the Layout menu.
       	2.)  Rather than clicking ON the control, click outside the 
       	control and drag over the control. Then let go of the mouse.  
       	That'll select the control without any chance of moving it.
       	3.)  If you DO move the control, just press alt-Backspace (or 
       	use any other method you like to undo).  

39. How do I copy all the information from the previous record on a
form to a new record?

        Users can copy the contents of any single field by using the
        Ctrl+' combination. If you want to duplicate an entire record
        on to a new record, see MSKB article number Q88670.

40. How do I incorporate photos in my forms, as Microsoft did in the
Employees for Northwinds?

        MSKB article Q100169 describes how Microsoft did it.       

41. How do I display a form without the caption bar at the top?

       	See MSKB Article number Q103261.
  
42. How can I change the cursor on my forms to something bolder?

        Access uses the default Windows cursor, and this decision is
        not exposed to your control. If you have a recent version of the
        Microsoft Mouse utilities, you can pick a larger cursor to 
        use in all of your Windows applications.
             
43. Is there a tool or method to convert Visual Basic forms to Access
forms or vice versa?

        There are currently no such tools that I am aware of, but
        a number of people have expressed interest in one, so possibly
        some entrepreneur is working on it even now.
        
Reports:
=======

44. How do I print reports to a file?

        See OUTPUT.ZIP in Lib 5. This contains a DLL and 
        instructions for sending output to straight ASCII text, RTF, 
        or the Excel BIFF format.

45. Why do I get extra blank pages between each page?

        You probably have extended the design surface so that it
        extended beyond the size of your printed page.  To fix this
        situation, open your report in design mode and pull in the right and
        bottom margins as far as possible to the top or left.  If the design
        surface is as small as possible and it still fails, check the
        File-Print Setup menu option and make sure that the margins are
        correct for your paper size.

46. How do I print a certain number of labels based on a "count" 
field in a record?

        First create a table called LabelDriver with only ONE field. 
        Make it a counter field and make it the primary key. Add as 
        many records to this table as the MAXIMUM number of labels 
        you will want for any given individual. There should be no gaps
        in the sequence numbers of the counter field. Now create a new
        query. Add your NameAndAddress table to the query. The table
        should have a field which contains the number of labels you 
        want to print for any given record. Assume this is a field called 
        "LabelCount". Now add the LabelDriver table to the query. Do NOT
        make any link between the Name table and the LabelDriver. The 
        reason for this is that you want to have EACH of your name records
        link out to ALL of the records in the LabelDriver table. This is 
        called a "cross-product" or "Cartesian" join, and is not something 
        you would ordinarily want to do, but for this task it works fine.
        Drag the appropriate fields as needed from the NameAndAddress table
        down to the query grid. Now, in order to limit the number of labels 
        to the LabelCount field, drag the 'id' or counter field from the
        LabelDriver table down to the query grid as well. (Uncheck the "show"
        checkbox because you don't need to see this field in the query 
        output.) In the selection criteria cell for the LabelDriver.ID 
        field put:

        <=[LabelCount]

47. How do I avoid "Out of Memory" errors on my report?

        Here's what Kim Abercrombie from Microsoft PSS has to say
        about this problem:
        
        First, it helps to visualize a big picture of how reports
        work when addressing this issue.

        Reports create a query, combined with the underlying record
        source, for every section of the report.  IE: a query for
        the report header, page header, group header, detail
        section, group footer, page footer, and report footer.

        All of these queries are then combined into what is called a
        Segmented Virtual Table or SVT.  The final output or SQL
        string needs to be compiled in a 64k limit.  If this limit
        is hit an "out of memory" error can occur.

        Things to look at when trying to help the customer avoid
        this error are:

        1) Long column names, table name, control names.  Reducing a
        30 character name down to a minimum will help

        2) Less expressions in the underlying queries.  Reducing
        space used for expressions in the Select list helps avoid
        the error.  If at all possible, place the expressions
        directly in the report instead.

        3) Fewer stacked query objects.  Avoid situations like query
        1 used to pull the data from 2 table, then query 2 just
        filters the data.  The more information that can be pulled
        together into one or fewer queries is far better than
        multiple queries each doing a portion of the tasks.

        4) Avoid including fields in the query that are not used in
        the final output of the report.

        5) Look at the subreports and the queries they are based on.
        Generally, subreports would *not* be based on the same
        queries as the main report, usually a smaller set of data.
        Again, check for fields that are not used in the final
        output.  Or possibly tables that do not need to be a part of
        this subset of data.

        The solution for getting around this error varies for
        everyone, the more you can describe the report and the
        underlying queries the easier it is to find a solution.

--------

        In addition to what Kim has to say on the subject, if a
        report based on a select query produces an "Out of Memory"
        error, try turning your select query into a make-table query
        and basing the report on the resulting table instead.

48. How do I print headers of the form "Page 1 of 12" on my report?

        See MSKB Article number Q97517.

> 49. Where do I find more information on report techniques?
>
>	(This list comes from Kim Abercrombie of Microsoft PSS)
>	The most frequently asked questions for reports can be answered 
>	by referring to the documentation, searching Help, or reviewing
>	the step by step examples in the sample database Solutions.   
>
>	(The references are for version 2.0 of Microsoft Access)
>
>	The User's Guide includes many common tips, such as:
>
>	"Combining Two or More Reports" - chapter 22, for details on 
>	combining subreports.
>	"Adding Page Numbers" - chapter 23, for "Page X of Y" or 
>	total pages example.
>	"Calculating Totals on Several Group Levels" - chapter 23.
>	"Calculating Percentages" - chapter 23.
>	"Using a Command Button to Print a Report" - chapter 26.
>	"Asking for Criteria Before Printing a Report" - chapter 26.
>	"Highlighting Data and Sections Dynamically" - chapter 26.
>	"Providing Custom Page Numbers" - chapter 26.
>	"Controlling the Number of Detail Line Printed on a Page" 
>	- chapter 26.
>	"Placing Totals in Page Headers and Footers" - chapter 26.
>	"Sending a Report to a Word for Windows Document" - chapter 26.
>
>	Some common questions answered in Help are:
>
>	Referencing subreport controls - "Referring to Controls on a 
>	Subform or Subreport (Common Question)".
>	Creating a dynamic sort for reports - "Sorting a Report 
>	(Common Question)".
>	Creating labels continuous mailing labels = "Creating Mailing 
>	Labels for a Dot Matrix Printer".
>	Shrinking or not printing controls when there is no data - 
>	"Reducing White Space in Reports".
>
>	Most common questions directly relate to controlling what you 
>	print on reports. The Solutions sample database contains the 
>	following examples plus "show me" Help topics for step by step 
>	instructions:
>
>	"Draw a circle around data to accentuate it".
>	"Hide a section when it falls at the top of a page".
>	"Hide and show controls based on the value in another control".
>	"Hide and show sections that print on a preprinted form".
>	"Print "Continued" at the bottom of a preprinted form".
>	"Print report criteria that was entered in a dialog box".
>	"Print the first and last entries on a page in a page header".
>	"Repeat a group name at the top of a column or page".

Macros:
======

50. How do I temporarily comment out a line in a macro?

        Although macros do not support the REM statement you may be used 
        to from batch files or BASIC, you can achieve a similar effect. 
        Simply activate the Condition column for your macro and enter 
        "False" as the condition for any action you wish to temporarily
        skip. If there's already a condition column, simply add "False 
	and " to the start of the condition to make it always False.
        
51. Why aren't there more questions about macros here?

        Most professional Access developers tend to use modules rather
        than macros in their databases. A module can do anything a macro
        can do except execute automatically at startup and modify menus.
        The key difference is that modules can be written to trap and
        cure errors, while any error in a macro brings operations to a 
        halt.

Modules:
=======

This file uses -> as a line-continuation marker in long code lines.
Any line which starts with -> should be appended to the end of the
previous line when you are typing the code into your module.

52. Why does Access put "Option Compare Database" at the top of 
every module I create?

	Option Compare Database tells Access to use its standard
	order when sorting data -- the same order it uses in
	queries. You can search on "Option Compare" in Access Help
	to see the other available sort orders. Most developers
	recommend you add "Option Explicit" directly after this
	line, which will force you to declare all your variables and
	help cut down on code errors due to mistyping.

53. Is there a way in Access Basic to determine the current 
record number so that the record number can be used in a 
GoToRecord action?

        Tables and query results (dynasets) don't really HAVE 
        "record numbers" in the dBase sense. Yes there is a number 
        shown at the bottom of forms and table datasheets, but that
        number is dynamic. The record number will vary depending on 
        the sort order, or the filter, or the query used. Records are
        distinguished from one another by their Primary Key -- a unique
        field or combination of fields. If you need to return to a 
        particular record you can save that location in a Bookmark
        variable, or you can save the values in the key fields and do a
       .seek or a .findfirst method to re-locate the records.

54. How do I change a field to Proper Case (first letter of each 
word capitalized)?

        Here is a function to convert strings to proper case:

        Function csvMultiCap (ByVal InString As Variant) As Variant

        Dim ANSI As Integer, Temp As Variant, X As Integer

        Temp = LCase(InString)                      ' Start with lowercase.

        If Len(Temp) > 0 Then                       ' If not empty string.
            Mid(Temp, 1, 1) = UCase(Left(Temp, 1))  ' I-cap first character.
            For X = 2 To Len(Temp) - 1              ' Check other characters.
                ANSI = Asc(Mid(Temp, X, 1))         ' Obtain ANSI values.
                If ANSI < 65 Or ANSI > 122 Or (ANSI > 90 And ANSI < 97) Then
                    Mid(Temp, X + 1, 1) = UCase(Mid(Temp, X + 1, 1))
                End If
            Next X
        End If

        csvMultiCap = Temp

        End Function

        You can call this function via a call to a helper function
        in the AfterUpdate event of a field:

            Function SetProper()
                    Screen.ActiveControl = csvMultiCap(Screen.ActiveControl)
            End Function
                
        or as a part of an expression in a calculated column of a 
        query:

        ProperName: csvMultiCap([Name])


55. How do I calculate elapsed business days between two dates?

        See BDAYS.ZIP in Lib 6

56. How do I dial a modem from Access?

        See COMM.ZIP in Lib 6 and DIAL3.EXE in Lib 6.

57. How do I display system information in an About box?

        See SYSINF.ZIP in Lib 7.

58. How do I play a sound file?

        If your computer is equipped with a sound card or a speaker
        driver, you can play .WAV (waveforms).  First, add the
        following declaration (all on one line) to the Declarations
        section:
    
        Declare Function csvSndPlaySound Lib "MMSYSTEM.DLL" Alias
        -> "SndPlaySound" (ByVal FileName As String, ByVal How As Integer) 
        -> As Integer

        Next, enter this funciton:
    
        Function csvPlayWave (ByVal FileName As String, ByVal How As Integer)
        -> As Integer
    
            csvPlayWave = csvSndPlaySound(Trim(FileName), How)

        End Function

        You can call this from a form or field event like so:

        =csvPlayWave("c:\windows\tada.wav", 1)

        Also see WAVMAC.ZIP in Lib 15 for some other ways to deal with
        sound files.

59. How do I set and retrieve global variables?

        You actually can't refer directly to global (or local 
        or static) variables directly in a form event or a field event
        or a macro. You need to write a sort of "helper" function to
        return the value for you:

        Function GetTheVar () as variant
            GetTheVar = TheVar 'a global variable previously set
        End Function

        Then you can use this function wherever you would use the 
        actual variable itself, for example in the 'criteria' field of
        a query:

        like GetTheVar() & "*"

        If you have a lot of these variables you can write a couple 
        of generic "set" and "get" functions:

        Function SetGlobalVar (var as variant)
            Select Case var
            Case "First_Var":
                First_Var = var
            Case "Another_Var":
                Another_Var = var
           'and so on
           Case Else:
               msgbox "Unrecognized variable name: " & var
           End Select
        End Function

        Function GetGlobalVar (var as variant) as variant
            Select Case var
            Case "First_Var": 
                GetGlobalVar = First_Var
            Case "Another_Var":
                GetGlobalVar = Another_Var
            'and so on
            Case else:
                MsgBox "Unrecognized variable name: " & var
            End Select
        End Function

        You will need to modify these functions whenever you 
        have another variable you would like to handle, but this is
        better than having to write separate functions for each
        variable. If you have a lot of Select Case statements this
        method can be slow, but for just checking global parameter
        values, this method works fine.

        However whenever possible instead of using global variables I
        create a hidden form and store information there. Forms that
        are open are available from anywhere, and since the form is 
        invisible the user doesn't need to know that they exist.

60. How do I send messages via Microsoft Mail?

        See SMAPI.ZIP in Lib 6.

61. How do I search by Soundex codes?

        See SNDX2.ZIP in Lib 3.

62. How do I spell out numbers for check printing?

        See SPELL.ZIP in Lib 6.

63. Where are there more functions for string manipulation?

        See STRDLL.ZIP in Lib 6.

64. How do I make certain events happen at certain times?

        See EVENTS.ZIP in Lib 7 and TIMER.ZIP in Lib 4.

65. How do I use the standard Windows File Open and File Save 
dialog boxes?

>        See CMMDLG.ZIP in Lib 6.

66. How do I execute an internal DOS command such as COPY?

    Function csvExecuteCommand (ByVal CommandText As String, ByVal 
    -> ShowFlag As Integer) As Integer

        ' From the "Access Basic Cookbook"
        '
        ' Declare Function csvWinExec Lib "Kernel" Alias "WinExec" (ByVal 
        ' -> ApplicationName As String, ByVal State As Integer) As Integer
        '
        ' Accepts: CommandText  The name of the internal DOS command,
        '                       including any command-line arguments. For
        '                       example, "copy a:\*.* b:\"
        '          ShowFlag     One of these constants indicating how the
        '                       DOS window is displayed:
        '
        '                       csvSW_HIDE           hidden
        '                       csvSW_MINIMIZE       minimized
        '                       csvSW_SHOW           current size/position
        '                       csvSW_SHOWMAXIMIZED  maximized
        '
        Const csvSW_HIDE = 0
        Const csvSW_MINIMIZE = 6
        Const csvSW_SHOW = 5
        Const csvSW_SHOWMAXIMIZED = 3
        Dim ComSpec As String, Msg As String, Reason As String, X As Integer
        Dim CRLF As String

        CRLF = Chr$(13) & Chr$(10)
        csvExecuteCommand = True

        ComSpec = Environ$("comspec")
        ComSpec = IIf(ComSpec = "", "command.com", ComSpec)

        If CommandText <> "" Then
            ComSpec = ComSpec & " /c " & CommandText
        End If

        X = csvWinExec(ComSpec, ShowFlag)
        If X < 32 Then
            Select Case X
                Case 0: Reason = "Out of memory"
                Case 2: Reason = "File not found"
                Case Is < 32
                        Reason = "Error code" & Str$(X)
            End Select
            Msg = "Couldn't execute" & CRLF & "'" & ComSpec & "'." & 
            -> CRLF & CRLF & "Reason: " & Reason
            MsgBox Msg, csvMB_ICONINFORMATION, "Execute Command"
            csvExecuteCommand = False
        End If

    End Function

67. How do I copy a file directly under control of Access?

       Function Copy_File (from_name, to_name) As Integer

        On Error GoTo Copy_file_Err

            Dim whole As Integer
            Dim part As Integer
            Dim buffer As String
            Dim start As Long
            Dim x As Integer

            Open from_name For Binary As #1

            whole = LOF(1) \ 32000      'numer of whole 32768 byte chunks
            part = LOF(1) Mod 32000     'remaining bytes at end of file
            buffer = String$(32000, 0)
            start = 1

            Open to_name For Binary As #2

            For x = 1 To whole          'this for-next loop will copy 32,000
                   Get #1, start, buffer    'byte chunks at a time. If there is
            Put #2, start, buffer    'less than 32,000 bytes in the file,
            start = start + 32000    'whole = 0  and the loop is bypassed.
            Next x

            buffer = String$(part, 0)   'this part of the routine will copy

            Get #1, start, buffer       'the remaining bytes at the end of the
            Put #2, start, buffer       'file.

            Close
            Copy_File = True
            Exit Function

         Copy_file_Err:
                MsgBox Error
                Copy_File = False
            Exit Function

         End Function

68. How do I read and write information from .INI files?
 
        Declare Function GetProfileInt Lib "Kernel" (ByVal
        -> lpApprofSection As String, ByVal lprofKeyName As 
        -> String, ByVal nDefault As Integer) As Integer

        Declare Function GetProfileString Lib "Kernel" 
        -> (ByVal lpApprofSection As String, ByVal lprofKeyName 
        -> As String, ByVal lprofDefString As String, 
        -> ByVal lRetStringedString As String, ByVal nSize 
        -> As Integer) As Integer

        Declare Function WriteProfileString Lib "Kernel" 
        -> (ByVal lpApplicationName As String, ByVal 
        -> lprofKeyName As String, ByVal lpString As String) As Integer

        Declare Function GetPrivateProfileInt Lib "Kernel" 
        -> (ByVal lpApplicationName As String, ByVal 
        -> lprofKeyName As String, ByVal nDefault As Integer, 
        -> ByVal lpFileName As String) As Integer

        Declare Function GetPrivateProfileString Lib "Kernel" 
        -> (ByVal lpApplicationName As String, ByVal 
        -> lprofKeyName As Any, ByVal lprofDefString As String, 
        -> ByVal lRetStringedString As String, ByVal nSize As Integer, 
        -> ByVal lpFileName As String) As Integer

        Declare Function WritePrivateProfileString Lib "Kernel" 
        -> (ByVal lpApplicationName As String, ByVal lprofKeyName 
        -> As Any, ByVal lpString As Any, ByVal lplFileName As 
        -> String) As Integer 
        
        Function DeleteProfileEntry (profSection As String, 
        -> profKey As String, INIFileName As String) As Integer

            Dim StringWritten As Integer
            Dim xnull As Long

            xnull = 0

            StringWritten = WritePrivateProfileString(profSection, 
            -> profKey, xnull, INIFileName)
            If StringWritten = 0 Then
                    MsgBox "Error writing to " + INIFileName$, 0, "ERROR"
                    DeleteProfileEntry = False
                Exit Function
            End If

            DeleteProfileEntry = True

        End Function

        Function GetEntriesInSection (profSection As String, 
        -> profDefString As String, INIFileName As String) As String
        Dim nSize As Integer
        Dim RetString As String
        Dim CharsReturned As Integer
        Dim xnull As Long

        xnull = 0

        RetString = Space$(2048)
        nSize = 2048

        CharsReturned = GetPrivateProfileString(profSection, xnull, 
        -> profDefString, RetString, nSize, INIFileName)

        If CharsReturned = 0 Then
                GetEntriesInSection = "error"
                Exit Function
        End If

        GetEntriesInSection = RetString

        End Function

        Function GetPrivateProfile (profSection As String, 
        -> profKey As String, profDefString As String, 
        -> INIFileName As String) As String
        Dim nSize As Integer
        Dim RetString As String
        Dim CharsReturned As Integer

        RetString = Space$(80)
        nSize = 80

        CharsReturned = GetPrivateProfileString(profSection, profKey, 
        -> profDefString, RetString, nSize, INIFileName)

        If CharsReturned = 0 Then
                GetPrivateProfile = "error"
                Exit Function
        End If

        RetString = Trim(RetString)
        RetString = Mid(RetString, 1, Len(RetString) - 1)
        GetPrivateProfile = RetString

        End Function

        Function WritePrivateProfile (profSection As String, 
        -> profKey As String, profNewString As String, 
        -> INIFileName As String) As Integer

        Dim StringWritten As Integer

        StringWritten = WritePrivateProfileString(profSection, profKey,
        -> profNewString, INIFileName)
        If StringWritten = 0 Then
                MsgBox "Error writing to " + INIFileName$, 0, "ERROR"
                WritePrivateProfile = False
                Exit Function
        End If

        WritePrivateProfile = True 
        End Function

        Here is an example which retrieves the 'shell=' entry from
        your SYSTEM.INI file:

        Dim shell_name As String
        shell_name = GetPrivateProfile("boot", "shell", "", "system.ini")
        MsgBox "Your Windows shell program is: " & shell_name

69. How do I send a fax from Access using WinFax?

        The sample code below assumes you are on a form and want to fax 
        out a report of the current record. The code can be attached to 
        the "on push" property of a button. It would look like this   
        =FaxRecord([phone],[contact name])

        This does not address starting up WinFax first or choosing it 
        as your default printer. There is sample code for the printer 
        routines in a file called SETPRT.ZIP in Library #7.

        Dick Cullom
        Microsoft Access, PSS
        '==============================================================
        'WinFax should already be running.
        'Grabbing the telephone number and name from the form will 
        'eliminate seeing the WinFax "send" dialog screen, unless you 
        'have preview set to "on".  You will still get a "send 
        'confirmation" message.
        '==============================================================
        Function FaxRecord (FaxNumber As String, Receiver As String)

            On Error GoTo FAX_Error
            Chan = DDEInitiate("FaxMng", "Transmit") 'Begins Conversation
            DDEPoke Chan, "Receiver", Receiver 'Fills-in who the fax goes to
            DDEPoke Chan, "Fax Number", FaxNumber 'Fills-in telephone number

        'Opens report in print mode on the current record of the form
            DoCmd OpenReport "ReportName",0,"", "[id]=Forms![formname]![id]"
            DDETerminate Chan
        FAX_Exit:
            Exit Function
        FAX_Error:
            MsgBox "Error: " + Error$, 0, "FAX"
            Resume FAX_Exit
        End Function

70. How do I calculate someone's age from their birthdate?

        This solution is longer, runs slower, but is easier to understand.
        It just gets the current number of years, and then subtracts 
        one from the age if the requested birthday hasn't happened so 
        far this year.

        Function GetAge (varBD As Variant)
            Dim varAge As Variant
            varAge = DateDiff("yyyy", varBD, Now)
            If Now < DateSerial(Year(Now), Month(varBD), Day(varBD)) Then
                varAge = varAge - 1
            End If
            GetAge = varAge
        End Function

        This solution works basically the same, but counts on the fact 
        that a TRUE value is the same as -1, so it just adds on the 
        value of
             Now < DateSerial(...)
        which will return -1 if the current date is less than the 
        birthdate passed in.

        Function GetAge (varBD As Variant)
            Dim varAge As Variant
            GetAge = DateDiff("yyyy", varBD, Now) + 
            -> (Now < DateSerial(Year(Now), Month(v
        End Function

71. How do I get the fully qualified path and file name of the currently-
open Access database?

        Sorry, you can't.
        
Wizards & Tools:
===============

72. How do I export multiple objects at once?

        See ACEXPO.ZIP in Lib 8.

73. How do I change all references to the names of Access 
objects?

        See REPLAC.ZIP in Lib 15.

74. Where do I find more information on the Access Distribution 
Kit?

        See RUNTME.TXT in Lib 13.

75. How do I convert macros to modules?

        See FIRST.ZIP in Lib 15, which contains several 
        excellent tools: A macro to module converter, some 
        additional form design buttons, a new module template and an 
        automated menu builder.

76. How do I create a Help File to use with Access?

        You will need the Microsoft Help Compiler to create a Windows
        help file. You can download the latest version from the WINSDK
        forum; the file name is HC505.EXE (this is a recent update
        which works with version 6.0 of Word; the previous version did not).
        While you can create the source code for help files directly
        in any word processor that understands the RTF format
        (such as Microsoft Word), many people prefer to use a 
        dedicated front-end tool for the purpose. One which has been
        mentioned by several regulars on the Access forum is Visual Help,
        which has a shareware demo version available as VH.ZIP in
        Lib 16 of the WINSDK forum.

77. Is there any way to have access link to MS Word 6.0 to do spell
checking on text or memo fields?

        There is a method for this in MSKB Article number Q96544 which
        depends on writing temporary files out and reading them in to
        Word. Microsoft has also recently issued documentation on the
        Common Speller Applications Programming Interface (CSAPI), which
        is the standard speller interface used in Microsoft products.
        However, the CSAPI license explicitly prohibits using any of
        the existing MS product dictionaries to spell-check other
        applications, so this does not appear to be a viable alternative.
	There is a new commercial product which you can use for spell-
	checking from Access. Called VT-Speller, it is a VBX/DLL 
	available for $99 from VisualTools, 800-884-8665 or 913-599-6500.

> 78. How do I use DDE to poke information into an Access table?
>
>	Although Access does not act as a DDE server or accept DDEPoke 
>	commands, there is a workaround for this problem which involves
>	using DDEInitiate to fool Access into running a function. See
>	MSKB Article number Q100167 for the details.
        
SQL and ODBC:
============

79. How do I talk directly to a SQL backend without involving 
the Access parser?

        You can use the SQL Passthrough Library for this. See 
        SPT100.EXE in Lib 11 (for Access 1.0) or SPT110.EXE in Lib 
        11 (for Access 1.1).

80. What do I need to use Btrieve files via ODBC?

        See ACBTR.ZIP in Lib 2.

81. How can I make my SQL application run faster?

        See RJETWP.ZIP in Lib 11.

Security:
========

82. Why is it that after securing my application following the manual, 
anyone with another copy of Access can still get in?

        There is a Microsoft white paper on security, SECURE.ZIP, in Lib
        12 that explains the security model in detail.  Briefly the
        situation is this: whoever is logged in when the new database is
        created is the owner of the database (called the Creator).  The
        database owner has lasting permissions that can not be removed in
        any direct way.  But in every newly installed copy of Access 1.X,
        the default user is Admin of the Admins group.  In addition the
        default user Admin has the same Security ID (SID) in every system of
        Access 1.X.  So if you created the database as Admin, no manner how
        you logged in later, how many new groups you added, or how much
        security you added, any user with another copy of Access would have
        Creator permissions on your database.  To see how to simply and
        reliably secure your system, see the next question.

83. How do I secure an Access database?

        There is only one MicroSoft approved method to fully secure an
        Access 1.X database.  This is to use the MicroSoft Security Wizard,
        available as SECWIZ.ZIP in Lib 12.

        Step I. Install the MicroSoft Security Wizard following the
        directions that come with it.

        Step II.  Open your database, say NWIND.MDB (or whichever
        database you wish to secure), under a developer account, say DEV
        with PIN 1234.  Be sure that you have permissions to everything in
        the database.  One way you may achieve this is:

        A.  Open NWIND.MDB (substitute your database here)
        B.  Set password for Admin User
        C.  Add New User (DEV in this example with PIN 1234)
        D.  Make User DEV a member of the Admins and Users groups
        E.  Logout/Close Access
        F.  Start Access and Login as DEV
        G.  Remove Admin User from Admins Group (Delete Admin)
        H.  Logout/Close Access
        I.  Start Access
        J.  Attempt to login as Admin (You should not be able to)
        K.  Login as DEV user

        Eliminating the original Admin user as above and verifying is
        recommended but not required.  It would be a good idea to save a
        copy of your SystemDB file, which was orginally named "SYSTEM.MDA,"
        say as SYSTEMOR.MDA, for possible later use when you don't want
        security.  You will not be able to recreate the original Admin user
        any way short of reinstalling if you don't backup.

        Step III.  Run the MicroSoft Security Wizard.  Use a new name
        for the secure database, such as NWINDSEC.MDA.  NWIND.MDB will not
        be modified.

            Your new database is now secure.  All permissions in your new
        database have been removed from the three original groups: Guests,
        Users and Admins.  Only the DEV user has permissions to logon to the
        system and access the objects.  From this point, you must assign
        security permissions to the groups/users you want, possibly creating
        new groups such as App_Read and App_Rd_Write.

84.  After securing a database, what are some methods to assign
permissions to users?

        Here it is important to remember, that a user who is using a
        new/clean system.mda is logging onto the system as the Admin user
        who is a member of the Users group.  Because of this, there are
        three scenarios you can follow when assigning permissions.

        Scenario A. Users are required to logon to the system.  Without
        logging on, users have no access to any of the objects.

        Remove all permissions from the Users group.  Create new
        groups and assign permissions to these groups.  Create new users and
        add users to groups as needed.

        Scenario B. Users can logon to the system, but it is not required.
        If they do not logon to the system, they will have limited access.

        Assign permissions to the users group for the objects you
        wish anyone not using your system.mda to have access to.  Next, add
        groups and users as needed.  Assign permissions as needed.

        Scenario C. Similar to step 2, but users cannot logon to the system.
        Users are never prompted for a logon and access to objects may be
        limited.

        Assign permission to the users group only.  There is no need
        to create other users or groups.  Save the system.mda you used to
        create the database as your administrator system.mda.  When using
        this system.mda, you are prompted for a logon.  The only active user
        is DEV.  When you need to make changes to the database, use this
        system.mda.  All other users will use a clean/new system.mda.  They
        will not be prompted and will only have the permissions you assigned
        to the users group.

        In all of the above cases, large numbers of changes may be
        required of many objects.  There is an utility, the Learning Network,
	Inc. Security Wizard 1.1a , that will automate this task.  It may 
	be downloaded from Lib 12 as LNSEC.ZIP.  It installs in a way 
	similar to the Microsoft Security Wizard, and is to be used in 
	conjunction with the MSSW.  Its one task is to change the security 
	of selected groups to a generic Read, Read_Write, Full or No 
	Security type.  After this mass processing, it is still often 
	necessary to make individual adjustments to objects that have 
	special requirements, but at least these will often be fewer in 
	number.


85.  How should I secure databases on a network?

        By default, Microsoft Access allows you to secure a database
        across a network.  The key is to place the system.mda file on the
        network.  Users can then modify their MSACCESS.INI file to point to
        the location out on the network.  You can also use the Change
        Workgroup Icon to change the ini setting.  There are also some
        sample applications on CompuServe that allow you to change
        workgroups more easily.  There are two basic strategies to use.

        A.  Create one system.mda and place it on a network.  When
        developing new MDB files, use this system.mda.  This will enable
        users to only have to use one system.mda.  All databases are secured
        by this system.mda.  This is good if one person is designing all
        databases used.

        B.  Create one system.mda per database.  This is easier for
        developers, but is more difficult for users since they have to
        change workgroups each time they change databases.  This is good if
        several different people are creating databases.

Access 2.0:
==========

> 86. What's new in Access 2.0?
>
>	There are many, many new features in version 2.0. Some of the most
>	significant include: a vastly expanded set of events and
>	properties, many more properties that can be set at runtime,
>	many new Wizards and Builders, improved interoperability with
>	other products, and a richer and more object-oriented Access
>	Basic. 

> 87. How much will it cost to upgrade my copy of Access?
>
>	The upgrade from any previous version of Access is $99, sold in
>	a package at $129 with a $30 rebate coupon.

> 88. Will Access 2.0 work with Access 1.1 files?
>
>	Access 2.0 can generally load and run Access 1.x database files.
>	However, to make changes to any object requires converting the
>	database to 2.0 format, after which it cannot be used in 
>	Access 1.x any longer.

For more information:
====================

        Microsoft Access ships with its own list of frequent 
questions. Look for the file PSSKB.TXT in your Access 
directory.
        Microsoft Access bugs and tips from the Microsoft 
Knowledgebase are periodically updated in a pair of files, 
ACC-KB.ZIP in Lib 1 and ACC-IN.ZIP in Lib 1. You can also 
get the most recent Knowledgebase tips on CompuServe by GO 
MSKB. This is the same collection of solutions that the Microsoft
technical support people are referring to when you call them on the
phone.

You can get the KB sent by mail free from MS by dialing the Fasttips line @
1-800-936-4100 and following the steps below:

   1. Press 4 for Microsoft Access.
   2. Press 1 for Express Order Service.
   3. When prompted, select your delivery method - mail.
   4. When prompted, leave your name and mailing address in the voice
      mailbox.
   5. When prompted, enter the number of the Item ID: 0928 and then press #.

   Recap: 4,1,DeliveryMethod,Name&Mailing Address,0928#

        The Help File can't be faxed, only mailed.  It is pretty
simple but you have to follow the instructions carefully...don't
press the numbers *until* told to do so as this will cause havoc.
        The Microsoft Access Companion Disk, with 4 sample 
applications and tips on their construction, is available as 
COMPAN.ZIP in Lib 14.
        PRMPT.MDB, in Lib 15, is a sample database which 
accompanies the Microsoft Press book RUNNING MICROSOFT 
ACCESS.

Periodicals:
===========

ACCESS ADVISOR, $35 for 1 year (6 issues) from PO Box 469030, 
    Escondido, CA, 92046.
SMART ACCESS, $139.00 for 1 year (12 issues) from PO Box 888,
    Kent, WA, 98035-0888.
INSIDE MICROSOFT ACCESS, $49.00 for 1 year (12 issues) from
    (800) 223-8720 or (502) 491-1900.

Books:
=====

        There are a lot of Access books on the market. Here's our
selection of the most useful:

"Access 1.1 Developer's Guide", includes diskette, $39.95
Roger Jennings
Sams Publishing / ISBN: 0-672-30178-4

"Access Basic Cookbook", includes diskette, $34.95
Chris St. Valentine [72702,724]
Addison-Wesley / ISBN: 0-201-62636-5

"Inside Access 1.1, Special Edition", includes diskette, $39.95
Chris St. Valentine [72702,724]
New Riders Publishing / ISBN: 1-56205-194-6
