PROC MAIN() nResult := NIL nDivident := 1 nDivisor := 0 cMacro := " nResult := nDivident / nDivisor " QOutResult( nDivident, nDivisor, cMacro ) // 1 0 UE macro is inValid nDivisor := 2 QOutResult( nDivident, nDivisor, cMacro ) // 1 2 N Result is : 0.50 cMacro := "AT( 'OK', MyUDF() ) > 0" QOutResult( 'AT( OK', 'MyUDF()', cMacro ) // AT( OK ... U macro is inValid cMacro := "{ 1, 2 }[ 2 ]" QOutResult( '{ 1, 2 }', '[2]', cMacro ) // { 1, 2 } [2] N Result is : 2 cMacro := "{ 1, 2 }[ 5 ]" QOutResult( '{ 1, 2 }', '[5]', cMacro ) // { 1, 2 } [5] UE macro is inValid lCond := 0 cMacro := "if( lCond, 'true', MyUDF() )" QOutResult( lCond, '', cMacro ) // 0 U macro is inValid ? WAIT RETU // Main() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._. PROC QOutResult( xVal1, xVal2, cMacro ) LOCAL cType := TYPE( cMacro ) ? PAD( xVal1, 10 ), PAD( xVal2, 10 ), PAD( cType, 3 ) IF ( cType # "U") ?? "Result is :", &cMacro ELSE ?? "macro is inValid" ENDIF RETU // QOutResult() *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._
Monthly Archives: March 2015
Mini Search Machine (2014)
Mini Search Machine ( MSM ) is a mini search utility for HMG users.
Purposes of this program is denote extreme power and flexibility of HMG and some goodies of command line and batch processing.
And of course (as always) being useful to HMG community by giving a humble example.
Thanks to builder and all kind of supporter and follower of HMG
And special thanks to Sr. P.C. Toledo for inspiration, hint for internet search and especially wonderful Clipper Online forum.
Notes :
– Please check folder definitions in MSM.ch depending on your configuration
– When output flow become annoyingly long, you can
– use “Wait Pages” option before starting
– use “Pause” key of keyboard and then any key to continue
– cut flow by pressing Ctrl-C or Ctrl-Break
– simply use X button
– I couldn’t implement “F:file” switch of FINDSTR; any idea ?
Happy HMG’ing 😀
Download :
How I can find empty fields in my table ?
This sample test program scan any table records for empty fields in any type ,
and reports number of record(s) included empty field(s) with number of FIRST empty field.
#include <hmg.ch> PROC MAIN SET( _SET_EOF, .F. ) USE TEST nFldCount := FCOU() cTestFNam := "empties.txt" nEmptyRec := 0 SET ALTERNATE TO (cTestFNam) SET ALTERNATE ON WHIL ! EOF() FOR nFld := 1 TO nFldCount IF EMPTY( FIELDGET( nFld ) ) ? RECN(), nFld ++nEmptyRec EXIT ENDI NEXT SKIP ENDD SET ALTE OFF SET ALTE TO MsgBox( LTRIM( STR( RECC() ) ) + " records with " +; LTRIM( STR( nFldCount ) ) + " field(s) scanned ;" +; CRLF + ; LTRIM( STR( nEmptyRec ) ) + ; " records found with empty field." ) EXECUTE FILE "NOTEPAD.EXE" PARAMETERS cTestFNam RETU
Extract non alphanumerics
* How I can remove all non alpha-numeric characters from a string #include <hmg.ch> /* Remove all non alpha-numeric characters from a string */ PROC MAIN cOriginal := "=<abc_-.#@123>#+-.," cCleaned := RemNAN( cOriginal ) MsgBox( "Original : " + cOriginal + STR( LEN( cOriginal ), 3 ) +; CRLF + ; "Cleaned : " + cCleaned + STR( LEN( cCleaned ), 3 ) ) RETU *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNC RemNAN( cString ) LOCAL cRVal := "",; c1Char := "" FOR EACH c1Char IN cString cRVal += IF( ISALPHA( c1Char ) .OR. ISDIGIT( c1Char ), ; c1Char, "" ) NEXT RETU cRVal *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![]()
What are basic data types ?
Types of FIELD variables are defined in STRUCTURE of tables (.dbf files).
For other type (memory) variables, Clipper isn’t a “strong typing” language. Programmers not obliged to define variables with type before referenced (used); variables are typed “on the fly” that is by assigning value.
Notes :
- “M” (memo) type is usable only in .dbf files, there isn’t “M” type variable. In terms of operation, “M” data is similar to character type.
- Harbour has 6 scalar types : Nil, String, Date, Logical, Number, Pointer, and 4 complex types: Array, Object, CodeBlock, and Hash. Types cited here are BASIC type: String, Number, Logical and Date.
- For more info about data types please refer here.
- Harbour supports also “extended” field types; see here.
- There is also NIL type that has only one allowable value: NIL. NIL is not “undefined”, simply “nothing”.
- This program also use “ALTERNATE” writing feature for display program output. This is handy for especially debugging and logging purposes.
/*
A little test program to explore basic data types in Clipper.
*/ #include <hmg.ch> PROC MAIN * Some global settings SET( _SET_EOF, .F. ) // Don't put EOF marker to end of files built SET CENTURY ON // Display Century portion of dates type data * Set test file name cTestFNam := "DataTypes.txt" // Name of test file * Set and open alternate file SET ALTERNATE TO (cTestFNam) // Redirect screen (console) output // (results of ? commands) to that file SET ALTERNATE ON // Open alternate writing * Assign values to variables cCharVar := "This is a character data" // Assign astring value to this variable nNumrVar := 123.456 // Assign this numeric value to this variable lLogiVar := .T. // Assign this logical value to this variable dDateVar := DATE() // Assign this date type value (date of day) // to this variable * Write variable names and value ? "cCharVar :", TYPE( "cCharVar" ), cCharVar ? "nNumrVar :", TYPE( "nNumrVar" ), nNumrVar ? "lLogiVar :", TYPE( "lLogiVar" ), lLogiVar ? "dDateVar :", TYPE( "dDateVar" ), dDateVar * Close alternate writing and file SET ALTE OFF // Close alternate writing SET ALTE TO // Close alternate file * Run Notepad of Windows and send to it my test file
EXECUTE FILE "NOTEPAD.EXE" PARAMETERS cTestFNam RETU *-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.