Page 1 of 1

SOLUCIONADO Algo raro con un array

PostPosted: Mon Jan 04, 2016 4:15 pm
by Willi Quintana
Hola amigos... en una función, lleno un array unidimensional con datos de un producto, luego modifico algunos registros con nuevos valores, dentro de la función el array esta modificado, pero al retornar a la función que lo llamo, el array aparece como si no se hubiera modificado... Estoy cometiendo algún error??
Code: Select all  Expand view

Function CargaDatos()
aDesPro := RelProductos(oMySQL, aDesPro, "QAZ123")

? aDesPro[ 2]                                                 // muestra  "01"      // los datos no cambiaron luego del AADD()
? aDesPro[12]                                                // muestra "UNIDAD"
...
..
.
Function RelProductos(oMySQL, aDesPro, cCodi)
aDesPro := {}
oDatos := DatosProducto(oMySQL, cCodi)          // aquí recabamos los datos de una tabla en MySQL
nLen := oDatos:RecCount()
FOR nCont := 1 TO nLen    // 77 campos
   AADD(aDesPro, oDatos:FieldGet(nCont)           // llenamos el array con los datos en forma unidimencional
NEXT nCont

? aDesPro[ 2]                                                 // muestra  "01"
? aDesPro[12]                                                // muestra "UNIDAD"

// realizo un cambio
aDesPro[ 2] := "12"
aDesPro[12] := "DOCENA"

? aDesPro[ 2]                                                 // muestra  "12"
? aDesPro[12]                                                // muestra "DOCENA"

Return(aDesPro)                                               // retorno el array con datos
 

Re: Algo raro con un array

PostPosted: Mon Jan 04, 2016 5:56 pm
by cnavarro
Willy, es estática la variable?

Re: Algo raro con un array

PostPosted: Mon Jan 04, 2016 6:11 pm
by hmpaquito
Willy, pues yo el codigo lo veo bien: no veo error y debe devolver "12" y "DOCENA". Seria bueno tener ese codigo mas sencillo para poder ejecutarlo incluso.
Me inclino porque el error lo tengas por otro sitio.

Cristóbal, creo que daría igual que fuera estatica, en la funcion, al ser parametro es una local y luego es devuelta.

Re: Algo raro con un array

PostPosted: Mon Jan 04, 2016 6:20 pm
by hebert_j_vargas
Willi Quintana wrote:Hola amigos... en una función, lleno un array unidimensional con datos de un producto, luego modifico algunos registros con nuevos valores, dentro de la función el array esta modificado, pero al retornar a la función que lo llamo, el array aparece como si no se hubiera modificado... Estoy cometiendo algún error??
Code: Select all  Expand view

Function CargaDatos()
aDesPro := RelProductos(oMySQL, aDesPro, "QAZ123")

? aDesPro[ 2]                                                 // muestra  "01"      // los datos no cambiaron luego del AADD()
? aDesPro[12]                                                // muestra "UNIDAD"
...
..
.
Function RelProductos(oMySQL, aDesPro, cCodi)
aDesPro := {}
oDatos := DatosProducto(oMySQL, cCodi)          // aquí recabamos los datos de una tabla en MySQL
nLen := oDatos:RecCount()
FOR nCont := 1 TO nLen    // 77 campos
   AADD(aDesPro, oDatos:FieldGet(nCont)           // llenamos el array con los datos en forma unidimencional
NEXT nCont

? aDesPro[ 2]                                                 // muestra  "01"
? aDesPro[12]                                                // muestra "UNIDAD"

// realizo un cambio
aDesPro[ 2] := "12"
aDesPro[12] := "DOCENA"

? aDesPro[ 2]                                                 // muestra  "12"
? aDesPro[12]                                                // muestra "DOCENA"

Return(aDesPro)                                               // retorno el array con datos
 



Hola Willi, solo debes pasar el array aDesPro por referencia:
Code: Select all  Expand view
aDesPro := RelProductos(oMySQL, @aDesPro, "QAZ123")

Re: Algo raro con un array

PostPosted: Mon Jan 04, 2016 7:01 pm
by RenOmaS
Es mejor colocar asi la llamada.

Code: Select all  Expand view

RelProductos(oMySQL, aDesPro, "QAZ123")


o

Code: Select all  Expand view
aDesPro := RelProductos(oMySQL, "QAZ123")

//y en la funcion
Function RelProductos(oMySQL, cCodi)
   Local aDesPro := {}
...
   Return aDesPro
 

SOLUCIONADO Re: Algo raro con un array

PostPosted: Tue Jan 05, 2016 1:23 am
by Willi Quintana
Hola Amigos,,, De verdad lo siento mucho,,, el error era mio,,, ese pedazo de código es de una app que tiene muchos años de trabajo,,, había una llamada de validación (media escondida) en la que no se procesaban los cambios... el manejo de los arrays en todos vuestros ejemplos y correcciones es correcto,,, mil disculpas.. :oops: :oops: :oops:

Re: SOLUCIONADO Algo raro con un array

PostPosted: Tue Jan 05, 2016 3:28 pm
by xmanuel
Willi aunque ya lo tienes solucionado el problema está aquí:
Function RelProductos(oMySQL, aDesPro, cCodi)
aDesPro := {}

Los arrays son tratados por referencia pero tu rompes la referencia tal como tratas aDesPro

Si quieres más rapidez yo lo haría así:
Code: Select all  Expand view


    Function CargaDatos()
    aDesPro := RelProductos(oMySQL, "QAZ123")

    ? aDesPro[ 2]                                                 // muestra  "01"      // los datos no cambiaron luego del AADD()
    ? aDesPro[12]                                                // muestra "UNIDAD"
    ...
    ..
    .
    Function RelProductos(oMySQL, cCodi)
    local aDesPro
    oDatos := DatosProducto(oMySQL, cCodi)          // aquí recabamos los datos de una tabla en MySQL
    nLen := oDatos:RecCount()
    aDesPro := array( nLEn )
    FOR nCont := 1 TO nLen    // 77 campos
       aDesPro[nCont ] := oDatos:FieldGet(nCont)           // llenamos el array con los datos en forma unidimencional
    NEXT nCont

    ? aDesPro[ 2]                                                 // muestra  "01"
    ? aDesPro[12]                                                // muestra "UNIDAD"

    // realizo un cambio
    aDesPro[ 2] := "12"
    aDesPro[12] := "DOCENA"

    ? aDesPro[ 2]                                                 // muestra  "12"
    ? aDesPro[12]                                                // muestra "DOCENA"

    Return(aDesPro)                                               // retorno el array con datos
     
 


He modificado tu función RelProductos para que devuelva un array nuevo, además está optimizada ya que array( nElemen ) crea un array con la dimension adecuada y dentro del for se asignan los elementos.
Con AADD tu programa tiene que REALOCAR memoria en cada llamada y eso es menos optimo. Siempre que se sepa la dimensión del array es mejor hacerlo como yo te digo. Espero que te valga. :D

PD: Pronto voy a sacar HDO para SQLite y me gustaría que fueras betatester si puedes :roll:

Re: SOLUCIONADO Algo raro con un array

PostPosted: Tue Jan 05, 2016 4:46 pm
by hmpaquito
Manuel,

El codigo es feo pero es correcto: hace lo que se espera que haga.
Se rompe la referencia pero da igual porque en la llamada recibe de nuevo el array.

Saludos

Re: SOLUCIONADO Algo raro con un array

PostPosted: Tue Jan 05, 2016 10:21 pm
by xmanuel
:lol: si es feo y muy poco optimizado.

Si se quiere se puede ir desde Sevilla a Malaga pasando por Cordoba pero si hay una autovía directa es mejor cogerla no?

Con array con dimensiones pequeñas no se notará mucho pero como le meta mucha caña se está duplicando el array en memoria ya que la referencia al array inicial no se rompe hasta que la segunda función devuelve el nuevo array y lo vuelve a asignar, y puede que aún así el "garbage collector" de Harbour tarde en liberarlo.
Eso y la optimización de crear el array ya dimensionado es mucho más rápido y efectivo usando la funcion array( n ) y luego asignar cada elemento a usar el AADD.

Yo tenía un profe de programación ( Java y PHP ) que decía que el código tenia que ser entendido por nosotros y otros programadores que lo leyeran, además de que fuera eficiente y compacto.
Y otro maestro como A. Linares al que he seguido desde hace muchisimos años ( mas de los que me gusta reconocer ) que también me enseñó algo parecido...

:twisted: :roll:

Re: SOLUCIONADO Algo raro con un array

PostPosted: Wed Jan 06, 2016 12:55 am
by Willi Quintana
Gracias a todos,,, aquí siempre se aprende...(y bastante), gtracias por vuestros consejos....
Salu2