avista wrote:I need to use array longer than 4096 elements (multidimensional if possible), and it is verry important to be used in LISTBOX.
Some sugestions ?[/b]
Firts, Antonio is right.
Second, try something like this with your code:
ArPrgElem[6] = TArray():New( your length array )
@ 1,1 LISTBOX ArPrgElem[3] ;
FIELDS "" ;
UPDATE ;
OF IdeArra4[5][NumPrg][1] ;
ON LEFT DBLCLICK TeclaFWD( VK_RETURN, nFlags, IdeArra)
// ArPrgElem[6] es el objeto de las array de arrays
//
ArPrgElem[3]:nAt = 1
ArPrgElem[3]:bLine = { || { ArPrgElem[6]:xGet(ArPrgElem[3]:nAt) } }
ArPrgElem[3]:bGoTop = { || ArPrgElem[3]:nAt := 1 }
ArPrgElem[3]:bGoBottom = { || ArPrgElem[3]:nAt := Eval( ArPrgElem[3]:bLogicLen ) }
ArPrgElem[3]:bSkip = { |
nWant, nOld | nOld := ArPrgElem[3]:nAt, ArPrgElem[3]:nAt +=
nWant, ;
ArPrgElem[3]:nAt := Max( 1, Min( ArPrgElem[3]:nAt, ;
Eval(ArPrgElem[3]:bLogicLen) ) ), ArPrgElem[3]:nAt - nOld }
ArPrgElem[3]:bLogicLen = { || ArPrgElem[6]:nIndMax }
ArPrgElem[3]:cAlias = "ARRAY"
ArPrgElem[3]:GoTop()
ArPrgElem[3]:nClrText := {|| ColorBloqueo( ArPrgElem[6]:xGet(ArPrgElem[3]:nAt) )}
ArPrgElem[3]:bRClicked := { |nRow,nCol,nKeyFlags| PasaMenu(nRow, nCol, nKeyFlags, IdeArra ) }
ArPrgElem[3]:nLineStyle := 0
...
The class TARRAY:
*****************************************************************************
********************** Funciones £tiles s¢lo en FiveWin *********************
********************** 66¦ parte ********************************************
/* A tener en cuenta:
-Se trata de una matriz de 4096 * 4096 elementos.
-Se van a¤adiendo o borrando ROW's de 4096 a la vez y en esos
casos de realiza un RESIZE() de la matriz.
Se trata de un clase muy interesante a la hora de tratar array's de
grandes dimensiones (superiores a 4096 elementos).
*/
#include "FiveWin.ch"
#define CR Chr( 13 )
/*
{ { ::a2[ 1, 1 ], ::a2[ 1, 2 ], ..., ::a2[ 1, Len( ::a2[ 2 ] ) ] }, ;
{ ::a2[ 2, 1 ], ::a2[ 2, 2 ], ..., ::a2[ 2, Len( ::a2[ 2 ] ) ] }, ;
.......
{ ::a2[ 4096, 1 ], ::a2[ 4096, 2 ], ..., ::a2[ 4096, Len( ::a2[ 2 ] ) ] } ;
}
*/
/*
Con oArray:nIndMax = 500000 .-
Para nI = 245741, se produce un "Clipper internal error":
"Error no recuperable 332:
Desbordamiento de la memoria para matrices/cadenas"
He comprobado que funciona con oArray:nIndMax = 300000 .-
*/
CLASS TArray
DATA a2
DATA nIndMax, nIndRow, nIndCol
METHOD New( nIndMax ) CONSTRUCTOR // 0 <= nIndMax <= 4096^2
METHOD End() INLINE ::a2 := nil, ;
Memory( -1 )
METHOD xSet( nInd, xValor )
METHOD xGet( nInd )
METHOD uAdd( xValor ) //incluye resizing
METHOD uIns( nInd, xValor ) //incluye resizing
METHOD uDel( nInd ) //incluye resizing
METHOD uIncrSize() //m‚todo auxiliar
METHOD uDecrSize() //m‚todo auxiliar
ENDCLASS
METHOD New( nIndMax ) CLASS TArray
If nIndMax < 0 .or. nIndMax > 16777216
/*MsgStop( "Clase TArray()" + CR + ;
"nIndMax =" + Str( nIndMax ) + CR + ;
OemToAnsi( "Indice máximo fuera de rango." ),;
"0 <= nIndMax <= 4096^2 (16777216)" ;
)*/
MsgStop( "Clase TArray()" + CR + ;
"nIndMax =" + Str( nIndMax ) + CR + ;
"Indice máximo fuera de rango.", ;
"0 <= nIndMax <= 4096^2 (16777216)" ;
)
End
::nIndMax := nIndMax
::nIndRow := 4096
If ::nIndMax > 4096
::nIndCol := 1 + Int( ::nIndMax / 4096 ) // ::nIndCol >= 2
Else
::nIndCol := 1
End
::a2 := Array( ::nIndRow, ::nIndCol )
Memory( -1 )
RETURN Self
METHOD xSet( nInd, xValor ) CLASS TArray
*No lo pongo, para no retardar...
*If nInd < 1 .or. nInd > ::nIndMax
* MsgStop( "Clase TArray()" + CR + ;
* "::xSet( nInd, xValor )", ;
* "Indice fuera de rango: nInd = " + LTrim( Str( nInd ) ) ;
* )
*End
::nIndCol := Int( nInd / 4096 ) // ::nIndCol >= 0
::nIndRow := nInd - ::nIndCol * 4096 // ::nIndRow >= 0
If ::nIndRow = 0
*( ::nIndCol > 0 )
::nIndRow := 4096
Else
::nIndCol++
End
::a2[ ::nIndRow, ::nIndCol ] := xValor
RETURN xValor
METHOD xGet( nInd ) CLASS TArray
*No lo pongo, para no retardar...
*If nInd < 1 .or. nInd > ::nIndMax
* MsgStop( "Clase TArray()" + CR + ;
* "::xGet( nInd )", ;
* "Indice fuera de rango: nInd = " + LTrim( Str( nInd ) ) ;
* )
*End
::nIndCol := Int( nInd / 4096 ) // ::nIndCol >= 0
::nIndRow := nInd - ::nIndCol * 4096 // ::nIndRow >= 0
If ::nIndRow = 0
*( ::nIndCol > 0 )
::nIndRow := 4096
Else
::nIndCol++
End
RETURN ::a2[ ::nIndRow, ::nIndCol ]
METHOD uIncrSize() CLASS TArray
local nIndCol, nI
If ::nIndMax > 4096
nIndCol := 1 + Int( ::nIndMax / 4096 ) // nIndCol >= 2
Else
nIndCol := 1
End
::nIndMax++ ///////
::nIndRow := 4096
If ::nIndMax > 4096
::nIndCol := 1 + Int( ::nIndMax / 4096 ) // ::nIndCol >= 2
Else
::nIndCol := 1
End
If nIndCol != ::nIndCol
*Resizeado de las columnas.-
For nI := 1 To 4096
aSize( ::a2[ nI ], ::nIndCol )
Next
Memory( -1 )
End
SysRefresh() //necesario para que funcione la pr¢xima ejecuci¢n
// de funciones del tipo Msg...()
RETURN nil
METHOD uDecrSize() CLASS TArray
local nIndCol, nI
IF ::nIndMax = 1
::nIndMax-- // ::nIndMax := 0
::nIndRow := 4096
::nIndCol := 1
::a2 := Array( 4096, 1 )
Memory( -1 )
ELSE
If ::nIndMax > 4096
nIndCol := 1 + Int( ::nIndMax / 4096 ) // nIndCol >= 2
Else
nIndCol := 1
End
::nIndMax-- ///////
::nIndRow := 4096
If ::nIndMax > 4096
::nIndCol := 1 + Int( ::nIndMax / 4096 ) // ::nIndCol >= 2
Else
::nIndCol := 1
End
If nIndCol != ::nIndCol
*Resizeado de las columnas.-
For nI := 1 To 4096
aSize( ::a2[ nI ], ::nIndCol )
Next
Memory( -1 )
End
END
SysRefresh() //necesario para que funcione la pr¢xima ejecuci¢n
// de funciones del tipo Msg...()
RETURN nil
METHOD uAdd( xValor ) CLASS TArray
::uIncrSize()
::xSet( ::nIndMax, xValor )
RETURN nil
METHOD uIns( nInd, xValor ) CLASS TArray
local x
local nI
IF ::nIndMax = 0
::uIncrSize()
nInd := 1 //"pasamos de" lo que valga nInd
ELSE
If nInd > ::nIndMax
MsgStop( "Clase TArray()" + CR + ;
"::uIns( nInd, xValor )", ;
"Indice fuera de rango: nInd = " + LTrim( Str( nInd ) ) ;
)
End
::uIncrSize()
*Desplazamiento hacia abajo.-
For nI := ::nIndMax To nInd + 1 Step -1
x := ::xGet( nI - 1 )
::xSet( nI, x )
Next
END
::xSet( nInd, xValor )
RETURN nil
METHOD uDel( nInd ) CLASS TArray
local x
local nI
IF ::nIndMax = 0
MsgStop( "Clase TArray()" + CR + ;
"Intento de borrar siendo ::nIndMax = 0",;
"::uDel( " + LTrim( Str( nInd ) ) + " )" ;
)
ELSE
If nInd > ::nIndMax
MsgStop( "Clase TArray()" + CR +;
"::uDel( nInd )", ;
"Indice fuera de rango: nInd = " + LTrim( Str( nInd ) ) ;
)
End
If ::nIndMax > 1 //de lo contrario, ::nIndMax = 1
if nInd < ::nIndMax //de lo contrario, nInd = ::nIndMax
*Desplazamiento hacia arriba.-
For nI := nInd To ::nIndMax - 1
x := ::xGet( nI + 1 )
::xSet( nI, x )
Next
end
End
*(Despreciamos el actual elemento ::nIndMax -‚simo)
::uDecrSize()
END
RETURN nil
Regards
Carlos G.
Note: Que alguién le traduzca mi mal ingles.