AutoCad - AUTOLISP: Ayuda! no me explico esto

 
Vista:
Imágen de perfil de Nicolás
Val: 42
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

AUTOLISP: Ayuda! no me explico esto

Publicado por Nicolás (33 intervenciones) el 23/01/2017 15:29:24
Bueno, pasó lo siguiente y me surge la duda de si a alguien le habrá pasado lo mismo y sabe la razón...

Me fui creando unos 4 mini programas para acelerar mi desempeño en autocad, pero lo raro es que cuando cargue los 4, ya sea manualmente o ubicándolos en la carga al inicio. Cuando llamo a uno, me llama a otro. Más exactamente, al último que cargué,

Es decir, supongamos lo siguiente:

-4 programas: EJ1 - EJ2 - EJ3 - EJ4

-Los cargo en ese orden

-Llamo desde autocad EJ2... llama EJ4

-Llamo EJ1... llama EJ4

-Vuelvo a cargar EJ1

-Llamo EJ1... llama EJ1

-Llamo EJ3... llama EJ1

y así...

Yo supongo que es porque todos los programas los creé a partir de una especie de plantilla que me hice en la cual ya tengo determinados separadores, y el subprograma error, pero no estoy seguro o al menos creo que no debería pasar...

De todas formas esto es para saber bien el porqué de la cuestión... ya que lo solucioné poniendo todos los mini programas en un solo Lisp...

Ya sea que sepan o no, gracias por molestarse en leer mi situación, si no se entendió algo o necesitan más información, no duden en preguntar :P
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

AUTOLISP: Ayuda! no me explico esto

Publicado por Gerardo (986 intervenciones) el 23/01/2017 20:45:10
tendrias que postear el codigo para revisarlos.

De fijo eso no es un comportamiento normal.

Si no quieres subirlos intenta imaginar la memoria y el hecho de que en ella cada funcion y cada variable se corresponde con un nombre unico, y si estableces una función o variable llamada igual a otra existente, esta se sobreescribira en la memoria, es decir, el nombre ya existente pasara a apuntar a la nueva funcion o variable.

Para eso tenemos los conceptos de variables locales y globales, las locales se declaran en el encabezado de las funciones para que coexistan con otras que se puedan llamar igual pero fuera de la funcion actual, y algo parecido se puede hacer con los nombres de funciones internas, siempre y cuando no sean funciones comenzadas con "c:", es decir, funciones que sirven como de servicio, para ser invocadas dentro de otras funciones
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Nicolás
Val: 42
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

AUTOLISP: Ayuda! no me explico esto

Publicado por Nicolás (33 intervenciones) el 24/01/2017 13:42:30
Bien, estos no son exactamente los cuatro, pero si son pruebas que tienen el mismo problema, como dije antes, fueron creados a partir de una misma plantilla creada anteriormente. Y puede ser que tenga algo que ver con no mencionar alguna variable en los encabezados pero tampoco conseguí hacerlo funcionar así.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

AUTOLISP: Ayuda! no me explico esto

Publicado por Gerardo (986 intervenciones) el 24/01/2017 19:24:03
Bien, efectivamente, al cargar cada rutina, las funciones DatosIniciales, procedimientos y controlerror se almacenan en memoria con esos nombres y si ya existen se reescriben. Por eso la ultima versión que cargues será la que cualquier otra función ejecute.

Soluciones?

Una es renombrar las funciones para que tengan nombres unicos. Por ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(defun C:DIFZ ()
  (setvar "cmdecho" 0)
  (setq error0 *error* *error* ControlError)
  (setq ref2D (getvar "osmode"))
 
  (command "_undo" "i")
 
  (DatosInicialesDIFZ)
  (ProcedimientosDIFZ)
 
  (command "_undo" "f")
 
  (setvar "osmode" ref2D)
  (setq *error* error0)
  (setvar "cmdecho" 1)
  (prin1)
)
 
 
(defun DatosInicialesDIFZ ()
  (setq Pto1 (getpoint "\n Seleccione punto 1: "))
  (setq Pto2 (getpoint "\n Seleccione punto 2: \n"))
)
 
(defun ProcedimientosDIFZ ()
  (setq Dif (- (caddr Pto1) (caddr Pto2)))
  (princ Dif)
)


Otra es que las funciones de servicio sean internas y declaradas locales dentro de la principal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(defun C:DIFZ ( / DatosIniciales Procedimientos ref2D Pto1 Pto2)
 
  (defun DatosIniciales ()
    (setq Pto1 (getpoint "\n Seleccione punto 1: "))
    (setq Pto2 (getpoint "\n Seleccione punto 2: \n"))
  )
  (defun Procedimientos ( / Dif)
    (setq Dif (- (caddr Pto1) (caddr Pto2)))
    (princ Dif)
  )
 
  (setvar "cmdecho" 0)
  (setq error0 *error* *error* ControlError)
  (setq ref2D (getvar "osmode"))
 
  (command "_undo" "i")
 
  (DatosIniciales)
  (Procedimientos)
 
  (command "_undo" "f")
 
  (setvar "osmode" ref2D)
  (setq *error* error0)
  (setvar "cmdecho" 1)
  (prin1)
)
Asi las funciones DatosIniciales y Procedimientos que usa DIFZ solo existiran en memoria durante la ejecución de DIFZ y luego desaparecerán. Aunque hubiera unas funciones globales con los mismos nombres, si las hay locales DIFZ le dará prioridad a las versiones locales

Otra opción es no usar las funciones sino incluir el codigo de las mismas como parte de la principal. Esto es viable si solo hay una llamada a DatosIniciales y Procedimientos dentro de DIFZ (si hay más de una si conviene que sean funciones) y además si estas fuinciones de servicio son pequeñas, a verces se suelen agrupar en funciones los codigos muy largos para facilitar la comprensión y depuración de los programas. En este caso son de llamada unica y son diminutas entonces si aplica hacerlo así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(defun C:DIFZ ( / ref2D Pto1 Pto2 Dif)
 
  (setvar "cmdecho" 0)
  (setq error0 *error* *error* ControlError)
  (setq ref2D (getvar "osmode"))
 
  (command "_undo" "i")
 
  (setq Pto1 (getpoint "\n Seleccione punto 1: "))
  (setq Pto2 (getpoint "\n Seleccione punto 2: \n"))
 
  (setq Dif (- (caddr Pto1) (caddr Pto2)))
  (princ Dif)
 
  (command "_undo" "f")
 
  (setvar "osmode" ref2D)
  (setq *error* error0)
  (setvar "cmdecho" 1)
  (prin1)
)



Finalmente, para el caso de esta función te diría que no hace falta ni control de undo ni control de errores ni guardar el valor osmode. Al final la siguiente hace exactamente lo mismo:
1
2
3
4
5
6
(defun C:DIFZ nil
  (princ (- (caddr (getpoint "\n Seleccione punto 1: "))
            (caddr (getpoint "\n Seleccione punto 2: \n"))
  )      )
  (princ)
)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Nicolás
Val: 42
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

AUTOLISP: Ayuda! no me explico esto

Publicado por Nicolás (33 intervenciones) el 25/01/2017 14:38:22
Como no vi eso?! lo de los subprogramas... ahora lo entiendo mejor... con respecto al uso de errores, undo y osmode, si eso lo sabía, simplemente era parte de la plantilla inicial y no lo borré :P ademas de no ser estos los programas finales.

Muchas gracias gerardo! y hasta la próxima!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar