Page 1 of 2

Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 5:03 pm
by edufloriv
Saludos amigos,

Tengo un problema con unas variables private, como podrán ver lineas abajo al inicio del módulo declaro una variable llamada OH_MODO como private, esta variable la uso a lo largo del módulo para realizar las operaciones respectivas. Sin embargo, hay ocasiones, no siempre, en las que al tratar de cerrar el módulo me lanza ese error:

Error BASE/1003 No existe la variable: OH_MODO

Called from ORDENSALIR(315)
Called from (b)ORDENDECOMPRA(51)

He revisado todos los .prg del sistema con el crimson y ya he verificado que esta variable solo existe en este módulo. En realidad me esta ocurriendo lo mismo en otros módulos del sistema con algunas variables, pero entiendo que resolviendo este, resuelvo todos. No sé si a alguno de Ustedes le he pasado y a lo mejor ya lo resolvió, por lo que recurro a su inapreciable ayuda.

* ------------------------------------------------------ *
* SISTEMA : FARMACOM *
* PRG : NOTAS.PRG *
* CREADO : 15-10-2010 *
* ACTUALIZADO : *
* AUTOR : EDUARDO V. FLORES RIVAS *
* COMENTARIOS : MODULO PARA CONFECCION DE PEDIDOS. *
* ------------------------------------------------------ *

PROC OrdenDeCompra

IF IsWindowDefined(Win_Orden)=.T.
MINIMIZE WINDOW Win_Orden
RESTORE WINDOW Win_Orden
RETURN
ENDIF

PRIVATE OH_NUMERO := 0
PRIVATE OH_FECHA := ''
PRIVATE OH_CODPROV := ''
PRIVATE OH_NOMPROV := ''
PRIVATE OH_ARCHIVO := ''
PRIVATE OH_REGISTR := 0
PRIVATE OH_MODO := 'Nada' // <-- OJO CON ESTA VARIABLE

PRIVATE aDetaDatos := {}
PRIVATE aEstaticos := {}
PRIVATE aLineMem := {}
PRIVATE aMesAnualSlots := {}
PRIVATE cTmpOrdenC := 'c:\farmacom\ordenes\ordenc.dbf'
PRIVATE cTmpOrdenD := 'c:\farmacom\ordenes\ordend.dbf'
PRIVATE cBackupC := ''
PRIVATE cBackupD := ''

PRIVATE oPediArti , oPediProv , oPediMark

IF ! ISDIR('c:\Farmacom\Ordenes')
CreateFolder('c:\Farmacom\Ordenes')
ENDIF

PrimosAbrir()

DEFINE WINDOW Win_Orden ;
AT 0 , 0 ;
WIDTH 1020 HEIGHT 730 ;
TITLE "ORDEN DE COMPRA" ;
FONT "Arial" SIZE 9 ;
CHILD ;
NOMAXIMIZE ;
ON INIT OrdenIniciar() ;
ON RELEASE OrdenSalir()

....

*
* GRID DE DETALLES
*
@ 130 , 010 BROWSE BrwPedidos ;
WIDTH 980 ;
HEIGHT 530 ;
HEADERS {'Código','Artículo','Labo','Unids.','VVF','PVF','Dct.T.','Costo','Total','Bonif.','Dct.B','Dct.1','Dct.2','Dct.3','Dct.4'} ;
FIELDS { 'ODTMP->OD_ARTCOD' , 'ODTMP->OD_ARTNOM' , 'ODTMP->OD_LABCOD' , 'ODTMP->OD_UNIDS' , 'ODTMP->OD_VVF' , 'ODTMP->OD_PVF' , 'ODTMP->OD_DCTT' , 'ODTMP->OD_CSTUNI' , 'ODTMP->OD_CSTTTL' , 'ODTMP->OD_TEXTB' , 'ODTMP->OD_DCTB' , 'ODTMP->OD_DCT1' , 'ODTMP->OD_DCT2' , 'ODTMP->OD_DCT3' , 'ODTMP->OD_DCT4' } ;
WORKAREA ODTMP ;
WIDTHS { 60 , 250 , 50 , 60 , 80 , 80 , 70 , 80 , 90 , 50 , 50 , 50 , 50 , 50 , 50 } ;
JUSTIFY { BROWSE_JTFY_LEFT , BROWSE_JTFY_LEFT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT , BROWSE_JTFY_RIGHT } ;
ON DBLCLICK OrdenEditItem()

...

END WINDOW

ACTIVATE WINDOW Win_Orden

PrimosCerrar()

RETURN


*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC OrdenIniciar

OH_MODO := 'Nada'
...
Win_Orden.BrwPedidos.Refresh

RETURN


*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC OrdenSalir

IF SELECT('ODTMP') > 0 .AND. TYPE(OH_MODO) <> 'U' //<-- EL ERROR SALE EN ESTA LINEA (315)
IF ODTMP->(RECCOUNT()) > 0 .AND. OH_MODO='Crear'
IF MsgYesNo('¿ Desea cancelar la orden de compra actual ?')
OrdenBorrarTemps()
ENDIF
ELSE
OrdenBorrarTemps()
ENDIF
ENDIF

RETURN


De antemano mil gracias por su valioso tiempo.

NOTA : Si necesitan el módulo completo, solo háganmelo saber para enviarselos.

Re: Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 5:31 pm
by Javier Tovar
Hola edufloriv,

A mi me han pasado cosas semejantes y lo he resuelto de la siguiente manera, muchas de esas dependen en el lugar donde ponemos el código, por ejemplo yo lo pongo así:

Code: Select all

#include <hmg.ch>

FUNCTION MAIN()
LOCAL nValor,....
PUBLIC nMin, nMax, nIncremento, nValor,.......
PRIVATE nValorIni

   IF IsWindowDefined(Win_Orden)=.T.
      MINIMIZE WINDOW Win_Orden
      RESTORE WINDOW Win_Orden
      RETURN
   ENDIF

   IF ! ISDIR('c:\Farmacom\Ordenes')
      CreateFolder('c:\Farmacom\Ordenes')
   ENDIF

   PrimosAbrir()

   DEFINE WINDOW Win_Orden ;
             AT 0 , 0 ;
             WIDTH 1020 HEIGHT 730 ;
             TITLE "ORDEN DE COMPRA" ;
             FONT "Arial" SIZE 9 ;
             CHILD ;
            NOMAXIMIZE ;
            ON INIT OrdenIniciar() ;
           ON RELEASE (OrdenSalir(), PrimosCerrar())

                 ......
                  ........
                 .......
   END WINDOW

   ACTIVATE WINDOW Win_Orden

RETURN


*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC OrdenIniciar

    OH_MODO := 'Nada'
   ...
   Win_Orden.BrwPedidos.Refresh

RETURN


*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------

PROC OrdenSalir

    IF SELECT('ODTMP') > 0 .AND. TYPE(OH_MODO) <> 'U' //<-- EL ERROR SALE EN ESTA LINEA (315)
        IF ODTMP->(RECCOUNT()) > 0 .AND. OH_MODO='Crear'
                IF MsgYesNo('¿ Desea cancelar la orden de compra actual ?')
                       OrdenBorrarTemps()
                ENDIF
       ELSE
               OrdenBorrarTemps()
       ENDIF
    ENDIF

RETURN
Bueno, por lo que yo veo es que las variables PRIVATE están después de un IF, después el procedimiento "PrimosCerrar()" esta después del "ACTIVATE WINDOW Win_Orden", Creo que si quieres que se ejecute ese procedimiento al cerrar tu Form lo tienes que incluir en "ON RELEASE" de tu ventana. Y dicho procedimiento no se si ahí se encuentra también la variable que te manda error.

Y por favor utiliza el botón que dice "CODE" (aquí donde se escriben los Post) y utiliza Sangría en tu código para que sea más claro.


Saludos y espero que te ayude, y si no házmelo saber :D

Re: Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 5:48 pm
by Javier Tovar
Hola ,

Otra pregunta: Hay en algún momento de tu código donde TYPE(OH_MODO) <> 'U' se cumpla?, que pueda tener el valor de "NIL",

o no será mejor utilizar VALTYPE() ?

Code: Select all

Examples

     .  These examples show the return values for several data types:

        ? VALTYPE(1)                // Result: N
        ? VALTYPE("GOOB")           // Result: C
        ? VALTYPE(NIL)              // Result: U
        ? VALTYPE(array)            // Result: A
        ? VALTYPE(block)            // Result: B 
Saludos

Re: Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 8:50 pm
by esgici
Did you tried PUBLIC instead of PRIVATE ?

Re: Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 9:20 pm
by edufloriv
Hola amigos,

Antes que nada gracias por sus respuestas. Y bueno si, la proxima vez uso el botón 'CODE' creo que por eso no se ven las sangrias. Lo siento.

Como dice esgici, efectivamente podria resolverlo haciendola PUBLIC, ya se me habia pasado por la cabeza, pero lo lance al foro para ver si alguien mas habia experimentado este problemilla y un poco para encontrarle sentido al mismo.

Javier, en realidad con la linea donde puse TYPE(OH_MODO) trataba de resolver el problema, pues supuestamente cuando TYPE se aplica sobre una variable que no existe te devuelve 'U', el error originalmente me salia en la linea que sigue, donde si te fijas, también aparece OH_MODO.

Ok, dicho esto, en resumén voy a realizar lo siguiente:

1.- Voy a pasar las proc que estaban afuera (primosabrir(),primoscerrar()) a el INIT y RELEASE de la ventana.

2.- Con respecto a declarar primero las private antes de verificar si la ventana ya esta abierta, tengo un dilema, porque justamente lo puse asi porque me pasaba que si el usuario abria la primera vez, las private se declaraban, si abria una segunda vez esta misma ventana, teniendo abierta aun esta ventana, como la verficacion estaba después de la declaracion, las private se sobreescribian, la segunda llamada ya no se realizaba y la primera ventana abierta se maximiziba, pero luego, en alguno de los procesos, me lanzaba algún error que implicaba alguna de estas variables.

De todos modos, si Ustedes me dicen que la única solución es hacerla publica, pues lo hago, pero queria encontrar algo de lógica al problema.

Saludos a todos y muchas gracias por su valioso tiempo.

Re: Variables PRIVATE no existen.

Posted: Tue Mar 25, 2014 9:25 pm
by edufloriv
Hola de nuevo,

Olvide mencionar que ni en PrimosAbrir() ni en PrimosCerrar() existe la variable OH_MODO, ni siquiera se menciona.


Gracias de nuevo y saludos,

Re: Variables PRIVATE no existen.

Posted: Wed Mar 26, 2014 2:26 am
by luisvasquezcl
Hola Edufloriv,
Siempre debe tener en cuenta el ambito de visibilidad de la variable dependiendo de donde se defina.
Si define una variable como privada dentro de un procedimiento o función y la quiere utilizar fuera de él, no será visible.
p.e.
procedure proc1
private var1 := 10
proc2()
return

procedure proc2()
@10, 10 say var1
inkey(0)
return
en este caso la variable Var1 definida el el proc1 no podras verla en el proc2

Ahora en este caso. Si defines la variable a nivel de módulo sí podrás verla.

Private Var1 := 0
Proc1()
proc2()
return

Procedure proc1()
var1 := 10
return

procedure proc2()
alert( var1 )
return

Si necesitas ver el manual de clipper puedes verlo en la siguiente dirección:
http://www.itlnet.net/programming/progr ... /menu.html" onclick="window.open(this.href);return false;
Espero haber sido de ayuda.
Saludos cordiales,
Luis Vásquez.

Re: Variables PRIVATE no existen.

Posted: Wed Mar 26, 2014 3:17 am
by Javier Tovar
Hola Luis Vazquez,

Como es definir a nivel de modulo y cuando no?

Ya vi el manual de Clipper que mencionas y no dan ejemplo al respecto (espero no equivocarme). Yo como las declaro están disponibles en todo el archivo *.PRG donde las defino. (Si estoy mal por favor aclarar esta duda).

Code: Select all

FUNCTION MAIN()
LOCAL nValorIni:= 5
PRIVATE nValorFinal := 10
PUBLIC nValorMedio := 7.5

VerValor()

	SET EXCLUSIVE OFF           // Inactivar para poder Abrir sahred New
	SET DELETE ON               // Mostrar los Eliminados
........
RETURN NIL

PROCEDURE VerValor()
  MSGBOX("ESTE ES EL VALOR DE UNA VARIABLE PRIVADA"+STR(nValorFinal))
RETURN NIL


Y si lo reconoce el valor.

Saludos.

Re: Variables PRIVATE no existen.

Posted: Wed Mar 26, 2014 3:37 am
by Javier Tovar
Hola Luis Vázquez,

Si ya hice una prueba donde dice que no existe la variable Privada y es asi:

Code: Select all

FUNCTION MAIN()
LOCAL nA := 12 <==== SOLO ES VISIBLE EN EL PROCEDIMIENTO DONDE SE DEFINIÓ.
PUBLIC nB := 24 <==== SON DECLARADAS A NIVEL DE APLICACIÓN, EN TODOS LOS *.PRG's DE NUESTRA APLICACIÓN.
PRIVATE nC := 36   <==== SON DECLARADAS A NIVEL DE MODULO, EN TODO EL *.PRG.

   Dos()
   Tres()

RETURN NIL


PROCEDURE Dos()
PRIVATE nD := 20 <==== SOLO ES VISIBLE EN EL PROCEDIMIENTO DONDE SE DEFINIÓ.
RETURN NIL


PROCEDURE Tres()

    MsgBox(STR(nA))  <====== NO LA RECONOCE COMO VARIABLE

    MsgBox(STR(nB))  <====== SI LA RECONOCE COMO VARIABLE
    MsgBox(STR(nC))  <====== SI LA RECONOCE COMO VARIABLE

    MsgBox(STR(nD))  <====== NO LA RECONOCE COMO VARIABLE

RETURN NIL
Saludos

Re: Variables PRIVATE no existen.

Posted: Wed Mar 26, 2014 4:02 am
by esgici
Doc wrote:The PRIVATE statement creates variables and arrays visible within the current and invoked procedures or user-defined functions.
So, scope of variables declared as PRIVATE in the MAIN module is same as declared PUBLIC; none ".prg file wide".

As the result, problem of Eduardo will be solved by moving PRIVATE statements to the MAIN module.

Viva INTERNATIONAL HMG :D