Useful Utilities (at least, I think they are)
Like all developers, whatever their preferred language or environment, I have my own personal set of tools and utilities that I use to make life a little easier for myself. Although not particularly generic, or even clever, I find that these little things really help so I offer them here, as is, for your enjoyment, adoption and modification.
The first is a little bit of code that I wrote because I was fed up with mis-spelling column names when writing SQL Statements – especially when working with cursors that included calculated or aliased columns. This little routine, named GetFList() gets the list of field names for a specified alias (or the currently selected alias if nothing is specified) and places them on to the Windows Clipboard. Once there, the list can simply be pasted into whatever window I happen to be working in at the time. Simple, but it has saved me many hours over the years.
******************************************************************** *** Name.....: GetFList.prg *** Author...: Andy Kramek *** Date.....: 7/7/2004 *** Notice...: Copyright <img src='/emoticons/m5.gif' alt='applause' border='0' /> 2004 Tightline Computers, Inc *** Function.: Copy the list of fields in the current, or specified, table to the clipboard ******************************************************************** LPARAMETERS tcTableLOCAL lcTable, lcALias, lcList, lnCnt, lcField, lnSelect *** Did we get a table name m.lnSelect = SELECT() IF VARTYPE(tcTable) = "C" AND NOT EMPTY( tcTable ) m.lcALias = JUSTSTEM( tcTable ) *** If it's not used, open it IF NOT USED( m.lcALias ) IF FILE( FORCEEXT( tcTable, 'dbf' )) USE (tcTable) AGAIN IN 0 ALIAS (m.lcALias) ELSE _CLIPTEXT = '' RETURN ENDIF ENDIF *** And Select the Alias SELECT (m.lcALias) ELSE *** Use whatever is currently selected m.lcALias = ALIAS()ENDIF *** Get the list of field namesIF NOT EMPTY( lcAlias ) m.lcList = '' FOR m.lnCnt = 1 TO FCOUNT() m.lcField = LOWER( ALLTRIM( FIELD( m.lnCnt ))) m.lcList = m.lcList + IIF( EMPTY( m.lcList ), "", ", " ) + m.lcField NEXT *** Add the alias name _CLIPTEXT = m.lcList + CHR(13) + CHR(10) + "*** " + m.lcALias ENDIF *** Restore work area SELECT (m.lnSelect) RETURN
The second little utility is one that I call from a hot-key in my development environment to open an instance of Windows Explorer to the currently selected drive and directory. I confess that I find the inconsistent behavior of the windows that access the file system irritating. Some applications open a window to the last directory that was accessed, others simply use a standard (“My files”) or static directory (C:\ or “My Computer”) and others again do something which is apparently randomized. Generally, when working in VFP, if I need to access Windows Explorer I want to find a file that is either in the current working directory (typically the root directory of a project hierarchy) or in some specific related directory which I know the name of anyway (e.g. “D:\VFP90\COMMON”).
The RunExplorer procedure uses the ShellExecute() API function to open Windows Explorer to the required location and I call it using a simple ON KEY LABEL command so that it is available on my “F5” function key. It will accept a specific drive/directory as a parameter but the default behavior is to use the current VFP working directory. Here is the code for it:
******************************************************************** *** Name.....: RUNEXPLORER.PRG *** Author...: Andy Kramek *** Date.....: 25/09/2004 *** Notice...: Copyright <img src='/emoticons/m5.gif' alt='applause' border='0' /> 2004 Tightline Computers, Inc *** Function.: Runs Windows Explorer with the specified directory selected *** .........: Defaults to VFP current working directory if none passed ***************************************************************** LPARAMETERS tcDirLOCAL ARRAY laDex[1] LOCAL lcDir, lnDex, llIsLoaded, lcParms, lnRes *** Default to current directory if nothing is passed in IF VARTYPE( tcDir ) # "C" OR EMPTY( tcDir ) lcDir = FULLPATH( CURDIR()) ELSE *** Default if specified directory does not exist IF NOT DIRECTORY( tcDir ) lcDir = FULLPATH(CURDIR()) ELSE lcDir = tcDir ENDIF ENDIF *** Make sure we have Shellexecute available lnDex = ADLLS( laDex ) IF lnDex > 0 llIsLoaded = (ASCAN( laDex, 'shellexecute', 2, -1, 2, 15 ) > 0) ELSE llIsLoaded = .F. ENDIF IF NOT llIsLoaded *** Load the function DECLARE INTEGER ShellExecute IN shell32; INTEGER hwnd,; STRING lpOperation,; STRING lpFile,; STRING lpParameters,; STRING lpDirectory,; INTEGER nShowCmd ENDIF *** Open Explorer to the correct location lcParms = "/n,,/e," + lcDirlnRes = ShellExecute( 0, "open", 'explorer.exe', lcParms, "", 1 ) RETURN
Incidentally the same parameters (“/n,,/e,” + <path>) can be used in desktop shortcuts to open windows explorer to a more useful location than “my computer”. I usually set my shortcuts to use “D:\” since that is the root of my application drive and therefore the most likely place that I will want to start using Windows Explorer from – but you can choose anything.
The final little utility that I want to share is one that I use less often directly, but which is useful anyway. One of the things that I always do is to set an explicit search path in VFP (see my blog article on paths for details) but of course in order to specify a path you need to list all of the directories. It has always struck me as odd that Windows Explorer has no mechanism that will allow you to copy a list of names – so I wrote GetSubDirs() to create a comma-separated list of the first level sub-directories that exist under the specified root and push it on to the clipboard. Why just first level? Only because my standard project directory structure does not use anything deeper and I have no need to handle any additional complexity. The code could easily be made recursive to handle additional levels of sub-directories but I leave that as an exercise for the reader…J
******************************************************************** *** Name.....: GETSUBDIRS.PRG *** Author...: Andy Kramek *** Date.....: 23/09/2004 *** Notice...: Copyright <img src='/emoticons/m5.gif' alt='applause' border='0' /> 2004 Tightline Computers, Inc *** Function.: Build a ";" separated list of SubDirectories and copy it to the clipboard ******************************************************************** LPARAMETERS tcRoot LOCAL ARRAY laDirs[1] LOCAL lcRoot, lcOrigDir, lnDirs, lnCnt, lcDir, lcList *** We definitely need a root directory IF EMPTY( m.tcRoot ) OR NOT DIRECTORY( m.tcRoot ) m.lcRoot = GETDIR( CURDIR(), "Must specify a Root Directory", "Get SubDirs" ) IF EMPTY(m.lcRoot) m.lcRoot = FULLPATH( CURDIR()) ENDIF ELSE m.lcRoot = FULLPATH( m.tcRoot ) ENDIF *** Save the original location m.lcOrigDir = FULLPATH( CURDIR() ) *** Switch to the specified directory SET DEFAULT TO (m.lcRoot) *** Now get a list of 1st level Sub_directories m.lnDirs = ADIR( laDirs, '*.', 'D' ) IF m.lnDirs = 0 _CLIPTEXT = "" SET DEFAULT TO (m.lcOrigDir) RETURN "" ENDIF *** We have at least one sub-directory m.lcList = '' FOR m.lnCnt = 1 TO m.lnDirs *** Ignore "." and ".." entries m.lcDir = LOWER( ALLTRIM( CHRTRAN( m.laDirs[m.lnCnt, 1], '.', ''))) IF EMPTY( m.lcDir ) LOOP ENDIF *** Add the directory to the list m.lcList = m.lcList + IIF( EMPTY( m.lcList ), '', ';' ) + m.lcDir NEXT *** Copy results to the clipboard and return the list SET DEFAULT TO (m.lcOrigDir) _CLIPTEXT = m.lcList RETURN m.lcList
Published Sunday, June 18, 2006 1:05 PM by andykr
No comments:
Post a Comment