Thanks Carlos for that neat piece of code. I use the OutputDebugString(...) command a lot in my code for debugging.
I modified yours slightly to make it more useful for me so that array values can be displayed on the output debug window.
Here is the modified code:
Code: Select all
#ifdef __RELEASE__
#xcommand DEBUG <cString1>[, <cStringN>] =>
#else
#translate ASSTRING( <x> ) => If( <x> == NIL, 'NIL', Transform( <x> , NIL ) ) + CRLF
#xcommand DEBUG <cString1>[, <cStringN>] ;
=> ;
OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cString1">+" ("+ValType( <cString1> )+"): " ) ; OutputDebugString( FormatAsString( <cString1> ) ) ;
[ ; OutputDebugString( ProcName() +"("+LTrim(Str(ProcLine())) +") - " ) ; OutputDebugString( <"cStringN">+" ("+ValType( <cStringN> )+"): " ) ; OutputDebugString( FormatAsString( <cStringN> ) ) ]
#endif
Then add these two routines somewhere in your code:
Code: Select all
******************************************************************
* Procedure: FormatAsString( xVal )
* Notes...: Writes information stored in xVal as a string suitable to be
* output to any standard character output device.
* Function returns the formatted string representing the value "xVal"
*****************************************************************
Function FormatAsString( xVal )
local cString, cValtype, cBuffer,i, j
local nFirstDimLen,nSecondDimLen, nSecondDimType
local cTabSeparator := chr(VK_TAB)
cValtype := VALTYPE(xVal)
DO CASE
CASE cValtype == "A" //Check if an Array
nFirstDimLen := len(xVal) //First Dimension length
//Init to a show array length and then output a new line
cString := "Array Length is: " + alltrim(str(nFirstDimLen)) + " ... Array values follow:" + CRLF
if nFirstDimLen > 0
FOR i := 1 TO nFirstDimLen //Loop through the number of First dimension elements
nSecondDimType := if (xVal[i] == NIL, "U", ValType(xVal[i])) //Type of Second dimension element
if nSecondDimType == 'A'
nSecondDimLen := len(xVal[i]) //Number of Second dimension elements
if nSecondDimLen != 0
// Must be non-zero length array
cBuffer := "" //Init to empty string
FOR j := 1 TO nSecondDimLen //Loop through the number of Second dimension elements
cBuffer := cBuffer + ElementToString(xVal[i][j]) + cTabSeparator
NEXT // j
else //if nSecondDimLen != 0
cBuffer := "Nil Array {}"
endif //if nSecondDimLen != 0
else // if cValType == 'A'
cBuffer := ElementToString(xVal[i]) //Convert element that is NOT an Array to a string value
endif // if cValType == 'A'
cString += cBuffer + CRLF //Build resultant string
NEXT // i
else
cBuffer := "Nil Array {}" + CRLF
endif
OTHERWISE
// xVal is NOT an array at this point.
cString := ElementToString(xVal) + CRLF
ENDCASE
return cString
******************************************************************
* Procedure: ElementToString( xVal )
* Notes...: Function returns a string representing the value "xVal"
*****************************************************************
Function ElementToString(xVal)
local cBuffer, cValtype := VALTYPE(xVal)
DO CASE
CASE cValtype == "A" //Check if an Array
cBuffer := "Recursive Array. Not Implemented"
CASE cValtype == "L" //Logical value ... I prefer the displayed .T. or .F. notation
cBuffer := if(xVal, ".T.", ".F.")
CASE cValtype == "C" .OR. cValtype == "M" //ASCII String or Memo value
cBuffer := xVal
CASE cValtype == "N" //Numeric
cBuffer := Alltrim(str(xVal))
CASE cValtype == "D" //Date
cBuffer := DToC(xVal)
OTHERWISE
cBuffer := "Not Processed" // All other cases, then return "Not Processed"
ENDCASE
return cBuffer
When you execute this:
local cText := "Array n := {2, 4, 6}"
local n := {2, 4, 6}
DEBUG cText, n, Date(), .T., 5, Nil
n := {1, "Test String",{3,4,5}, .t.}
DEBUG n
n := {}
DEBUG n
you get on the output debug window the following:
PACKIT(197) - cText (C): Array n := {2, 4, 6}
PACKIT(197) - n (A): Array Length is: 3 ... Array values follow:
2
4
6
PACKIT(197) - Date() (D): 18/03/2009
PACKIT(197) - .T. (L): .T.
PACKIT(197) - 5 (N): 5
PACKIT(197) - Nil (U): Not Processed
PACKIT(200) - n (A): Array Length is: 4 ... Array values follow:
1
Test String
3 4 5
.T.
PACKIT(203) - n (A): Array Length is: 0 ... Array values follow:
Ofcourse, the code can be tailored to suit yourselves; perhaps even displaying instantiated Object variables in a tabular form.
Best regards,
Angelo.c