You are on page 1of 8

Reinaldo Togores <reinaldo.togores@unican.

es>
Arquitecto. Profesor Asociado de Tcnicas de Expresin Grfica, Universidad de
Cantabria (Santander, Espaa). Consultor en temas CAD y GIS. Miembro del Autodesk
Developers Network
Pgina WEB Personal: http://personales.unican.es/togoresr

Juntndolo todo... y una pizca de DCL


Los dos artculos anteriores examinaban la capacidad de Visual LISP para acceder a
las propiedades y mtodos de los objetos ActiveX. Ahora utilizaremos las funciones
en ellos desarrolladas (CadXpress 61 y 62) para crear un programa Visual LISP
dotado de una interfaz grfica de usuario programada en DCL.

Antecedentes
En el nmero 61 describamos la manera de acceder a una hoja de clculo EXCEL
desde AutoCAD y llenar los campos de una tabla con los datos de una lista de
asociacin LISP.
En el siguiente nmero examinamos una funcin capaz de extraer la informacin de
los atributos y otros datos asociados a las referencias de bloque.
Contamos con que el lector ya dispondr de las siguientes funciones organizadas en
dos archivos1:
Achivo fuente:
Funciones:
Propsito:
ListaExcel.LSP apl-err
Gestin de errores.
Establece la comunicacin.
(CadXpress 61) IniciaExcel
TerminaExcel
Libera la aplicacin.
DatoCelda
Inserta una valor en una celda
Excel.
ProcesaFila
Escribe los campos de una fila.
ProcesaTabla
Escribe la fila de ttulos y llena
la tabla.
Lista->Excel
Recibe la lista e invoca las
funciones anteriores
LeeAttribX.LSP LeeAtribX
Extrae datos a partir de un objeto
(CadXpress 62)
Referencia de Bloque
Procesa
Lee el identificador y el valor de
un atributo
Los artculos mencionados incluyen adems funciones diseadas con el objeto de
probar el funcionamiento de los programas. De una de esas funciones podemos
ahora prescindir, la funcin TablaCirculos. Otra la utilizaremos con pequeas
modificaciones:
Artculo:
Funciones:
Propsito:
CadXpress 61
TablaCirculos
No se utilizar
C:TABLA
No se utilizar
CadXpress 62
SelBloque
Se modifica para que reciba el
nombre de un bloque seleccionado de
un Cuadro de Dilogo en lugar de
teclearlo el usuario
A estos dos archivos aadiremos en esta entrega el archivo con la definicin del
Cuadro de Dilogo y otro con las funciones Visual LISP necesarias para gestionarlo
y que explicaremos ms abajo:

2000, Reinaldo Togores. Todos los derechos reservados

Achivo fuente:
ExtrATT.LSP
CadXpress 63

Funciones:
CargaDialogo
CompruebaAtributos
ExtrATT
ListaNombres

TieneAtributos
SelBloque

ExtrATT.DCL

Propsito:
Inicia la operacin del Cuadro de
Dilogo.
Comprueba que el bloque
seleccionado posea atributos.
Lanza la funcin Lista->Excel.
Devuelve una lista con los bloques
de usuario encontrados en el
dibujo.
Discrimina si una Definicin de
Bloque incluye atributos.
Selecciona las Referencias de
Bloque que corresponden al nombre
de bloque seleccionado por el
usuario.
Definicin del Cuadro de Dilogo

El Cuadro de Dilogo
El cuadro de dilogo propuesto (ver Figura 1) es muy simple, aunque sirve
perfectamente a los fines que nos proponemos.

Figura 1. Cuadro de Dilogo de la


Aplicacin.

El componente principal del Cuadro de dilogo lo es una casilla de lista (list_box)


que presenta los nombres de los bloques presentes en el dibujo. Para cada nombre
de bloque se indica si tiene atributos insertando el texto "ATRIB" en la fila
correspondiente. El ordenamiento de este texto en forma de columna se logra
introduciendo un carcter tabulador "\t" entre el nombre del bloque y el texto
"ATRIB", y asignando al atributo tabs de la casilla de lista un valor de 33, siendo la
anchura total (width) de 40. Esta casilla de lista slo admite la seleccin de un
nombre de bloque (multiple_select = false;).
Los otros componentes del dilogo son los botones de Aceptar y Cancelar que
provienen del componente predefinido ok_cancel y una lnea de texto para indicar
errores tambin predefinida a partir del componente errtile. Para el cdigo
completo del archivo ExtrATT.DCL vase la Figura 2. Es importante que la
ubicacin de este archivo se encuentre en una carpeta que figure dentro de las
rutas de bsqueda de archivos de soporte de AutoCAD. Estas rutas pueden
definirse desde el cuadro de dilogo Opciones... del men Herramientas. En caso de
duda, puede simplemente ubicarse en la carpeta SUPPORT de AutoCAD.

2000, Reinaldo Togores. Todos los derechos reservados

Figura 2. Cdigo de la Definicin del Cuadro de dilogo.

Gestin del Cuadro de Dilogo


La operacin de Cuadro de Dilogo se asegura a partir de la funcin CargaDialogo
(ver Figura 3). Lo primero que comprueba esta funcin es la existencia de una
variable global que llamamos *Posicion*. En caso que no exista se valora como
'(-1 -1). Esta variable se suministra a la funcin new_dialog y sirve para
determinar la posicin del dilogo en la pantalla. Si el usuario desplazara el Cuadro
a una nueva posicin, los valores que a ella corresponden sern devueltos al
cerrarse el dilogo mediante done_dialog y el programa almacenara las nuevas
coordenadas, de manera que al volverlo a invocar reaparecera en la ltima
posicin que ocupaba.
Una vez valorada *Posicion*, el programa comprobar que el archivo DCL est
disponible y que la definicin del Cuadro de Dilogo puede ser cargada, alertando
de cualquier error encontrado. De aparecer uno de estos mensajes, debemos
asegurarnos de haber situado el archivo DCL en la carpeta adecuada y de que no
contiene errores sintcticos.

Llenar la Casilla de Lista


En caso de que todo marche bien, se proceder a llenar la casilla de lista con los
nombres de los bloques encontrados en el dibujo. Para obtener estos nombres se
llama a la funcin ListaNombres, que reviste cierta complejidad y que ser
explicada ms abajo. Slo diremos ahora que los nombres se guardan en una lista
de asociacin compuesta por pares punteados2.
El procedimiento para llenar una lista DCL es el habitual:
x Una llamada a la funcin start_list a la que se suministra la clave (key)
asignada al componente:
(start_list "lista_bloques")
x Una invocacin de la funcin mapcar que aplica la funcin 'add_list a cada
miembro de la lista.
Aqu tenemos una variante, otra llamada a mapcar anidada en la anterior,
que tiene como objetivo crear una cadena que convertir el par punteado
("NOMBREBLOQUE" . "ATRIB") en la cadena "NOMBREBLOQUE\tATRIB".

2000, Reinaldo Togores. Todos los derechos reservados

Figura 3. Funcin CargaDialogo

Esto se logra aplicando una funcin lambda, es decir una funcin annima,
definida en tiempo de ejecucin y que desaparece una vez cumplido su
objetivo:
(mapcar 'add_list
(mapcar '(lambda (term) (strcat (car term) "\t" (cdr term)))
*listaBloques*))
Si ListaNombres devolviera una lista vaca en lugar de llenar la casilla de
lista se presentara un mensaje de error en el componente errtile:
(set_tile "error" "No hay bloques en el Dibujo Actual")
El proceso de escritura en la lista concluye con la llamada a end_list.

Estableciendo las acciones de los componentes


Una vez llena la casilla de lista se procede a asignar la accin que desencadenar
cada componente del Dilogo. La casilla de lista tendr una accin propia asignada
mediante action_tile:
(action_tile "lista_bloques" "(CompruebaAtributos $value)")
El argumento $value que se pasa a la funcin CompruebaAtributos (ver Figura 4)
contendr el ndice de la lnea sobre la que se haya pulsado el ratn, bien entendido
que a la primera lnea corresponder el valor cero. La gestin de la casilla de lista
exige conservar en memoria la lista original *listaBloques*. Para comprobar el

2000, Reinaldo Togores. Todos los derechos reservados

bloque a que corresponde la lnea pulsada se extraer el miembro de la lista que


ocupa la posicin que corresponde al ndice devuelto por $value.
CompruebaAtributos lo hace aplicando la funcin nth:
(nth (atoi valor) *listaBloques*)
El valor devuelto que es de tipo String por lo que debe convertirse en Integer
mediante la funcin atoi.
Se revisa entonces si el segundo trmino del par punteado es igual a "ATRIB". En
caso contrario, se muestra un mensaje en errtile indicando que "El bloque
seleccionado no posee atributos"

Figura 4. Funcin CompruebaAtributos.


Debemos sealar que adems de esta accin que corresponde al evento de un clic
del ratn, esta casilla tendr tambin asignada la accin del botn Aceptar que se
lanzar a partir del doble clic sobre una de sus lneas, tal como se define en el
cdigo DCL: allow_accept = true;
La accin para la tecla Aceptar se define en la funcin ExtrATT a la que se pasa
como argumento el ndice de la lnea resaltada, que se obtiene esta vez mediante la
funcin get_tile:
(action_tile "accept" "(ExtrATT (get_tile \"lista_bloques\"))")

Figura 5. Funcin ExtrATT


La funcin ExtrATT (ver Figura 5) comprobar ante todo que exista
*listaBloques*, previendo que el dibujo pueda no contener bloque alguno.
Despus comprueba que el segundo trmino del par punteado que identifica el
bloque sea "ATRIB". Si ambas verificaciones tienen xito, se lanza la funcin
Lista->Excel (CadXpress 61) que recibe como argumento la funcin SelBloque
(CadXpress 62), esta ltima modificada para eliminar la solicitud al usuario del
nombre del bloque, ya que en este caso se le pasara a partir de una seleccin en el
cuadro de dilogo. (ver Figura 6).
El botn Cancelar no tiene otra accin asignada que registrar la posicin del cuadro
de dilogo al cerrarse.

2000, Reinaldo Togores. Todos los derechos reservados

Figura 6. Funcin SelBloque.

Creando la lista de Bloques


Como hemos visto, toda la funcionalidad de este Dilogo gira en torno a la lista de
nombres de bloques *listaBloques*. Para acceder a esta informacin seguiremos
la lnea marcada en los artculos anteriores, empleando los mtodos y propiedades
de los objetos ActiveX. Para ello debemos conocer algo de la estructura de AutoCAD
como aplicacin.
AutoCAD en s mismo constituye un objeto, el objeto Aplicacin. Es a partir de este
objeto que se podr llegar a todos los componentes que integran el dibujo. Los
objetos que se incluyen en la aplicacin se cuentan por centenares. De ah que sea
necesario estructurarlos de alguna manera. Esa manera de estructurarlos es a
partir de Colecciones. Todos los dibujos abiertos en una misma sesin de trabajo
componen la Coleccin Documentos. El Documento Activo es uno de los miembros
de esa Coleccin. A su vez el Documento Activo contiene una serie de Colecciones
de Objetos.

Las Colecciones de Objetos


Una coleccin se define como un conjunto ordenado de elementos de
informacin sobre los que podemos operar como una estructura de carcter
unitario. Desde el punto de vista del programador AutoLISP, una coleccin
es en gran medida como una lista. Aunque las colecciones no tienen que
contener necesariamente el mismo tipo de dato para cada uno de sus
miembros, las colecciones de AutoCAD tienden a componerse de referencias
a objetos de tipo similar. Por ejemplo, la Coleccin "Blocks" contiene slo
objetos Bloque y la Coleccin "TextStyles" contiene slo objetos Estilo de
Texto3.
La va para obtener la coleccin "BLOCKS" ser la siguiente:
x Obtener el objeto Aplicacin AutoCAD
x Obtener su objeto Documento Activo
x Obtener del Documento Activo la Coleccin "BLOCKS"
x Extraer los nombres de los objetos que integran la coleccin.
Los dos primeros pasos se resumen en la siguiente lnea de cdigo:
(setq *EsteDibujo* (vla-get-ActiveDocument (vlax-get-acad-object)))
Esta lnea de cdigo no forma parte de una de las funciones definidas. Aparecen de
manera independiente al principio del archivo ExtrATT.LSP (ver Figura 7) junto con
la llamada a (vl-load-com)4, con lo que se valorar de inmediato en el momento
de cargar el programa.

2000, Reinaldo Togores. Todos los derechos reservados

Figura 7. Funciones de Inicializacin.


La referencia al objeto Documento Activo se guarda en la variable global
*EsteDibujo*. La funcin ListaNombres utiliza esta referencia para acceder a la
Coleccin "Blocks" (ver Figura 8). La coleccin "Blocks" es una propiedad del
objeto Documento recuperable mediante
(vlax-get-property *EsteDibujo* "Blocks")
Visual LISP suministra vlax-for, una funcin que nos permite iterar a travs de
una coleccin con la misma facilidad que lo haramos con una lista:
(vlax-for obj (vlax-get-property *EsteDibujo* "Blocks")...
De cada uno de los objetos que componen la coleccin y que recuperamos
secuencialmente, podemos obtener la propiedad "Name", es decir su nombre:
(vlax-get-property obj "Name")

Figura 8. Funcin ListaNombres.


Pero no todos los objetos recuperados a partir de la coleccin "Blocks" interesan a
los efectos de nuestro programa. Slo deseamos obtener los nombres de bloques
definidos por el usuario. Hay toda una serie de posibles objetos de tipo bloque que
debemos excluir: los llamados bloques annimos, generados y gestionados por
AutoCAD que se distinguen por poseer como primer carcter un asterisco "*", los
bloques de usuario que dependen de Referencias Externas y que se conocen por
incluir un carcter pipe (|), y las Referencias Externas en s mismas (detectados a
partir de su propiedad "IsXRef"). De ah la condicional en que se ubica el cdigo
para confeccionar la lista de bloques. Para las dos primeros casos se utiliza la
funcin wcmatch con la cadena "`**,*|*" como patrn de comparacin.

2000, Reinaldo Togores. Todos los derechos reservados

Otro aspecto que nos interesa comprobar ahora es si las Definiciones de Bloque
restantes incluyen Definiciones de Atributos5. Para ello ser necesario examinar,
una a una, las Definiciones de Bloque encontradas. Una Definicin de Bloque es
tambin una Coleccin. En este caso integrada por entidades entre las cuales
pueden encontrarse Definiciones de Atributo. La funcin TieneAtributos (ver
figura 9) recorre mediante vlax-for cada Definicin de Bloque y devuelve t
(cierto) en caso de que la propiedad "ObjectName" de alguna entidad sea
"AcDbAttributeDefinition".

Figura 9. Funcin TieneAtributos.

Implantar un nuevo Comando AutoCAD


Para terminar, sera conveniente crear un nombre para este programa que
permitiera llamarlo desde la lnea de comandos. En AutoLISP lo hacamos
definiendo una funcin cuyo nombre estuviera precedido por "C:". Ahora
disponemos de otras maneras para hacerlo. Agregamos al final del archivo
ExtrATT.LSP (ver figura 3, abajo) la siguiente lnea:
(vlax-add-cmd "AtrEX" 'CargaDialogo)
Ahora bastar teclear ATREX en la lnea de comandos para acceder al programa.
Recordemos que para probarlo debemos cargar todos los archivos que componen el
proyecto: ListaExcel.LSP, LeeAttribX.LSP y ExtrATT.LSP.

Conclusiones
Con lo publicado en este nmero completamos lo que sera el cdigo para una
aplicacin de utilidad evidente. Ms adelante abordaremos los procedimientos para
crear un proyecto que nos ayude a gestionar los diversos archivos, los aspectos a
tener en cuenta para su compilacin y el proceso mediante el cual podemos
convertir todo esto en una aplicacin ejecutable VLX.
1

El cdigo fuente puede ser descargado va Internet desde:


http://personal1.iddeo.es/ret0028o/CadXpress/
2
Listas de dos trminos del tipo que se obtiene al aplicar la funcin cons sobre dos tomos: (cons "A"
"B"), y que devuelve ("A" . "B"). Los pares punteados, tambin conocidos como CONSES se
diferencian de las verdaderas listas en una serie de aspectos, entre ellos que la funcin cdr aplicada a
un par punteado no devuelve una lista, sino un tomo. (cdr '("A" . "B")) devolvera "B", mientras
que (cdr ("A" "B")) devolver ("B").
3
Gibb, J.W. y Kramer, B. AutoCAD VBA Programming: tools and techniques. Miller-Freeman, 1999. Pg.
83. Traduccin libre de R. Togores.
4
Sobre vl-load-com ver CadXpress 60.
5
Recordemos la distincin entre Definicin de Atributo y Referencia de Atributo que hacamos en nuestro
artculo anterior (CadXpress 62).

2000, Reinaldo Togores. Todos los derechos reservados

You might also like