Access Database Design & Programming, Second Edition by Steven Roman Unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. If you have any error reports or technical questions, you can send them to booktech@oreilly.com. (Please specify the printing date of your copy.) This page was last updated December 20, 2001. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification UNCONFIRMED errors and comments from readers: [all] This book contains no reference to or information on the DoCmd object and its methods/properties/uses. ?general? An example of a database called LIBRARY is used throughout the book. In this sample database, Jane Austen is entered as the author of the book "Jane Eyre." "Jane Eyre" was written by Charlotte Bronte! Although my technical knowledge of Access Database has not been impeded by this mistake, it should be corrected in the next version so as to avoid alienating any English literature scholars who have taken up the study of databases. I do, however, appreciate the author's effort to use an example that is easily understood. The LIBRARY database is certainly better than the database of airplane parts I encountered in my last book. ?general? significant suggestion: From my perspective, as someone who played around quite a bit with Access 2 and essentially ignored Access until Access 2000, there is a gap in the presentation. Specifically, I found no mention of references and libraries before the DAO section of the text. I'm sure this sounds silly to you, but it took me a while to figure out that for the VBE, I needed to go to Tools, Options, References and put a check next to Microsoft DAO 3.6 Object Library, in order to get the code examples to run. It's one of those "It's obvious, ONCE you see it" problems. If your readers are all already using DAO code, they don't need to know. If they bought the book to learn about DAO (like I did), they may not know about references, or even object libraries. For housekeeping purposes, you might want to suggest a specific group of references that you expect to be checked before starting Section IV (VBA). You also might want to consider adding some mention of references and libraries to Chapter 8 or 9 (The VBE, parts I & II). Similarly, a brief discussion of how Access Projects and Access Databases are related would be useful. It would probably be appropriate at the beginning of Chapter 8. I found the Microsoft Visual Basic help link javascript:HelpPopup('actip9.hlp','IDH_acdefAccessProject'); to be helpful. Microsoft seems to be in love with the word project, using it in COM, C++, Access, Java, etc. At the beginning of Chapter 8, you do mention the fact that only one user project can be shown in the IDE per Access session, and point out that Access itself may open other projects. You don't mention that those projects may be opened as a result of establishing a reference (see above), or what an adp file might be, or why you would have projects at all. These suggestions may reflect the gaps in my knowledge more than a gap in your presentation. On the other hand, they may be a result of your familiarity with the topics making them invisible to you . [3] On the last line on the page, the reference to DELETE_ME table is unclear. {34} Figure 3-9 Index file between City, State, and Publisher: The index file in the example has pointers from "Kansas CityKS" pointing to the record for Kansas City, MO; the pointer for "Kansas CityMO" points to the record for Kansas City, KS. I am not an expert (obviously...or I wouldn't be reading the book), but this does not seem correct to me. [46] Regarding the second paragraph of Normalization heading: Why is (ISBN, Title,AuID) in 1st normal form? Couldn't the AuID attribute contain more than one Author ID? (57) top; It would help readers if the tables were labeled by name. When introducing algebraic concepts on tables S and T, for example, it would help to know which table is S and which table is T. I had to write in pencil next to the tables to keep them straight. Oddly, the suggested table labeling method is shown on page 74 (Implementing Joins in Microsoft Office), but not in too many other places. (76) The third row of the fourth table now reads: i j k l s h It should read: i j k l s j [83] The 3rd paragraph under heading OPTIMIZATION now reads: S joinT =" proj S.ISBN,Title,Price,PageCount T(sel S.A1=T.A1(SXT)) It should read: S joinT =" proj S.ISBN,Title,Price,PageCount (sel S.A1=T.A1(SXT)) (That is, the first T on the right side should be eliminated.) [93] Create the Books table scheme... example; FORIEGN KEY declarations are only specified in Multi-ColumnConstraint syntax (Page 93). The CREATE TABLE statment syntax (pg. 91) specifies that Multi-ColumnConstraints are preceded by a comma and must appear after all colunm definintions. The fourth line of the CREATE TABLE BOOKS scheme should then begin: PubID TEXT(10), CONSTRAINT Test FOREIGN KEY (PubID) REFERENCES When I run th code as printed, it wont compile. When I insert the comma, it does. (94) The CREATE INDEX Statement syntax; Ambiguous square bracket structure on line 2 of syntax definition. {101-103} entire pages; Initially, the tables are named Temp1, Temp2, and Temp3 and the SQL statements are in agreement. However, the accompanying text refers to them as tblA, tblB, and tblC. This causes some confusion. [102] The bottom bullet list now reads: These "row" pairs are all distinct. In fact: - Row 1 comes from row 1 of tblA and row 2 of tblC. - Row 2 comes from row 1 of tblA and row 1 of tblC. It should read: - Row 1 comes from row 3 of tblA and row 2 of tblC. - Row 2 comes from row 3 of tblA and row 1 of tblC. (122) In the first full paragraph, regarding the last sentence that reads: The following short program:" and the following code beginning "Dim..." This is not a program but a code snippet. I had quite a number of students that typed this (or similar) code in a new module. Without a sub and an end sub, this will produce an error. That will teach them not to program before Chapter 8, you might say. However, in our situation we had the following side effect: the form wizard was (falsely) complaining that it had not been installed. I would suggest to list a complete program here or to skip the example completely. [128] The first line of code on the page now reads: dbLibrary.Name = "LIBRARY" This needs to be omitted in order for the program to run. This line was not included in the first edition. [129] The fourth line of Example 7-2 now reads: Set dbLibrary = ws.OpenDatabase("d:\dao\library.mdb") In order for this module to run, it should read: Set dbLibrary = DBEngine.OpenDatabase("d:\dao\library.mdb") ?147? Perhaps the simplest, most intuitive (for me at least) way to insert a breakpoint in code is to simply click the left margin in front of the line. This toggles the breakpoint for the line. You might want to add this technique. {162, 165} Under "The Set Statement" heading, you use the term "nonobject variable declaration" in the Dim example. Later (page 165, Table 10-3) you use the term "Standard Variable" rather than nonobject variable. Are there nonobject variables that are not standard variables? If not, wouldn't it be more consistent and understandable to use "standard variable" (or "nonobject variable") throughout? {163} Under the "Arrays" heading, the sentence after the third set of code reads: ...then VBA will automatically set the first index to 0... If you're going to deal with that issue (array bounds), you should probably consider mentioning the Option Base statement. Obviously, if Option Base 1 is in effect, VBA will set the first index to 1. Also, if you mention Option Base 1, you should probably point out that while it affects array variables, it does NOT affect built-in objects. In other words, MyTable.Fields(0) always exists, whether the code uses Option Base 0 or Option Base 1. My feeling is that using Option Base 1 should be avoided whenever possible, but the reader should be aware that it exists, and its setting may affect his portion of a project. ?168-9? In the "Variable Lifetime" section, the phrase "lifetime of the entire module" is used (second to last paragraph on 169), but the lifetime of a module (i.e., when module-level variables' lifetimes begin and end) is not explained clearly. (189) The 14th sentence from the top now reads: The StrCmp function also... It should read: The StrComp function... {191} The sixth line of code in the first code listing on the page now reads: s = rsLastName) It should read: s = rs!LastName Also, the description of IIS() is a bit confusing. I would suggest adding one paragraph showing the IIS() version of that same code snippet to make things clearer, e.g., just after the sentence that ends "...if we try to assign a NULL value to a string variable," add: Using IIS, the code becomes much simpler: s = IIS(Not IsNull(rs!LastName), rs!LastName, "") which assigns the value of rs!LastName to s if rs!LastName is set, and uses the zero-length string ("") otherwise. You could then carry on with the discussion of how IIS evaluates all of its arguments regardless of the value of the first argument. {199} It would appear that the code in Example 12-2 is slightly incorrect. The variable names are not the same. If the error condition is experienced, a new table name is entered into the variable sTable, but it is not put into the variable TableName, which is used to open the record set after the Resume statement. It would appear that the variable names here need to be identical. (204) In the Sub DoExample() code, the line: Debug.Print rs!Name causes a runtime error, specifically: Run-time error 3265: Item not found in this collection The line should probably read: Debug.Print rs.Name (With a dot rather than an exclamation point.) ?212-213? Nothing wrong, just a suggestion. An object variable is an alias (or pointer) assigned to an object by the keyword "Set". A data value is assigned to a standard variable by the keyword "Let". Many object variables can be assigned to one object, while one data value can be assigned to many standard variables. (229) 1st line: The first line says "of the previous example,". However, the relevent example does not appear until further down page 229 (Example 14-6). ?233? Question: When are application-defined properties inherited? Built-in properties never are, and user-defined properties may be, but where do application-defined properties fit in? <237> suggestion for the "caveats" section half way down the page: Make the first "bullet" (warning against closing unupdated Recordset objects) the warning, and then just list the three ways that you can close an open Recordset object: 1) The close method 2) Exiting the procedure that declared the Recordset object or its Database 3) Closing either the Workspace or Database object that contains the Recordset object. ?240? I made the mistake of looking at the VB Help. When I looked at the listings for "Users" collection or "Groups" collection, everything was fine. Then I checked the same listing with "ADOX" following them. What the heck is "ADOX," and what's a "Catalog object?" No answer required... ?246? Microsoft appears to have added ANOTHER note to the CurrentDB Help listing that you quote. It doesn't make it any clearer to me. As my wife (who used to teach German) would say when I asked why some verb misbehaved: because that's how it is, just learn it! {265} There are two changes on this page that were corrected in the previous edition (see http://www.oreilly.com/catalog/accessdata/errata/accessdata.399) but appear to have reverted in this edition. Line 10 of Example 15-7 now reads: strSQL = "UPDATE BOOKS SET Price = Price*1.1 WHERE Price > 20 It should read: strSQL = "UPDATE BOOKS SET Price = Price*1.1 The last line on the page now reads: if qdf.RecordsAffected > 15 Then It should read: if qdf.RecordsAffected <= 15 Then [274] The intro for Example 16-4 indicates that the code find[s] the first title that begins with the word On. This is true, but if such a book does not exist, the >= operator will cause the code to find any book that starts with an expression that would appear later in an alphabetically ordered list. Changing the operator to = causes the code to function in a manner that is closer to what is expected. [277] The code on the last line of the page causes an error. The currency keyword should be enclosed in quotation marks. [333-334] In the "ExcelExample" subroutine and "TextExample" subroutine on page 335-337, the examples mislead the user into thinking that it is possible to open a "Client-Side Dynamic Recordset" for Excel and text data sources. The truth is that for any data source the only kind of client-side recordset one can open is one with a cursor type of static (not dynamic). This is even inconsistent with page 300 (2nd paragraph) which states truthfully that "Even if we specify a different type of cursor for a client-side cursor, ADO will open a static cursor instead." {334} The sixth line of code reads: For r = 0 To Ubound(vrecs, 1) For f = 0 To Ubound(vrecs, 2) It should read: For r = 0 To Ubound(vrecs, 2) For f = 0 To Ubound(vrecs, 1) This was discovered when dimensions of example Excel table were changed by adding an additional row. {334} The fifth line of code now reads: vrecs = rs.GetRows(6) Although this will work, it actually can be restated as: vrecs = rs.GetRows(5) for the example table, as it ignores the first row of field names. {369} In the 5th line of the 3rd paragraph under "Machine data sources," "HKEY_LOCAL_USER" should read "HKEY_CURRENT_USER," as it does in the bulleted list above this paragraph. [385] First bullet; The example files are missing on the ftp server!