Craig Hoyt asked: >I was surprised to see the amount of posts generated by my 'days between >dates' question and reply. I agree with those who favor the formula method >over the counting method. There are too many exception handling in the >counting method to make it practical. Those who need to understand the >formula are making their life more complicated. I tested it and it worked! >I don't fully understand it but it works. That's good enough for me. For the list skeptics (I admit this may add to the skepticism) I have located a discussion of the algorithm used in the day difference function I posted here. I translated several Julian Date functions from Pascal, C and several variations of BASIC, but this one-- a modified Julian Date function which sees use by astronomers-- seemed the most robust. Here goes: http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q109/4/51.asp&NoWebContent=1 Note the innuendo in difference between VB's implementation of INT compared with FB^3's FIX. I hope my translation proves accurate. It's possible that the function input variables should be redimensioned to: local fn AstroDay#( inyear as long, inmonth as int, inday as double ) For those who prefer counting vs algorithm, please don't slay me, I'm just the messenger! Michael Evans offered a fine solution. I do feel that Craig's implementation, while just fine for his purposes, does severely limit the range of the AstroDay algorithm. Alain can read my mind, because both samples are going into the Rosetta Stone Library giving us an equivalent to VB's datefiff function. At any rate, after a quiet few months, I'm very happy to see some excellent code being posted here. >I have another question... Below is a function taken from the search edit >field example on the r7 CD. I am having a hard time wrapping my mind around >parts of this function. I created a similar routine to search an edit field >using the munger function. I wanted to have my search case insensitive so I >too transformed both the TEHandle and the search string. My problem is that >converting the TEHandle to upper case and then applying the munger function >changes the entire contents of the edit field to upper case. In the example >below the TEHandle is transformed to UC as mine is but then transferred to >the pointer upTxtHP. The munger function is applied to the TEHandle and not >the upTxtHP. I'm confused. Can anyone adapt this function to; A) not use a >passed pointer (or handle) and B) not change the case of the contents of >the edit field the same way as the example does. I don't have much time, so I just cut and pasted the following demo which allows a user to open a text file into an edit field and do a search and replace on the handle. Perhaps you can get a few ideas from it. (Note: Fn HandleSearchAndReplace) I wrote this in a couple hours last year as an experimental GUI for a project I was working on. It seems fairly robust, but watch for bugs. Best, Ken please watch for lost constant underscores on the Associate server #if cpu68K compile shutdown "Requires PPC or Carbon Compile" #endif begin globals // Create containers to hold undo data dim as container gOriginalC, gRevisedC dim as boolean gUndoFlag end globals // Initialize containers to hold text gOriginalC = "" gRevisedC = "" // Enumerate edit field and control constants begin enum 1 _oldStrLabelEF _newStrLabelEF _oldStrEF _newStrEF _mainEF _errorEF _openBtn _replaceBtn _saveBtn end enum // Turn on new navigation services gFBUseNavServices = _zTrue // Build menus local fn BuildMenus apple menu "(Demo..." menu 1, 0, _enable, "File" menu 1, 1, _enable, "Open/O" menu 1, 2, _enable, "Replace/R" menu 1, 3, _disable, "-" menu 1, 4, _enable, "Save/S" menu 1, 5, _disable, "-" menu 1, 6, _enable, "Close" // Enable Select All in Edit menu gFBEditSelectAll = _zTrue // FB^3's own Edit menu set as 2 edit menu 2 // Enable "Undo" in Edit menu menu 2, 1, _enable end fn // Create main window local fn BuildWindow dim as rect r setrect( r, 0, 0, 600, 400 ) appearance Window -1, "File String Parser", @r,¬ _kDocumentWindowClass, _kWindowStandardFloatingAttributes def SetWindowBackground( _kThemeActiveDialogBackgroundBrush,_zTrue ) text _sysFont, 11 edit = 3 setrect( r, 10, 20, 155, 35 ) edit field _oldStrLabelEF, "Find this string:", @r, _statNoFramed,_rightJust offsetrect( r, 0, 34 ) edit field _newStrLabelEF, "Replace with this string:", @r,_statNoFramed,_rightJust text _courier, 11 setrect( r, 161, 20, 450, 35 ) edit field _oldStrEF, "", @r,_framedNoCR,_leftJust offsetrect( r, 0, 34 ) edit field _newStrEF, "", @r,_framedNoCR,_leftJust text _courier, 11 edit = 4 setrect( r, 20, 90, 434, 340 ) edit field _mainEF,"",@r,_framed,_leftJust setrect( r, 434, 86, 450, 343 ) scroll button -_mainEF,0,0,0,0, @r, _scrollOther setrect( r, 470, 130, 590, 220 ) edit field _errorEF,"",@r,_statNoframed,_leftJust setrect( r, 470, 20, 590, 40) button _openBtn, 1, "Open file...", @r,_push offsetrect( r, 0, 35 ) button _replaceBtn, 1, "Replace string", @r,_push offsetrect( r, 0, 35 ) button _saveBtn, 1, "Save results", @r,_push edit field _mainEF window 1 end fn // Read contents of selected file into a handle local fn LoadFileIntoHandle( fileStr as str255, vol as int ) dim as handle @ fileH dim as long fileLen dim as OSErr err open "I", #1, fileStr, ,vol fileLen = lof(1, 1) fileH = fn newhandle _clear( fileLen ) err = syserror long if fileH != 0 and err == 0 read file #1, [fileH], fileLen end if close #1 end fn = fileH // Place text from handle created by fn LoadFileIntoHandle // into specified edit field local fn TextHandleIntoEF( efID as int, fileH as handle ) dim as long size dim teH as ..TERec edit$(efID) = "" size = fn gethandlesize( fileH ) teH = teHandle( efID ) HLock( fileH ) // Purposely limit edit field size to 32K to avoid inherent TE problems if ( size > 32000 ) then size = 32000 TEInsert( [fileH], size, teH ) TESetSelect( 0, 0, teH ) HunLock( fileH ) end fn // Open file, load text into edit field local fn LoadFile( efID as int ) dim as handle @ fileH dim as integer @ vRefNum dim as str255 fileNameStr fileNameStr = FILES$( _fOpen, "TEXT", ,vRefNum ) long if fileNameStr = "" exit fn xelse fileH = FN LoadFileIntoHandle( fileNameStr, vRefNum ) end if // If file handle is valid, load its contents into edit field long if fileH != 0 fn TextHandleIntoEF( efID, fileH ) def DisposeH( fileH ) xelse beep end if setselect _maxInt, _maxInt setselect 0, 0 // Switch focus to main field edit field efID end fn clear local mode local fn HandleSearchAndReplace( searchH as handle,¬ findStr as str255,¬ replaceStr as str255 ) dim as long startSearch, oldSearch, count dim as OSStatus status startSearch = 0 ' start search at beginning oldSearch = 0 ' synch flag count = 0 ' clear count do status = fn munger( searchH,¬ startSearch,¬ @findStr + 1,¬ findStr[0],¬ @replaceStr + 1,¬ replaceStr[0] ) long if startSearch > oldSearch count++ oldSearch = startSearch end if until startSearch <= 0 end fn = count // Determine number of lines in target edit field local fn CountLinesInEF( efID as int ) dim as int lines dim as handle teH teH = TEHANDLE( efID ) lines = teH..teNLines% end fn = lines // Check to see if all necessary information is present to perform replace local fn CheckForCompleteInfo dim as boolean noErrors noErrors = _false edit$(_errorEF ) = "" long if edit$(_mainEF) = "" edit$(_errorEF) = "Please open a file to parse." edit field _mainEF exit fn end if long if edit$(_oldStrEF) = "" edit$(_errorEF) = "Please enter a string to find¬ as a target in the ""Find this string"" field." edit field _oldStrEF exit fn end if noErrors = _true end fn = noErrors // Initialize the three functions above to replace string local fn DoReplace dim as str255 testStr, oldSubStr, newSubStr dim as handle @ teH dim as long i // Make sure all information for replace is present if fn CheckForCompleteInfo = _false then exit fn // Initialize replace strings testStr = "" : oldSubStr = "" : newSubStr = "" oldSubStr = edit$(_oldStrEF) newSubStr = edit$(_newStrEF) // Load original field contents into its container for undo gOriginalC = edit$(_mainEF) get field teH, _mainEF for i = 1 to fn CountLinesInEF( _mainEF ) fn HandleSearchAndReplace( teH, oldSubStr, newSubStr ) next i gRevisedC = &teH kill field teH edit$( _mainEF ) = "" // Load finished container into edit field edit$( _mainEF ) = #gRevisedC gUndoFlag = _true setselect 0, 0 end fn // Very rudimentary Undo function local FN Undo long if gUndoFlag = _true edit$(_mainEF) = #gOriginalC gUndoFlag = _false xelse edit$(_mainEF) = #gRevisedC gUndoFlag = _true end if end fn // Function to save completed results clear local local fn SaveFile dim as str255 fStr dim as integer @ defaultVol dim as handle @ textH get field textH, _mainEF def open "TEXTttxt" menu fStr = files$( _fSave, "Save As...", "untitled", defaultVol ) long if fStr[0] open "O", #1, fStr, 1, defaultVol write file# 1, [textH], fn gethandlesize(textH) close #1 end if menu 1, 0, 1 end fn // Dialog handlers local fn DoDialog dim as long evnt, id evnt = dialog(0) id = dialog(evnt) select case( evnt ) case _wndClose select( id ) case 1 : gFBQuit = _zTrue end select case _btnClick select( id ) case _openBtn : fn LoadFile( _mainEF ) case _replaceBtn : fn DoReplace case _saveBtn : fn SaveFile end select end select end fn // Menu handlers clear local local fn DoMenus dim as long menuID, itemID menuID = menu(_menuID) itemID = menu(_itemID) select case( menuID ) case _applemenu select( itemID ) case 1 end select case 1 select( itemID ) case 1 : fn LoadFile( _mainEF ) case 2 : fn DoReplace case 4 : fn SaveFile case 6 : gFBQuit = _zTrue end select case 2 select( itemID ) case 1 : FN Undo end select end select menu end fn // Main event loop on dialog fn DoDialog on menu fn DoMenus fn BuildMenus fn BuildWindow do handleevents until gFBQuit end