------------------------------------------------------------------------------ ------------------------------------------------------------------------------ NNNNNNNNNNNN NNNNNNNNNNNN NNNNNNN NNNNNN NNNNNNN NNNNNN NNNNNNNNNNNNNN NNNNNNNNNNNNNN NNNNNNNN NNNNNN NNNNNNNN NNNNNN NNNNNN NNNNN NNNNNNNNNN NNNNNNNNN NNNNNN NNNNNNNNN NNNNNN NNNNNN NNNNN NNNNNNNN NNNNNNNNN NNNNNNN NNNNNNNNNN NNNNNN NNNNNNNNNNNN NNNNNN NNNNNNNNNNNNNNNNN NNNNNNNNNNNNNNNNN NNNNNN NNNNNN NNNNNNN NNNNNN NNNNNNNNNN NNNNNN NNNNNNNNNN NNNNNN NNNNNN NNNNNNNN NNNNNN NNNNNNNN NNNNNN NNNNNNNN NNNNNNNNNNNNNN NNNNNNNNNNNNN NNNNNN NNNNNNN NNNNNN NNNNNNN NNNNNNNNNNNNN NNNNNNNNNNN NNNNNN NNNNNN NNNNNN NNNNNN ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Boston Computer News Network May/June 1994 A Service of the Boston Computer Society, USA Vol.1, No.4 Sponsored by the Foxpro SIG Foxpro Version ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ 0. Introduction. ----------------------------------------------------------------------- ReplyTo: David Rose [73164,2263] Whew! Sorry for the delay, but it seems like it has been a busy month. Of course that was last month, or is it next month? Anyway, your wait is over, the next issue is finally on your computer, I hope it is worth the wait. Thank you for all of your responses to my question for what you would like to see in future issues. The one thing that was overwhelming: snippets! I guess those of you who might be considering sending in a little something know what that means. There was also a very favorable response on Robert de Kock's story about Foxpro saving the day in rural Bangladesh. So here's an opportunity for those of you who would like to share stories from far away places and strange circumstances. Whether it is a snippet or a great story, we hope that you are growing a little more connected (as we are ourselves) with the great wide Foxpro world out there. 1. Free BCS Fox User Group Event at Database & Client/Server World Boston. ----------------------------------------------------------------------- ReplyTo: Arnold Bilansky [71533,1031] (617)522-3700 x374 Meeting: June 29, 1994 Place: Hynes Convention Center, 900 Boylston Street Boston, MA USA. 9:30am Hank Fay: Building Event-Driven FoxPro Applications on the Fly 11:30am Dick Bard: Multi-Window Programming - The Real Power of FoxPro 1:00pm Whil Hentzen: FoxPro Rapid Application Development 3:00pm Panel: Programming Today in Anticipation of FoxPro 3.0 5:30pm David Kalman: FoxPro Data Warehousing. For More Information on The BCS Meetings: Call BCS at 617 290-5700 BCS meetings are free and require no reservations. Door-prizes! 2. Other BCS FoxPro User Group Meetings. ----------------------------------------------------------------------- ReplyTo: Arnold Bilansky [71533,1031] (617) 522-3700 x374 Place: Microsoft Office, 9 Hillside Avenue, Waltham, MA USA. Meeting: June 16, 1994, 6:30 p.m. Replay of DevCast IV Meeting: July 13, 1994, 7:00 p.m. John Miller: Data Modeling, Data Dictionaries & Metadata Meeting: August 10, 1994, 7:00 p.m. Menachem Bazian: FP as a Client/Server Front and Back End Training: August 11, 1994, 9:30 a.m. - 4:30pm (Fee Charged) Menachem Bazian: Advanced FoxPro for Windows Training 3. Foxpro in Oz. ----------------------------------------------------------------------- ReplyTo: Mike Rychter [100033,1361] MailTo: Mike Rychter Ashpoint Pty Limited 9 Arthur Street Dover Heights NWS 2030 AUSTRALIA PhoneTo: 61.2.371.7399 FaxTo: 61.2.371.0180 Portable:61.18.229.934 Please advise BCNN readers and others that I will convene the Third Australasian FoxPro Technical Workshop. This is a three day seminar held in Melbourne (Australia) July 4,5 & 6; Sydney (Australia) July 8,11 & 12; and Auckland (New Zealand) July 14,15. Seminars will be headed by noted FoxPro personality Lisa Slater. Best regards from Down Under... 4. How Does PKZIP Corrupt a CDX File? ----------------------------------------------------------------------- ReplyTo: Richard Skinner 72143,3277 You asked in the last BCNN letter, "How does PKZIP corrupt an index file?" Well, I dunno. But, in FP 2.0 days, I was developing a project that involved the printer codes database that ships with FoxPro. Corruption _always_, without fail, happened when I PKZIPped the DBF file. There appears to be a subtle bug in PKZIP that only triggers when a rarely occurring sequence of bytes gets passed through. Since I switched over to LHArc, the problem has never recurred. Of course, that means that anything I upload has to be a self- extracting file, since PKZIP has become the de-facto standard on CIS. Someone with more time and knowledge of compression may track this down someday. 5. Advice for an Apprentice. ----------------------------------------------------------------------- ReplyTo: Whil Hentzen, 70651,2270 Milwaukee WI USA Hentzenwerke 414.332.9876 Download: Multiple Let's suppose your son or daughter formally asked for a meeting with you one night, and after you ascertained that the family car was still in one piece, you agreed. They close the door to the study, and gravely proclaim, "I want to become a master FoxPro programmer like you, Dad (or Mom, as the case may be)." In the olden days (about six months ago, I believe), young people would apprentice with a craftsperson, learning a trade and passing down tools to the initiate. What tools would you pass along to help them become part of the guild? Listed in no particular order, here's a partial list of tools and utilities I would insist that my apprentice master. I'd be interested in hearing what belongs in your toolkit, and why. Commercial products listed below can all be found via advertisements in the trade magazines. The shareware products are all on the FoxForum. o Paul Heiser's dSalvage, of course, because the day it arrives, you'll never need to repair another database or memo file (right?). o MicroMega's FoxFire, because I don't like creating reports, and, funny enough, my users do. o Joe Gotthelf's JKEY, for incremental search capability in my browses. o Pat Adam's PROERROR error trapping utility so that I don't have to write my own inferior version. o A "stripped down" version of Fox that fits on a single disk and perform most Command Window activities. (This can be created using the distribution kit.) o John Whitney's Visual Compare, to compare two text files. Wonderfully useful. o PKZIP, of course. o Filefind and text search utilities (I use old, compact versions of Norton's). And while we're talking about Norton, some version of an "Unerase" utility for that one customer that is still running DOS 3.3. o Perhaps a text editor, and clean boot disk of DOS. o Last, just for fun, CUSTCURS (over on WINFUN Forum) provides about 30 different cursors that replace the blah arrow that comes with Windows. 6. Useful Cursor"ies". ----------------------------------------------------------------------- ReplyTo: Gerald Morgan [100013,756] We make heavy use of cursors in our systems to provide undo mechanisms, 2-way picker dialogs and all sorts of other things. The following three UDFS often come in handy. Hope these are of some use. Your suggestions for improvements will be gratefully received. The most useful has been the MkCursRW function which can be used after SELECT, e.g. SELECT *,.T. FROM customer WHERE NAME="SMITH" INTO CURSOR smiths =mkcursrw("smiths") *---------------- FUNCTION mkcursrw *---------------- * Makes a Read Only cursor Read/Write (e.g. from a SELECT). * Requires that the cursor is a 'real file', not just a filtered-view, * which can be ensured by adding a dummy field to the SELECT (e.g. .T.) * m.cn - Cursor name being passed * m.cf - Real cursor file name PARAMETER m.cn PRIVATE m.retstat && True if completed ok m.cf=DBF(m.cn) && Cursor's real filename IF ".TMP" $ m.cf && Its a real file! USE (m.cf) AGAIN IN 0 ALIAS tctc && Open again with dummy alias USE IN (m.cn) && Close original cursor USE (m.cf) AGAIN IN 0 ALIAS (m.cn) && Use dummy with original alias USE IN tctc && Close dummy cursor SELECT (m.cn) && Original cursor (now read/write) m.retstat=.T. && Successful ELSE m.retstat=.F. && Unsuccessful ENDIF RETURN m.retstat *---------------- FUNCTION curspack *---------------- * 'Packs' a cursor, there are two slightly different methods here. * The first works on a 'real' file and is usually fastest. * The other works on a 'filtered view' and could be slower. PARAMETER m.cn PRIVATE m.cf,m.arec m.cf=DBF(m.cn) && Cursor's real filename IF ".TMP" $ m.cf && Original is a real file! * Put non-deleted's into dummy cursor SELECT * FROM (m.cn) WHERE NOT DELETED() INTO CURSOR tctc m.cf=DBF("tctc") && Get real name of dummy cursor use in (m.cn) && Close Original use (m.cf) AGAIN IN 0 ALIAS (M.CN) && Use dummy alias 'original' USE IN tctc && Close Dummy ELSE && Filtered view-different tactics! =dbf2curs(m.cn,"tctc") && Dummy cursor with original stru. SELECT (m.cn) SCAN FOR NOT DELETED() && Non-deleted's into dummy cursor SCATTER MEMO TO m.arec INSERT INTO tctc FROM ARRAY arec ENDSCAN USE IN (m.cn) =dbf2curs("tctc",m.cn) SELECT tctc SCAN && Write stuff back to original SCATTER MEMO TO m.arec INSERT INTO (m.cn) FROM ARRAY arec ENDSCAN USE IN tctc ENDIF RETURN *---------------- FUNCTION dbf2curs *---------------- * Creates empty read/write cursor with same structure as passed table. PARAMETERS m.dn, m.cn PRIVATE dstru, m.oldsel m.oldsel=SELECT() SELECT (m.dn) =AFIELDS(dstru) && Put structure into array CREATE CURSOR (m.cn) FROM ARRAY dstru && Build empty cursor from array SELECT (m.oldsel) RETURN 7. Using a Finite State Machine to Navigate a Complex Screen Set. ----------------------------------------------------------------------- ReplyTo: Bill Passman [bpassman@internet.kronos.com] The following provides data-driven control for navigating large sets of screens. The technique is useful in applications containing multi-page dialogs: surveys, tests and wizards to name a few examples. * * Snippet to Navigate a multi-screen application. * * This snippet is currently procedure of a menu pad selection in the * menu builder. It calls a screen.spr program with a return parameter. * The Screen State machine database (Scrstate.dbf) contains 5 fields: * 1. scr_numb: The current screen number. * 2. scr_name: The name of the current screen. * 3. scr_if: The possible button-pushed return value from the .spr * 4. scr_goto: Screen number to GO TO if the button is pressed. * 5. scr_comment: A comment field. * * One rule. Every screen referenced must have one record with a if- * return value of "1" defined in the database. The record in the * database with the "1" if-return value must contain the scr_name of * the screen. * * scr_numb scr_name scr_if scr_goto scr_comment *--------- -------- ------ -------- --------------- * 0001 my_1.spr 1 0001 "My 1st screen" * 0001 2 0002 " if 2 pressed, goto 0002" * 0001 3 0003 " if 3 pressed goto 0003" * 0001 4 0002 " if 4 pressed goto 0002" * 0002 my_2.spr 1 0001 "My 2nd screen" * 0002 2 0001 " if 2 pressed go back to 1 also" * 0002 3 0003 " if 3 pressed, go to 0003" * 0003 my_2.spr 1 0001 "My 2nd screen - but different" * 0003 2 0002 " if 2 pressed, goes to 0003" *etc... *--------------------------------------------------------------------- * The database is ordered by the scr_number and by: * * scr_if * STR(scr_numb,4,0)+STR(scr_if,3,0), * * so you can seek to "If I am in screen my_2, and I push button #3" *--------------------------------------------------------------------- * Default to 1st Screen and set the current state to: * * pn_ret_but = 1 * pc_cur_state = " 0" * Run Screen State Machine, Zero gets me back to the menu * DO WHILE pn_ret_but <> 0 SELECT Scrstate * Process the return button pressed pc_ret_but = str( pn_ret_but, 3, 0 ) * Find the state record to the record that has this screen * and this button pushed. SEEK( pc_cur_state + pc_ret_but ) IF NOT FOUND() WAIT WINDOW " Illegal Screen "+pc_cur_state +" "+ pc_ret_but EXIT ENDIF * "Where do I go to next?" pc_next_state = STR( Scrstate.scr_goto, 4, 0 ) * Find the record with the name of the next screen SEEK( pc_next_state + " 1" ) IF NOT FOUND() WAIT WINDOW " Illegal Screen "+pc_curstate +" "+ " 1" EXIT ENDIF * "What is the name of the next screen?" pc_cur_state = pc_next_state pc_scr_name = ALLTRIM( Scrstate.scr_name ) + ".spr" * Go to the next screen DO (pc_scr_name) WITH pn_ret_but ENDDO && of While in main screen RETURN *------------------------------------------------------------------ * Each Screen Program has a SETUP snippet which includes a PARAMETER * with the message of which button was pushed. *--------------------- * Sample SETUP snippet * *--------------------- #SECTION 1 PARAMETER pn_return_button *------------------------- * and each of the navigational buttons, like "NEXT" is set up as a * terminating button, and has a VALID snippet which sets the * pn_return button value... *------------------------------ * Sample Button Valid snippet * *------------------------------ pn_return_button = 3 8. Time and Billing Using FoxPro's Calendar/Diary and LogTime(). -------------------------------------------------------------------------- Reply To: Ted Roche, MCP <76400,2503> MailTo: Computer Resource, Contoocook, NH Most of us need to keep track of our time for one reason or another. Bosses often ask for status reports; clients like to be kept up on what's going on; we independent consultants like to be able to bill clients only for the time spent on their projects. Although I've tried several time-and-billing systems, I haven't found one yet that meets all of my needs. Until I find a suitable system, I've been tracking my hours using FoxPro's Calendar/Diary function (available from the DOS System or Windows Help menu pads). Rather than calling up the calendar, figuring out what time it is, making sure that I've got the right date, and then making my entry, I've created a simple function, LogTime(), that posts a message to the diary for the current date and time. Later, I use the calendar tool to review my entries, or create a simple SQL SELECT to produce a status report on my activities. * LogTime.PRG - time entry into resource diary * Copyright (c) Ted Roche, 12/20/93 parameters tcLogMessage private all like l* if empty(set('reso',1)) && make sure resource file available. wait window Program() + ": No resource in use!" return .f. else lcResSet = SET('RESOURCE') &&-Turn it off temporarily set resource off endif lnSelect = SELECT() &&-Save the original work area select 0 use set('reso',1) again alias Diary &&-Use resource file as .DBF locate for type = "DATA" and ; &&-See if entry for today exists. ID = "DIARYDATA" and ; Name = DTOS(DATE()) if not found() &&-If not, create one. insert into Diary ; (Type,; ID,; Name,; ReadOnly,; CkVal,; Data,; Updated ; )VALUES ; ("DATA",; "DIARYDATA",; DTOS(DATE()),; .F.,; 0,; TIME()+" "+tcLogMessage,; DATE() ; ) else replace Data with Data + chr(13) + TIME() + " " + tcLogMessage endif replace CkVal with val(SYS(2007,Data)) &&-Update checksum. use in Diary &&-Close the file. select (lnSelect) &&-Re-select orig work area. set resource &lcResSet &&-Restore resource file setting. return 9. Polar Bear Heaven BBS. ----------------------------------------------------------------------- ReplyTo: Fitzgerald, Thomas INTERNET:Fitzgerald@volpe3.dot.gov I thought you might like to know about a FoxPro file server located in Canada and I hope you enjoy using its file and mailing list server. You can get a complete help file by addressing a message to: foxpro-help@polarbear.rankin-inlet.nt.ca The text of the message is insignificant and will be discarded. You may add yourself to mailing lists, query Polarbear about its files, and request downloads of selected files. Responses from the file & mail server are queued up immediately upon receipt. However, because we're paying long distance charges to access our InterNet feed, files will not be sent until the wee hours of the morning, when long distance rates only constitute theft, as opposed to rape! ;-0) Therefore, please be patient when requesting files from this service. There might be up to a twenty-four hour delay in sending you your files (if you happened to call just after the last batch was sent). 10. FoxPro Secret Screen. ----------------------------------------------------------------------- Reply To: Dale Gilstrap Leopold [76244,3534] Treasurer, Mid-Atlantic Association of Foxpro User Groups. What prompted me to write was your unsuccessful search for a FoxPro secret screen, or (more appropriately for the weekend I'm writing this) "Easter egg." Well such a thing *does* exist, as I just confirmed by calling in to a LAN I setup a few years ago. On it was a version of FoxPro 1.01 (that should give you some idea of when I set it up...). If you can dig up, dust off and install those old 1.01 disks, here's what you do: 1) From the System menu pad, choose the "About FoxPro" prompt. This displays the "About FoxPro" window (a single window in those days). 2) Single click one character down and to the right from the upper- left-hand corner of the box. The box now reads "FoxPro was written by:" and a list of FoxPro's authors will scroll across the middle of the window in a continuous loop. 3) Single clicking one character down and to the left of the upper-right-hand corner of the window will produce a scrolling list of FoxPro's documenters. As far as I know, there are no Easter eggs in any subsequent versions of FoxPro, but you never know...you may already have received some messages to the contrary. 11. Ken Levy DevCast Comments. ----------------------------------------------------------------------- ReplyTo: Ted Roche [76400,2503] The recent Microsoft DevCast created a storm of messages, both positive and negative, on the Compuserve FoxPro forums. Many saw DevCast as nothing more than an 'infomercial' for the rollout of Access 2.0. Others saw very positive signs of increasing Microsoft support and marketing of FoxPro, as well as the announcement of the newest upgrade, version 2.6. In a short 'preview of things to come' at the conclusion of the DevCast, Chris Capposella showed us some features 'in the next major release' of FoxPro. Ken Levy, author of GenScrnX and a software engineer at FLASH Creative management, was quite impressed: "You saw GETS/READ replaced with objects tied to the Windows event model, multiple application instances running completely modeless and independent with full encapsulated methods and properties, user defined class definitions, access to Windows events (DblClick, etc.), runtime control of object instances (X.TITLE='new title'), multiple object instances from a class definition, and an independent toolbar. That 5 minute demo showed technology that blows away the copy-and-paste methodology found in Access 2.0." 12. BCNN Statement of Ownership, Copyright, and Responsibility. ----------------------------------------------------------------------- The BCNN Newsletter is sponsored by the Foxpro User Group of the Boston Computer Society. BCNN is dedicated to keeping professional database developers (both consultants and corporate employees) informed about educational events, meetings, job openings, world events, notable articles, technical tips, new and 'must have' products, etc. As an electronic network BCNN is also a hub where developers can address world class issues with fellow developers around the world. Recipients agree to respond via Email to periodic polls of their directions, opinions, and needs. For those who do not have User Groups in their areas, BCNN is a vehicle for individuals to volunteer and contribute to something larger than themselves. Over 7,500 persons world-wide participate with CA-Clipper, Microsoft Access and FoxPro. The newsletter is distributed monthly by electronic mail via CompuServe, Internet, FidoNet, and other electronic gateways. It is free of charge to individual developers. Modest fees are charged to corporations for job placement and third-party announcements. Opinions expressed are solely expressed by the Foxpro User Group or the author found in the ReplyTo of the article. No warranties are made by the authors, editors, the Foxpro User Group or BCNN regarding the accuracy or applicability of the information provided in this newsletter, nor are the above named parties responsible for direct or incidental damages due to your use of this information. All materials are copyrighted by the BCS, unless otherwise indicated, and free for any user group to redistribute on their own BBS on the condition that a by-line referencing the BCS is included. Associate Editors: ----------------------------------------------------------------------- David Rose, Days (508)538-8064, Eves (617)935-6843. CIS:73164,2263 Internet:73164.2263@CompuServe.Com Arnold Bilansky Days (617)522-3700 x374 CIS:71533,1031 Internet:71533.1031@CompuServe.Com Ted Roche, CIS 76400,2503 Computer Resource, Contoocook, NH (603) 746-4017 Submissions. ----------------------------------------------------------------------- Send submissions to 73164,2263 with the subject 'BCNN Foxpro Submission'. Format your submissions similar to this letter. Distribution and Subscription Services. ----------------------------------------------------------------------- Les Squires, Director, Xbase Language Group. bcnn@World.Std.Com or 73020,3435 Add Subscribers: BCNN/FoxYes to bcnn@World.Std.Com. Delete Subscribers: BCNN/FoxNo to bcnn@World.Std.Com. Back Issues: (to be announced...) Boston Computer Society, Inc. 101 First Avenue Suite 2 Waltham, MA 02154 617-290-5700 General Number 617-290-5700 Ext. 432 for up-to-date meeting information. BCNN Email Services donated by Word Jenny Inc. LSquires@World.Std.Com (c) 1994 Boston Computer Society, Inc.