MÓDULO DOCE

Programación en Visual Basic orientada a AutoCAD 14 (VBA)


DOCE.1. INTRODUCCIÓN

En este MÓDULO vamos a estudiar una nueva característica muy importante a la hora de realizar programas para AutoCAD 14, la cual es la programación en Visual Basic. AutoCAD 14 proporciona una nueva interfaz de desarrollo en Visual Basic, uno de los lenguajes de programación más potentes que existen y que se está convirtiendo en un estándar a la hora de realizar programas en entorno Windows.

Si el desarrollador dispone de una versión de Visual Basic instalada en su ordenador podrá crear programas en este leguaje que, tras compilarlos, podrán correr bajo AutoCAD, siempre que sigan una normas básicas para manejar los objetos del programa. Sin embargo esto no es imprescindible, ya que el propio AutoCAD 14 implementa un módulo VBA (Visual Basic for Aplications), el cual dispone de la sintaxis completa del leguaje (en su versión 5.0), un depurador y un entorno de desarrollo integrado. De esta forma es totalmente factible crear un programa e irlo probando mientras se va depurando en una sesión de AutoCAD.

El objetivo de este MÓDULO no es explicar a fondo el lenguaje de programación Visual Basic, ya que para ello se necesitaría como mínimo un curso completo, y existen muchos y muy buenos; por ello, eso escapa a las pretensiones de este curso. Al lector se le suponen ya unos conocimientos medios o avanzados de programación en dicho lenguaje y simplemente habrá de actualizarse al manejo de los objetos incluidos en AutoCAD 14 para Visual Basic.

 

DOCE.2. Visual Basic Y ActiveX Automation

Visual Basic es la desembocadura de lo que en un principio se llamó lenguaje BASIC (Beginner's All-purpose Symbolic Instruction Code, algo así como código de instrucción simbólica para todo propósito del principiante), que fue diseñado para iniciados en EE.UU. en 1964. Fue una derivación del lenguaje FORTRAN que se caracterizaba por su sencillez de manejo y curva de aprendizaje.

Microsoft a lo largo de su historia ha venido proporcionando una serie de editores BASIC cuyos más altos exponentes sin duda fueron GWBASIC y, sobre todo, QuickBASIC. Cuando apareció Windows como entorno las cosas comenzaron a cambiar: aparecen los lenguajes visuales. La programación visual, conocida como orientada a objetos y conducida por eventos, permite desarrollar aplicaciones para Windows de una manera sencilla e intuitiva. Visual Basic, a lo largo de su historia, ha ido creciendo en importancia y potencia, llegando en muchos momentos a no tener nada que envidiar a su más temible competidor, probablemente el lenguaje visual más potente que existe: Visual C++.

Hoy en día, esta programación orientada a objetos se sirve de una de las últimas tecnologías de programación, esto es ActiveX Automation. La tecnología ActiveX, presente en las últimas versiones de Windows, supera con creces al sistema anterior OLE, proporcionando una interfaz de programación que permite manejar los objetos de una aplicación desde fuera de la misma. La intercomunicación ahora entre aplicaciones que manejen objetos ActiveX es total: nosotros seremos capaces desde un programa en Visual Basic de abrir una sesión de AutoCAD, añadir una serie de líneas a modo de tabla y, a continuación abrir una sesión en Excel, por ejemplo, para leer determinados datos, operar con ellos y volver a AutoCAD para añadir los datos a la tabla. Y todo esto mediante letreros de diálogo, botones y demás componentes típicos y sencillos de manejar de Microsoft Windows.

Los objetos propios de una aplicación son así expuestos a las demás aplicaciones como objetos Automation. En AutoCAD 14 son objetos Automation todos los objetos de dibujo, las denominadas tablas de símbolos como bloques, capas, estilos de cota, etc. y también las Preferencias. Las aplicaciones que proporcionan un entorno de programación en el que los desarrolladores o usuarios pueden escribir macros y rutinas para acceder y controlar objetos ActiveX se denominan controladores de Automation. Estos controladores pueden ser aplicaciones de Windows como Word y Excel, o entornos de programación como Visual Basic o Visual C++.

Los objetos ActiveX exponen para su control dos conceptos específicos: métodos y propiedades. Los métodos son funciones que ejercen una acción sobre los objetos. Las propiedades son funciones que definen o devuelven información sobre el estado de un objeto. Las propiedades y métodos dependen de cada tipo de objeto y se describen a través de una biblioteca de tipos. Los desarrolladores o usuarios tienen a su disposición un examinador de biblioteca de tipos, para saber en todo momento los métodos y propiedades existentes. AutoCAD 14 dispone de sus propios objetos ActiveX para ser manejados desde un programa.

La biblioteca de tipos donde se encuentran definidos los métodos y propiedades a través de los cuales expone AutoCAD sus objetos Automation se encuentra en el archivo ACAD.TLB. Las referencias se establecen desde el editor de VBA, desde el menú Herramientas>Referencias..., activando la casilla AutoCAD Object Library. Los objetos de una aplicación pueden usarse sin hacer referencia a la biblioteca de objetos, pero es preferible añadir dicha referencia por motivos de facilidad, fiabilidad y comprobación.

Es posible acceder a objetos Automation desde muchas aplicaciones de Windows. Estas aplicaciones pueden ser ejecutables independientes, archivos de bibliotecas de enlace dinámico .DLL y macros dentro de aplicaciones como Word y Excel. Mediante Automation resulta muy sencillo desarrollar y mantener una interfaz gráfica de usuario. La interfaz puede ir desde un solo cuadro de diálogo o una barra de herramientas que mejore una aplicación existente, hasta una aplicación propia completa.

 

DOCE.2.1. La línea de productos de Visual Basic

El lenguaje de programación Visual Basic como tal está dividido en diferentes productos que el usuario adquiere según sus propias necesidades. En líneas generales podemos dividir estos productos en tres grandes grupos:

— Visual Basic. Es la herramienta de más alto nivel dentro de la gama. Posee todas las características del leguaje y está dividida en cuatro ediciones: Creación de Controles (Control Creation), que permite únicamente —que no es poco— el desarrollo de controles ActiveX, por lo que no permite la creación de aplicaciones autónomas; Estándar (Learning), con acceso de alta velocidad a bases de datos y que ya sirve para el desarrollo de aplicaciones; Profesional (Professional), con herramientas avanzadas para el diseño de aplicaciones profesionales; y Empresarial (Enterprise), con todas las herramientas disponibles para desarrolladores e investigadores.

— VBA (Visual Basic for Applications). Es una herramienta menos avanzada que la anterior y diseñada para ser implementada en las distintas aplicaciones Windows y poder desarrollar programas para ellas. Incluye importantes implementaciones para macros y guiones, la casi completa sintaxis de programación Visual Basic, un depurador y un entorno de desarrollo integrado. Es la incluida en AutoCAD 14.

— VBScript (Visual Basic Scripting Edition). Es la herramienta de inferior nivel. Contiene un subconjunto del lenguaje Visual Basic, pero sin acceso a sistema operativo ni a operaciones de entrada y salida de archivos. Se ha concebido fundamentalmente como herramienta de diseño script para páginas Web de Internet en HTML (al estilo de JavaScript).

 

DOCE.3. EL MÓDULO VBA DE AutoCAD 14

Como ya se ha comentado, AutoCAD 14 proporciona un módulo VBA que es una versión preview, sin embargo podríamos decir que funciona completamente bien (en la versión 14.01 de AutoCAD ya se da una versión final del editor VBA). Este módulo no se instala en la instalación general del programa, sino que hay que hacerlo después de ella. Para este menester deberemos acudir al directorio \VBAINST\ del CD-ROM de instalación de AutoCAD 14, y ejecutar el archivo SETUP.EXE, que instalará el módulo VBA.

Una vez instalado, y tras quizá reiniciar el equipo mejor, aparecerá un nuevo menú desplegable en AutoCAD denominado VBA (entre Herr. y Dibujo). Este menú dispone de las siguientes opciones:

· Run Macro (ejecutar macro) ejecuta una macro o rutina. Debe haberse cargado previamente algún proyecto con la opción siguiente. El comando en línea de comandos es VBARUN.

· Load Project (cargar proyecto) permite cargar un nuevo proyecto (.DVB). Al cargar un proyecto existente, AutoCAD muestra el editor VBA con el contenido del proyecto (formularios, módulos de código...). El comando en línea de comandos es VBALOAD.

· Unload Project (descargar proyecto) descarga un proyecto previamente cargado. El comando en línea de comandos es VBAUNLOAD.

· Show VBA IDE (mostrar editor VBA) permite mostrar el editor de VBA. El comando en línea de comandos es VBAIDE.

NOTA: En la versión 14.01 de AutoCAD se añade un menú de persiana al menú Herr. llamado Macro.

El módulo VBA de AutoCAD 14 es ligeramente distinto al entorno Visual Basic habitual, si es que estamos familiarizados con él. En principio, por defecto el Explorador de proyectos y la Ventana de Propiedades aparecen anclados a la izquierda, y no a la derecha. El Cuadro de herramientas no aparece por ningún lado, ya que sólo se pone de manifiesto cuando estamos trabajando con un formulario.

En general la estructura de menús y barra de herramientas es muy parecida, si bien existen ausencias —sobre todo— en VBA con respecto a Visual Basic, como por ejemplo la capacidad de incluir formularios MDI, de compilar proyectos o de abrir proyectos, entre otras. Esto último se realiza desde el menú desplegable de AutoCAD, y sólo desde ahí. Decir que el módulo VBA únicamente puede ser abierto desde una sesión de AutoCAD, y no independientemente.

Todas la nuevas características se irán aprendiendo a lo largo de este MÓDULO, por lo que no debemos preocuparnos si dominamos Visual Basic y creemos no sentirnos a gusto en VBA.

Dado que, como hemos dicho, se suponen conocimientos previos por parte del lector, nos meteremos de lleno ya mismo con la programación exclusivamente dirigida a AutoCAD 14.

 

DOCE.4. COMENZANDO CON VBA

Lo primero que quizá nos haya llamado la atención es la entrada por defecto que aparece en el Explorador de proyectos: ThisDrawing, dentro de una carpeta llamada AutoCAD Objetos. El objeto ThisDrawing se refiere al documento actual activo de AutoCAD, y no puede ser eliminado. A él nos referiremos a la hora de gestionar objetos de AutoCAD, ya que siempre que hagamos algo será evidentemente referenciado y ejecutado en el documento actual activo.

Antes de comenzar a programar tenemos que asegurarnos —para evitarnos problemas posteriores— que la referencia a la librería de objetos de AutoCAD 14 (ACAD.TLB) está activada. Para ello acudiremos al menús Herramientas>Referencias....

La forma de programar en Visual Basic es muy personal, ya que hay gente que utiliza bastante los módulos de código y otra gente que incluye todo el código en el propio formulario. En AutoCAD normalmente trabajaremos con un único formulario (cuadro de diálogo) al estilo DCL + AutoLISP que realizará determinada función. Es por ello que se utilizarán muy poco los módulos de código (excepto para macros), y muchísimo menos los módulos de clase. A los programadores avanzados les puede ser muy interesante el disponer de estas características en VBA.

 

DOCE.4.1. La plantilla de objetos

Los objetos ActiveX que proporciona AutoCAD 14 para su manejo desde programas VBA están divididos según una jerarquía que deberemos seguir a la hora de llamarlos o referirnos a ellos. La plantilla que se muestra a continuación nos será muy útil a la hora de programar, ya que establece dicha jerarquía.

En Visual Basic es factible añadir al entorno nuevos objetos creados por nosotros para luego ser utilizados. Lo que se ha hecho en VBA es precisamente eso. Estos objetos tienen sus propiedades y métodos, al igual que los demás. Existen objetos de entidades individuales de dibujo (líneas, círculos, arcos...) con sus propiedades (color, capa, tipo de línea...) y métodos (copiar, mover, escalar).

También se han definido otros objetos no gráficos como son el Espacio Modelo, el Espacio Papel y los bloques. Estos se consideran una colección de objetos de entidades individuales de dibujo y tienen también sus propiedades para, por ejemplo, saber cuántas entidades simples contienen, y sus métodos para, por ejemplo, añadir nuevas entidades a la colección.

El propio documento actual de AutoCAD está definido como un objeto y tiene sus propiedades (camino de acceso, límites...) y métodos (guardar, regenerar...). Dentro de él se encuentran los mencionados anteriormente, además de otras colecciones como el conjunto de capas, de estilos de texto, etcétera, cada una con propiedades y métodos.

Y todo ello está incluido en el objeto más exterior, que es la aplicación de AutoCAD.

La plantilla que muestra toda la jerarquía se proporciona en el archivo siguiente para AutoCAD 14 (PLANTILLA.DWG), comprimido en formato ZIP aquí ---> PLANTILLA.ZIP.

 

DOCE.4.2. Empezar un programa

El primer paso que vamos a dar al realizar un programa en VBA será casi siempre el mismo, y se refiere a la declaración de las variables de objeto que serán necesarias para acceder a los distintos aspectos de AutoCAD.

Según la plantilla de la página anterior, la propia aplicación AutoCAD, el documento activo, el Espacio Modelo o el Espacio Papel, entre otros, son objetos que hemos de definir en un principio para luego poder referirnos a ellos a lo largo del programa fácilmente. Como objetos que son los declararemos como tales, así por ejemplo, la aplicación en sí la podríamos declarar así (en General_Declaraciones):

AcadApp as Object

el documento activo:

AcadDoc as Object

y el Espacio Modelo y Papel:

AcadModel as Object

y

AcadPapel as Object

Esto en sí no tiene mucho sentido hasta que no le demos unos valores coherentes. Para ello utilizaremos el procedimiento UserForm_Initialize (si nuestro programa dispone de formulario; no es una macro), ya que habrán de tomar valores al iniciar el programa, así:

Set AcadApp = GetObject(, "AutoCAD.Application")
Set AcadDoc = AcadApp.ActiveDocument
Set AcadModel = AcadDoc.ModelSpace
Set AcadPapel = AcadDoc.PaperSpace

NOTA: Como sabemos, para añadir valores a variables del tipo Object, es necesario utilizar la instrucción Set.

Como vemos, la primera línea es la que realmente hace referencia a la librería o biblioteca de objetos de AutoCAD. No se incluye el camino por encontrarse el archivo ACAD.TLB en el directorio principal de instalación de AutoCAD, esto es, por estar en directorio de archivos de soporte. Sin embargo, la coma necesaria de la función GetObject que separa los dos parámetros es imprescindible incluirla.

Las líneas restantes hacen referencia a los demás objetos que, como se ve, cuelgan todos del primero. El documento activo (ActiveDocument) cuelga directamente de la aplicación AutoCAD, y tanto el Espacio Modelo (ModelSpace) como el Espacio Papel (PaperSpace) del documento actual. Esta jerarquía la podemos apreciar perfectamente en la plantilla anteriormente expuesta.

Esta asignación de objetos no es necesaria realizarla, ya que podemos referirnos a ellos con toda la secuencia de nombres. Pero parece lógico utilizar, por ejemplo, un nombre de variable como AcadModel cada vez que nos tengamos que referirnos al Espacio Papel (que serán muchas veces), que utilizar la secuencia entera hasta ModelSpace.

Además si trabajamos directamente en VBA podemos sustituir las llamadas al documento actual por ThisDrawing así:

Set AcadDoc = ThisDrawing

o incluso utilizar ThisDrawing posteriormente en las llamadas durante el programa. El problema de esto reside en que sólo el VBA de AutoCAD sabe lo que es ThisDrawing. En el momento en que queramos abrir nuestro programa en un entorno Visual Basic externo para, por ejemplo compilarlo (que ya lo veremos), necesitaremos realizar las llamadas pertinentes a la librería de objetos, si no nunca funcionará. Es por ello que es mejor acostumbrarse a esta técnica mucho más versátil y elegante.

Todo esto es necesario porque debemos decirle a VBA que vamos a trabajar con una aplicación denominada AutoCAD, que utilizaremos el documento actual activo y, por ejemplo, su Espacio Modelo. A la hora de añadir un círculo, por ejemplo, deberemos indicar que ha de ser al Espacio Modelo del documento actual de AutoCAD, sobre todo si trabajamos con un Visual Basic externo o el archivo está ya compilado.

Se emplea en estas declaraciones la función GetObject, cuya finalidad consiste en devolver una referencia al objeto que se le solicita, en nuestro caso a AutoCAD.Application, que engloba a todo el modelo de objetos. Para que esta función responda adecuadamente es necesario que AutoCAD esté cargado y con un dibujo abierto (en la versión 14 no es posible cerrar un dibujo), que será referenciado como ActiveDocument.

 

DOCE.5. Dibujo y representación de entidades

A continuación, bajo esta sección, estudiaremos los diferentes métodos que tenemos de añadir entidades individuales de dibujo mediante programas en VBA.

La manera de dibujar entidades dice relación a métodos que pertenecen a las colecciones de Espacio Modelo, Espacio Papel y bloques (como se ve en la plantilla de objetos). Estas colecciones también tienen propiedades, pero eso lo veremos más adelante.

 

DOCE.5.1. Líneas

NOTA IMPORTANTE DE SINTAXIS: La sintaxis que se utiliza en este MÓDULO es similar a la de MÓDULOS anteriores: instrucciones, funciones, métodos, propiedades y demás términos reservados como aparecen en el editor VBA una vez aceptados; los textos en cursiva son mnemotécnicos que han de ser sustituidos por su valor; los textos no en cursiva deben escribirse coma tales; las sintaxis en colores: métodos en azul y propiedades en verde; en las listas las propiedades y métodos de objetos nuevos (sin explicar) en negrita, los ya explicados no; los listados de programas se muestran como aparecen en el editor; una barra vertical indica una dualidad de valores.

La sintaxis del método AddLine para dibujar líneas es la que sigue:

Set ObjLínea = ObjColección.AddLine(DblPtoInicial, DblPtoFinal)

Propiedades de los objetos de línea:

Application
Color
EndPoint
EntityName
EntityType
Handle
Layer
Linetype
LinetypeScale
Normal
ObjectID
StartPoint
Thickness
Visible


Métodos de los objetos de línea:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Offset
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Los objetos gráficos de dibujo hemos de declararlos previamente como tales. Para ello deberemos definir un nombre de variable que almacenará el objeto; es a lo que se refiere ObjLínea. Esta variable puede ser declarada como Object simplemente o como un objeto especial de VBA para AutoCAD que representa el tipo de objeto que almacenará. Este objeto especial tiene diferentes nombres según el objeto que almacene; su sintaxis podría definirse así: IAcadObjeto, es decir, primero la cadena fija IAcad y luego el nombre del objeto.

De esta manera, una variable que tuviera que guardar una línea podría declararse como Object o como IAcadLine. La diferencia es que si la declaramos como Object podrá almacenar cualquier objeto a lo largo del programa: una línea, un círculo, un rayo, un texto... Si la declaramos como IAcadLine esa variable única y exclusivamente podrá almacenar entidades de línea de AutoCAD 14, una o varias a lo largo de la ejecución, pero sólo líneas. Es recomendable hacerlo con la primera opción (Object), sino a veces hay problemas.

Las entidades de AutoCAD, para ser dibujadas desde VBA, han de ser guardadas en una variable de objeto, por lo tanto con Set. Veremos casi al final de este MÓDULO que esto no es rigurosamente cierto. Por ahora lo haremos así.

ObjColección se refiere a la colección donde se almacenará la línea, es decir, si se dibujará en Espacio Modelo o Espacio Papel, o si formará parte de un bloque. Los puntos inicial y final de la línea (DblPtoInicial y DblPtoFinal) deben ser agrupaciones de tres coordenadas (X, Y, y Z), por lo tanto han de definirse como matrices (arrays o tablas) de tres elementos, cada uno de ellos de tipo Double, generalmente.

Para realizar nuestra primera prueba de dibujo de una línea crearemos una macro que así lo haga. Una macro en VBA se crea y se añade automáticamente al módulo estándar de código existente si existe, si no existe se crea una nuevo. La macro se ejecutará sin necesidad de letrero de diálogo.

Para crear un macro VBA lo haremos desde el menú Herramientas>Macros.... Esto abre un cuadro que permite introducir un nombre para la nueva macro (también se puede eliminar, editar o ejecutar una existente). Tras pulsar el botón Crear se añadirá un nuevo procedimiento Sub al módulo de código existente (o se creará uno). Dicho procedimiento tendrá el nombre de la macro. Para ejecutar una macro podemos hacerlo desde el mismo cuadro de creación (eligiendo una) o desde el menú de AutoCAD VBA>Run Macro..., esto último arranca un cuadro de diálogo que permite elegir el módulo estándar en cuestión donde se encuentra la macro y la macro por su nombre (en el caso de que hubiera varias dentro de un mismo módulo).

Creemos pues una macro llamada DibujoLínea. A continuación añadiremos las siguientes líneas de código:

NOTA: Cuidado con lo que va tras General_Declaraciones (siempre hasta la primera línea de división) y el resto (en estos casos se muestra el nombre de procedimiento Sub en el encabezado).

Option Explicit
Dim AcadDoc As Object
Dim AcadModel As Object
Dim ObjLínea As IAcadLine
Dim PuntoInicial (1 To 3) As Double
Dim PuntoFinal (1 To 3) As Double


Sub DibujoLínea()
  Set AcadDoc = GetObject( ,"Autocad.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace
  PuntoInicial(1) = 100: PuntoInicial(2) = 100: PuntoInicial(3) = 0
  PuntoFinal(1) = 200: PuntoFinal(2) = 200: PuntoFinal(3) = 0
  Set ObjLínea = AcadModel.AddLine(PuntoInicial, PuntoFinal)
End Sub

NOTA: Como en la mayoría de los programas en Visual Basic se recomienda el uso de Option Explicit para depurar errores en tiempo de corrida.

Lo primero que hacemos en General_Declaraciones, tras Option Explicit que nos obliga a declarar todas las variables utilizadas, es definir o declarar las variables que vamos a usar. La que representa al documento actual y la del Espacio Modelo, como ya se había explicado; la que contendrá la línea, como un objeto de línea de AutoCAD; y las del punto inicial y final de la línea, como matrices del tipo Double.

En el cuerpo de la macro propiamente dicha se asigna su valor a cada variable, tanto a las de la aplicación y el dibujo actual, como a los puntos inicial y final. Por fin se utiliza el método explicado para dibujar la línea en el Espacio Modelo. Solo habremos de correr la macro por alguno de los métodos explicados para comprobar el resultado.

NOTA: Existen los correspondientes objetos IAcadModelSpace e IAcadDocument, pero se recomienda la sintaxis utilizada en el ejemplo para estos objetos.

La ventaja que lleva implícita el almacenamiento en una variable de objeto de la entidad dibujada, dice relación a su posterior utilización para la aplicación de propiedades. Ahora no es necesario (como hacíamos en AutoLISP) acceder a la Base de Datos interna de AutoCAD para modificar las propiedades de un objeto, ya que dichas propiedades se relacionan directamente con sus objetos. Así por ejemplo, si tras trazar la línea del ejemplo anterior quisiéramos cambiarla al color rojo, únicamente deberíamos añadir la siguiente línea al programa (tras Set ObjLínea...):

ObjLínea.Color = 1

Color es una propiedad de la línea (véase en la lista tras la sintaxis), por lo que lo único que hacemos es cambiarle el valor como a cualquier otra propiedad en Visual Basic: indicando el objeto, seguido de un punto de separación, la propiedad, un signo de igual y el nuevo valor. Así de simple. Algunas propiedades se tratan de otra forma.

A continuación se explican a fondo cada una de las propiedades de los objetos de línea. Se explican de manera ambigua, es decir, sin referirse a las líneas en sí, ya que estas propiedades son comunes a muchos otros objetos VBA.

· Application. Obtiene el objeto Application de la entidad. Este objeto representa la aplicación de AutoCAD. La sintaxis es:

Set ObjAplicación = ObjGráfico.Application

siendo ObjAplicación una variable definida como Object y ObjGráfico un objeto gráfico. En el caso de nuestro ejemplo anterior de dibujo de una línea, ObjGráfico sería la variable ObjLínea.

· Color. Obtiene y/o asigna el color de/a una entidad. El color se representa como un número entero de 0 a 256 (colores de AutoCAD). También se pueden emplear algunas constantes predefinidas como:

AcByBlock
AcByLayer
AcCyan
AcRed
AcBlue
AcYellow
AcMagenta
AcGreen
AcWhite

La sintaxis para esta propiedad es

ObjGráfico.Color = IntNumColor

Siendo IntNumColor el número de color o alguna de las constantes. Esta es la forma en que hemos cambiado el color a nuestra línea en el ejemplo. Existe otra sintaxis para obtener el color de un objeto dibujado y guardado en una variable:

IntNumColor = ObjGráfico.Color

donde IntNumColor es ahora la variable (tipo Integer) que guardará el número de color y ObjGráfico la variable (tipo Object) que almacena la línea. En nuestro caso anterior la línea estaba almacenada en ObjLínea (tipo IAcadLine). Si quisiéramos objeter su color y guardarlo en una variable denominada NúmeroColor habríamos de hacer, por ejemplo:

NúmeroColor = ObjLine.Color

Antes de esto, y si existe una instrucción Option Explicit, habremos de declarar la variable NúmeroColor como Integer.

NOTA: Recordemos que el color 0 es PorBloque y el color 256 PorCapa.

· EndPoint. Obtiene el punto final de un objeto arco, elipse o línea y, en el caso de las líneas, también puede asignarse. Así pues, la sintaxis para obtener el punto final de los objetos mencionados es:

VarPtoFinal = ObjGráfico.EndPoint

siendo VarPtoFinal una variable que almacena un punto. Estas variables de punto siempre han de definirse como Variant. En el caso de nuestra línea podríamos haber obtenido su punto final así, aunque esto no tiene mucho sentido (como con el color) porque ya sabemos su punto final; se lo hemos dado nosotros.

Si lo que deseamos es asignar un punto final (sólo para líneas) utilizaremos la siguiente sintaxis:

ObjLínea.EndPoint = DblPtoFinal

donde ObjLínea es una variable tipo objeto que contiene una línea y DblPtoFinal es una variable que contiene un punto, es decir una matriz de tres valores tipo Double.

· EntityName. Obtiene el nombre de un objeto. Este nombre es el que la clase a la que pertenece el objeto. En concreto se refiere al código 100 en la definición de la entidad en Base de Datos cuando accedíamos con AutoLISP, y no al código 0 que es el que utilizábamos nosotros para obtener el nombre de la entidad. La sintaxis de obtención de un nombre es:

StrNombre = ObjGráfico.EntityName

donde ObjNombre es una variable de tipo String que guardará el nombre del objeto, y ObjGráfico es la variable que guarda el objeto. Si en el ejemplo de nuestra línea, y tras definir una variable llamada por ejemplo NombreLínea como String, escribiríamos al final:

NombreLínea = ObjLínea.EntityName


NombreLínea
guardaría la cadena AcDbLine, nombre de clase del objeto de entidad línea.

Cuando se pregunta por objetos de AutoCAD se puede emplear la siguiente propiedad EntityType.

· EntityType. Obtiene el tipo de entidad. Éste ha de ser guardado en una variable de tipo Integer así:

IntNumTipo = ObjGráfico.EntityType

El número de tipo devuelto se corresponde con los expuestos en la siguiente tabla:


Tipo de entidad Descripción
1 AcDB3DFace 2 AcDB3DPolyLine 3 AcDB3DSolid 4 AcDBArc 5 AcDBAttribute 6 AcDBAttributeReference 7 AcDBBlockReference 8 AcDBCircle 9 AcDBDimAligned 10 AcDBDimAngular 11 AcDBDimDiametric 12 AcDBDimOrdinate 13 AcDBDimRadial 14 AcDBDimRotated 15 AcDBEllipse 16 AcDBGroup 17 AcDBHatch 18 AcDBLeader 19 AcDBLine 20 AcDBMText 21 AcDBPoint 22 AcDBPolyline 23 AcDBPolylineLight 24 AcDBPolyMesh 25 AcDBPViewPort 26 AcDBRaster 27 AcDBRay 28 AcDBRegion 29 AcDBShape 30 AcDBSolid 31 AcDBSpline 32 AcDBText 33 AcDBTolerance 34 AcDBTrace 35 AcDBXLine

En nuestro ejemplo, una sentencia de este tipo nos devolvería en código 19.

· Handle. Obtiene el rótulo o código del objeto. Se trata de una cadena de texto que identifica el objeto durante toda la vida de ese objeto en el dibujo. Existe otra manera de identificar una entidad, mediante su ObjectID (visto más adelante). Algunas funciones de ARX requieren un ObjectID en lugar de Handle. Para los demás casos es preferible usar Handle. La sintaxis pues de esta propiedad es:

StrRótulo = ObjGráfico.Handle

StrRotulo es una cadena (String).

· Layer. Permite obtener y/o asignar la capa de/a un objeto. La sintaxis para asignar una capa a un objeto ya dibujado es:

ObjGráfico.Layer = StrNombreCapa

donde ObjGráfico es la variable que guarda el objeto y StrNomCapa una cadena de texto con el nombre de una capa existente. Si la capa no existe VBA proporciona un error de ejecución. Para evitar eso habría que crearla previamente con un método que veremos bastante más adelante. En nuestro ejemplo de la línea, si existiera una capa llamada CUERPO en el dibujo actual y hubiésemos querido colocar o introducir dicha línea en esa capa, habríamos hecho:

ObjLínea.Layer = "Cuerpo"

La sintaxis para obtener la capa de un objeto es:

StrNomCapa = ObjGráfico.Layer

StrNomCapa habrá de ser una variable del tipo String, es decir una cadena alfanumérica.

· Linetype. Permite obtener y/o asignar un tipo de línea de/a una entidad de dibujo. Para asignar un tipo de línea:

ObjGráfico.Linetype = StrNombreTipoLínea

siendo ObjGráfico el objeto en cuestión (como nuestra línea en ObjLínea) y StrNomTipoLínea una cadena que especifica el nombre del tipo de línea. Si éste no está cargado se producirá un error (cómo cargar tipos de línea se verá más adelante). Como tipos de línea especiales se pueden indicar:

ByLayer
ByBlock
Continuous

Para obtener el tipo de línea de un objeto:

StrNomTipoLínea = ObjGráfico.Linetype

StrNomTipoLínea será una cadena (String).

· LinetypeScale. Obtiene y asigna la escala de tipo de línea de/a un objeto. Para asignar:

ObjGráfico.LinetypeScale = RealEscalaTipoLínea

RealEscalaTipoLínea es el valor de la nueva escala.

Para obtener:

RealEscalaTipoLínea = ObjGráfico.LinetypeScale

RealEscalaTipoLínea es una variable positiva y real del tipo Double.

· Normal. Obtiene y asigna la normal de/a una entidad. La normal es un vector unitario que indica la dirección Z en el SCE (Sistema de Coordenadas de la Entidad). El vector se almacena en una variable del tipo Variant, que recogerá una matriz de tres elementos Double. Para asignar una normal:

ObjGráfico.Normal = DblVector

Para obtener una normal:

VarVector = ObjGráfico.Normal

· ObjectID. Extrae el identificador interno de una entidad. Este número, devuelto en notación decimal, se corresponde con el valor hexadecimal que aparecía tras Entity name en la definición de una entidad en Base de datos cuando accedíamos con AutoLISP; el número del código –1. Para obtenerlo:

LngNúmeroID = ObjGráfico.ObjectID

Donde LngNúmeroID es una variable que habrá sido declarada como Long.

· StartPoint. Funciona igual que EndPoint pero para el punto inicial de líneas, arcos y elipses. En estos dos último casos sólo se puede obtener su valor; con las líneas se puede modificar. Para asignar un nuevo punto inicial a una línea la sintaxis es:

ObjLínea.StartPoint = DblPtoInic

Donde ObjLínea sólo puede ser un objeto de línea exclusivamente y DblPtoInic una variable que almacene un punto o una matriz de tres valores tipo Double.

Para obtener el punto inicial de los objetos mencionados:

VarPtoInic = ObjLínea.StartPoint

VarPtoInic habrá sido declarada como Variant.

· Thickness. Obtiene y/o asigna un valor que representa la altura en Z de un objeto 2D. Para asignar, la sintaxis es la siguiente:

ObjGráfico.Thickness = DblAlturaObjeto

y para obtener la elevación de un objeto:

DblAlturaObjeto = ObjGráfico.Thickness

DblAlturaObjeto habrá sido declarada como Double.

· Visible. Obtiene y/o asigna la visibilidad de/a una entidad. Esta propiedad es del tipo Boolean, por lo que sus resultados sólo podrán ser True o False. Si queremos asignar un estado de visibilidad a un objeto utilizaremos la siguiente sintaxis:

ObjGráfico.Visible = BooEstadoVis

Por ejemplo, en el caso de la macro que dibujaba una línea, si al final del cuerpo de la macro (antes de End Sub) escribiéramos:

ObjLínea.Visible = False

y la ejecutáramos, la línea se habría dibujado, pero permanecería invisible. A veces puede ser interesante mantener objetos invisibles para mostrarlos en un momento dado.

Si queremos extraer el estado de visibilidad de un objeto utilizaremos la sintaxis que sigue:

BooEstadoVis = ObjGráfico.Visible

donde BooEstadoVis habrá sido declarado, como norma general, como Boolean.

A parte de las propiedades, los nuevos objetos VBA para AutoCAD 14 también poseen métodos. Veremos a continuación todos los métodos para las líneas uno por uno.

NOTA: Al igual que para las propiedades, los métodos de los objetos son muchos de ellos comunes, por lo que nos referiremos aquí a ellos como globales, no como particulares de la creación de líneas.

· ArrayPolar. Este método crea una matriz polar del objeto indicado, especificando un centro, los grados abarcados y el número de objetos. La sintaxis de este método es la siguiente:

VarMatriz = ObjGráfico.ArrayPolar(IntNúmero, DblÁngulo, DblCentro)

Donde VarMatriz ha de ser una variable declarada como Variant que guardará todos los objetos de la matriz o array. ObjGráfico es el objeto ya creado del que se realizará la matriz polar, IntNúmero es el número de objetos de la matriz (Integer), DblÁngulo los ángulos cubiertos en radianes (Double) y DblCentro el centro de la matriz (un punto de tres elementos Double).

Así, y retomando el ejemplo que hemos visto de dibujo de una línea, veámoslo ampliado a continuación:

Option Explicit
Dim AcadDoc As Object
Dim AcadModel As Object
Dim ObjLínea As Object
Dim PuntoInicial (1 To 3) As Double
Dim PuntoFinal (1 To 3) As Double
Dim MatrizLin As Variant
Dim PuntoBase (1 To 3) As Double


Sub DibujoLínea()
  Set AcadDoc = GetObject( ,"Autocad.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace
PuntoInicial(1) = 100: PuntoInicial(2) = 100: PuntoInicial(3) = 0 PuntoFinal(1) = 200: PuntoFinal(2) = 200: PuntoFinal(3) = 0 Set ObjLínea = AcadModel.AddLine(PuntoInicial, PuntoFinal) PuntoBase(1) = 10: PuntoBase(2) = 10: PuntoBase(3) = 0 MatrizLin = ObjLínea.ArrayPolar(10, 3.14159, PuntoBase) End Sub

En este nuevo ejemplo, a parte de lo anterior se declara la variable MatrizLin como Variant y PuntoBase como una tabla de tres valores Double. Después se realiza la matriz (tras dar valores a PuntoBase). El número de elementos y los ángulos cubiertos pueden ser también variables, evidentemente declaradas como Integer y Double respectivamente.

Podemos acceder a la tabla que guarda los objetos mediante índices para obtener los propios objetos de la matriz. En el ejemplo anterior, únicamente deberemos añadir las siguientes dos líneas al listado (antes de End Sub):

Dim Línea6 As Object
Set Línea6 = MatrizLin(6)

para guardar en la variable Línea6 la sexta de las líneas de la matriz en este caso. Esta variable tiene que ser declarada como Object porque va a guardar un objeto. Además el índice habrá de ser coherente con el número de objetos claro está, sino se produce un error de ejecución en el módulo VBA.

· ArrayRectangular. Este método crea una matriz polar de dos o tres dimensiones repitiendo el objeto al que se le aplica. Hay que indicar el número de filas, columnas y niveles, así como las distancias correspondientes, de la siguiente manera:

VarMatriz = ObjGráfico.ArrayRectangular(IntNúmFil, IntNumCol, IntNumNiv,
DblDistFil
, DblDistCol, DblDistNiv)

Los números de filas, columnas y niveles serán enteros (Integer) y las distancias lo más lógico es que sean de doble precisión (Double).

Las demás consideraciones, así como la manera de acceder a los objetos simples de la matriz, son las mismas que para ArrayPolar.

· Copy. Método que copia la entidad a la que se aplica en la misma posición que el objeto original. Su sintaxis es simplemente:

Set ObjCopia = ObjGráfico.Copy

ObjCopia será un objeto, por lo que estará definido como tal. Para copiar la línea sexta de la matriz del último ejemplo, la cual habíamos guardado en Línea6, haríamos por ejemplo:

Dim Copia6 As Object
Set Copia6 = Línea6.Copy

Para copiar un objeto y moverlo a su vez, utilizaremos primero este método y luego el método Move, que veremos después.

· Erase. Elimina la entidad a la que se aplica el método. Como en este caso no hemos de guardar objeto ni valor alguno en ninguna variable, podemos llamar al método con Call, pero al no necesitar argumentos no hace falta. Su sintaxis es pues:

ObjGráfico.Erase

Para borrar por ejemplo la línea sexta, del ejemplo que venimos manejando, guardada en Línea6 haremos:

Línea6.Erase

· GetBoundingBox. Este método devuelve las coordenadas inferior izquierda y superior derecha de la caja de abarque del objeto al que se le aplique. Esta caja de abarque es el rectángulo que se ajusta al objeto abarcándolo por completo. La sintaxis de GetBoundingBox es:

Call ObjGráfico.GetBoundingBox(VarInfIzq, VarSupDcha)

La forma de trabajar este método es un poco extraña. VarInfIzq y VarSupDcha han de ser forzosamente dos variables declaradas, antes de llamar al método, como Variant. Al final de la ejecución guardarán las coordenadas en cuestión. Si deseamos ahora utilizar esos puntos para por ejemplo dibujar una línea, no podremos utilizarlos como tales, sino que habremos de realizar un trasvase de variables e introducir los diferentes valores en una matriz de tres elementos. Veamos una ampliación más de nuestro ejemplo de la línea:

Option Explicit
Dim AcadDoc As Object
Dim AcadModel As Object
Dim ObjLínea As Object
Dim PuntoInicial (1 To 3) As Double
Dim PuntoFinal (1 To 3) As Double
Dim MatrizLin As Variant
Dim PuntoBase (1 To 3) As Double


Sub DibujoLínea()
  Set AcadDoc = GetObject( ,"Autocad.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace
  
  PuntoInicial(1) = 100: PuntoInicial(2) = 100: PuntoInicial(3) = 0
  PuntoFinal(1) = 200: PuntoFinal(2) = 200: PuntoFinal(3) = 0
  Set ObjLínea = AcadModel.AddLine(PuntoInicial, PuntoFinal)
  PuntoBase(1) = 10: PuntoBase(2) = 10: PuntoBase(3) = 0
  MatrizLin = ObjLínea.ArrayPolar(10, 3.14159, PuntoBase)
  Dim Línea6 As Object
  Set Línea6 = MatrizLin(6)
 
  Dim EsqInfIzq As Variant
  Dim EsqSupDch As Variant
  Call Línea6.GetBoundingBox(EsqInfIzq, EsqSupDch)
  Dim Pto1 (1 To 3) As Double
  Dim Pto2 (1 To 3) As Double
  Pto1(1) = EsqInfIzq(0): Pto1(2) = EsqInfIzq(1): Pto1(3) = EsqInfIzq(2)
  Pto2(1) = EsqSupDch(0): Pto2(2) = EsqSupDch (1): Pto2(3) = EsqSupDch(2)
  Set ObjLínea = AcadModel.AddLine(Pto1, Pto2)
End Sub

Véase cómo se realiza el trasvase de variables. En el caso de las variables Pto1 y Pto2, las hemos definido con un rango de 1 a 3, sin embargo en EsqInfIzq y EsqSupDch se utiliza el rango 0 a 2, por lo que los índices están desfasados una unidad.

NOTA: Este mecanismo lo deberemos utilizar bastantes veces, como veremos. Inexplicablemente los puntos guardados en variables Variant, que da la casualidad de que son las variables de salida de métodos como este visto u otros más importantes (como el equivalente al GETPOINT de AutoLISP, que ya estudiaremos), no pueden ser utilizados directamente para, por ejemplo, dibujar entidades. Aspecto que debe solucionarse.

· GetXData. Permite recuperar los datos extendidos de una entidad. Su sintaxis es la que sigue:

Call ObjGráfico.GetXData(StrNomAplicación, VarTipoXDato, VarValorXDato)

Los datos extendidos no los crea AutoCAD sino una aplicación AutoLISP o ADS. Si embargo, estos datos se almacenan en la base de datos con los restantes del dibujo.

StrNomAplicación es el nombre de la aplicación que ha creado los datos extendido; es una cadena (String). Si se especifica un cadena vacía se devuelven todos los datos extendidos de todas las aplicaciones.

VarTipoXDato y VarValorXDato son obligatoriamente dos variables de salida definidas como Variant antes de llamar al método. Esta variables almacenarán un array de códigos de tipo de datos y un array con el tipo de dato para cada código respectivamente.

· Highlight. Asigna lo que se denomina puesta en relieve de una entidad, es decir, su resalte o designación (línea de trazos en lugar de continua). La sintaxis es la siguiente:

ObjGráfico.Highlight(BooRelieve)

BooRelieve es Boolean. El valor True hace que la entidad se resalte y False que no se resalte. A veces puede ser necesario realizar una regeneración o utilizar el método Update para que los resultados sean visibles. La mayoría de las veces no hace falta.

· IntersectWith. Calcula todos los puntos de intersección de dos entidades y los devuelve en forma de matriz de puntos. La sintaxis es:

VarMatrizPtos = ObjGráfico1.IntersectWith(ObjGráfico2, OpciónExt)

Se indican los objetos gráficos con los que se desea calcular las intersecciones y una opción de extensión cuyos valores son:

Opción			Descripción


AcExtendNone No se prolonga ninguna entidad AcExtendThisEntity Se prolonga ObjGráfico1 AcExtendOtherEntity Se prolonga ObjGráfico2 AcExtendBoth Se prolongan ambas entidades

El resultado es una matriz de valores de puntos tipo Variant. Si no hay puntos de intersección, su valor es nulo.

· Mirror. Produce una simetría de la entidad en cuestión con respecto a un eje de siemetría que viene definido por dos puntos, ambos arrays de tres elementos tipo Double. El valor devuelto es un nuevo objeto simétrico al inicial (variable tipo Object). La sintaxis de este método es:

Set ObjSimétrico = ObjGráfico.Mirror(DblPto1, DblPto2)

Los objetos no originales no son eliminados y, si deseáramos hacerlo, deberíamos utilizar el método Erase tras la ejecución de la simetría.

NOTA: Recordemos la función de la variable MIRRTEXT a la hora de hacer simetrías de textos. Veremos más adelante cómo dar valores a variables de sistema de AutoCAD 14.

Veamos un ejemplo de este método:

Option Explicit

Dim AcadDoc As Object
Dim AcadModel As Object
Dim ObjLínea As Object
Dim PuntoInicial(1 To 3) As Double
Dim PuntoFinal(1 To 3) As Double
Dim PuntoSim(1 To 3) As Double
Dim SimLin As Object


Sub DibujoLínea()
  Set AcadDoc = GetObject(, "Autocad.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace

  PuntoInicial(1) = 100: PuntoInicial(2) = 100: PuntoInicial(3) = 0
  PuntoFinal(1) = 200: PuntoFinal(2) = 200: PuntoFinal(3) = 0
  Set ObjLínea = AcadModel.AddLine(PuntoInicial, PuntoFinal)
  PuntoSim(1) = 200: PuntoSim (2) = 100: PuntoSim (3) = 0
  Set SimLin = ObjLínea.Mirror(PuntoFinal, PuntoSim)
End Sub

En este ejemplo, tras dibujar una línea se realiza una simetría de la misma, apoyándonos en un punto propio de la línea origen y en otro recién creado.

· Mirror3D. De manera similar al método anterior, Mirror3D produce una simetría tridimensional de un objeto con respecto a un plano definido por tres puntos. Los tipos de datos son iguales que en Mirror. Veamos la sintaxis de Mirror3D:

Set ObjSimétrico3D = ObjGráfico.Mirror3D(DblPto1, DblPto2, DblPto3)

· Move. Se utiliza para desplazar un objeto apoyándose en un punto de base que se moverá a otro punto indicado. Ambos puntos son matrices de tres elementos del tipo Double. Como no obtenemos ningún objeto, matriz de puntos o valor como devolución, sino simplemente un desplazamiento, deberemos llamar al método con Call.

La sintaxis de este método es:

Call ObjGráfico.Move(DblPto1, DblPto2)

Si en el último ejemplo hubiésemos querido desplazar el objeto simétrico, llevando el segundo punto del eje de simetría al último punto de la primera línea, habríamos añadido el siguiente renglón tras la simetría:

Call SimLin.Move(PuntoSim, PuntoFinal)

· Offset. Este método crea un copia paralela o equidistante a un objeto y según una distancia dada. La copia será un matriz de objetos Variant; lo más lógico es que la distancia sea una variable Double (si es variable y no se indica directamente un valor, claro está):

VarEquidist = ObjGráfico.Offset(DblDistancia)

Para acceder posteriormente a cada objeto podemos utilizar la técnica de las matrices.

· Rotate. Gira el objeto en cuestión con respecto a un punto base (tabla o array de tres elementos Double) y según un ángulo indicado en radianes (Double). Su sintaxis es:

Call ObjGráfico.Rotate(DblPtoBase, DblÁngulo)

Para girar, por poner un ejemplo, la simetría que hemos movido en el ejemplo anterior, añadiremos al código del programa:

Call SimLin.Rotate(PuntoFinal, (3.14159 / 2))

· Rotate3D. Al igual que Rotate gira un entidad, esta vez en el espacio 3D y tomando como eje de giro el que determinan dos puntos. Los tipos de datos son los mismos. Su sintaxis es:

Call ObjGráfico.Rotate3D(DblPto1, DblPto2, DblÁngulo)

· ScaleEntity. Aplica un factor de escala al objeto con el cual esté asociado y a partir de un punto base indicado. El tipo de dato de la escala dependerá de nuestra conveniencia, pero es lógico que sea Double. Su sintaxis es la que sigue:

Call ObjGráfico.ScaleEntity(DblPtoBase, DblFactorEscala)

· SetXData. Permite asignar datos extendidos a una entidad. Se suministra un array Integer con el código para cada tipo de dato y un array Variant con los datos, así:

Call ObjGráfico.SetXData(IntTipoXDato, VarValorXDato)

· TransformBy. Mueve, escala y gira el objeto mediante una matriz de transformación de 4Ž 4. Los elementos de la matriz son de tipo Double y deben tener una disposición concreta:

R00	R01	R02	T0
R10	R11	R12	T1
R20	R21	R22	T2
0	0	0	1

La rotación se indica en la submatriz 3Ž3 que lleva la letra R, y en la columna marcada con T se indica la traslación. También en la submatriz de 3Ž3 es donde se indica el factor de escala. La sintaxis de TransformBy es:

Call ObjGráfico.TransformBy(DblMatriz)

· Update. Actualiza el objeto al que se le aplica, que puede ser una entidad o incluso todo el dibujo. Su sintaxis es la que sigue:

ObjGráfico.Update

Realizar una actualización del un objeto puede ser necesario en determinadas ocasiones en que una operación en cuestión no produce el efecto deseado hasta que se actualiza.

Si quisiéramos por ejemplo actualizar la primera línea dibujada del ejemplo que venimos manejando hasta ahora haríamos:

ObjLínea.Update

Si lo que queremos es actualizar la aplicación, habríamos de definir un objeto así por ejemplo:

Dim AcadApp As Object

para darle un valor así:

Set AcadApp = GetObject(, "AutoCAD.Application")

y luego:

AcadApp.Update

En este caso declararíamos el objeto de documento activo simplemente así:

Set AcadDoc = AcadApp.ActiveDocument

Después de estudiar todas las propiedades y todos los métodos del objeto de línea, pasaremos ahora a ver los demás métodos de las estas colecciones existentes para la creación de objetos o entidades gráficas de dibujo desde VBA. Muchas propiedades y/o métodos son comunes a todos los objetos gráficos, por lo que, de aquí en adelante, únicamente se expondrán aquellos que no se hayan visto ya. Es decir, iremos aprendiendo las características nuevas de cada objeto gráfico sino se han visto con anterioridad en otro. Aún así, de cada objeto se proporcionan listadas todas sus propiedades y listados sus métodos, resaltando en negrita los que se explican en la sección en curso.

 

DOCE.5.2. Círculos

El método AddCircle permite dibujar círculos en la colección de objetos de Espacio Modelo, Espacio Papel o formando parte de un bloque. Hay que indicar las coordenadas del punto del centro, que será un matriz de tres elementos (coordenadas X, Y y Z) de tipo de dato Double, y el radio del círculo, que también será Double. La sintaxis de AddCircle es:

Set ObjCírculo = ObjColección.AddCircle(DblCentro, DblRadio)

Propiedades de los objetos de círculo:

Application
Area
Center
Color
EntityName
EntityType
Handle
Layer
Linetype
LinetypeScale
Normal
ObjectID
Radius
Thickness
Visible

Métodos de los objetos de círculo:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Offset
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Como podemos observar, los métodos son los mismos que para las líneas. En cuestión de propiedades desaparecen dos evidentemente (StartPoint y EndPoint) y aparecen Area, Radius y Center, que son las que vamos a comentar a continuación.

· Area. Obtiene el área de una entidad cerrada (círculo, elipse, arco, polilínea, región o spline). La variable que guarde el dato de salida habrá sido declarado como Double. La sintaxis de esta propiedad es:

DblÁrea = ObjGráfico.Area

· Center. Obtiene y asigna el centro de la entidad. La sintaxis para asignar un nuevo centro es:

ObjGráfico.Center = DblPtoCentro

siendo DblPtoCentro un array de tres elementos Double que guarda las coordenadas X, Y y Z del nuevo centro. Para obtener el centro utilizaremos la sintaxis siguiente:

VarPtoCentro = ObjGráfico.Center

donde VarPtoCentro será una variable declarada como Variant que guardará las coordenadas del centro. Recordemos que para utilizar luego estás coordenadas, a la hora de suministrarlas como puntos de dibujo para objetos gráficos, habrá que realizar un trasvase de variables y guardarlas en una matriz o array de tres elementos tipo Double.

· Radius. Obtiene y asigna el radio de un círculo (o de un arco). El valor en cuestión, tanto uno nuevo para asignar como el que recogerá una variable al obtener, será del tipo Double. Por lo que si se utilizan variables (al obtener seguro, pero el asignar no es obligatorio) deberán declararse como de doble precisión.

La sintaxis para asignar un radio es:

ObjGráfico.Radius = DblRadio

y la sintaxis para obtener el radio de una entidad ya dibujada es:

DblRadio = ObjGráfico.Radius

En el siguiente pequeño programa se crea un sencillo cuadro de diálogo (formulario en Visual Basic) que permite, mediante una serie de casillas de edición y un botón de acción, dibujar un círculo en el Espacio Modelo o Espacio Papel, según el botón excluyente que esté activado. El cuadro de diálogo es el siguiente:

El listado del código es el que sigue:

Option Explicit

Dim AcadDoc As Object
Dim AcadModel As Object
Dim AcadPapel As Object
Dim DibujoEn As Object
Dim CírculoObj As Object
Dim PtoCentro(1 To 3) As Double
Dim Radio As Double


Private Sub buttonDibujar_Click()
  PtoCentro(1) = Val(boxX.Text)
  PtoCentro(2) = Val(boxY.Text)
  PtoCentro(3) = Val(boxZ.Text)
  Radio = Val(boxRadio.Text)
  formPrincipal.Hide

  If optionModelo.Value = True Then
    Set DibujoEn = AcadModel
  Else
    Set DibujoEn = AcadPapel
  End If
  Set CírculoObj = DibujoEn.AddCircle(PtoCentro, Radio)
  End
End Sub


Private Sub UserForm_Initialize()
  Set AcadDoc = GetObject(, "AutoCAD.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace
  Set AcadPapel = AcadDoc.PaperSpace
End Sub

Como vemos, tras inicializar todas las variables se muestra el cuadro. La acción al pulsar el botón Dibujar (buttonDibujar es su nombre) pasa por extraer los valores de las casillas de coordenadas (boxX, boxY y boxZ), pasarlos a valores numéricos e introducirlos en la matriz que será el punto centro del círculo. También se realiza lo mismo con el radio (casilla boxRadio). Por último se dibuja el círculo en el Espacio Modelo o en el Espacio Papel según el valor de la variable de objeto DibujoEn, que lo que hace es almacenar un objeto u otro (Modelo o Papel) según qué botón excluyente o de opción esté marcado (optionModelo u optionPapel).

NOTA: Se podrían haber introducido también diversos controles de errores.

 

DOCE.5.3. Elipses

El método AddEllipse permite dibujar elipses o arcos de elipse en la colección de objetos de Espacio Modelo, Espacio Papel o en la colección de bloques. La sintaxis de AddEllipse es:

Set ObjElipse = ObjColección.AddElipse(DblCentro, DblPtoEjeMayor, DblRelación)

El centro ha de indicarse como una matriz de elementos Double (DblCentro); DblPtoEjeMayor es un punto (matriz de tres valores Double) en uno de los extremos del eje mayor, considerando las coordenadas en el SCO y relativas al centro; DblRelación es un valor Double que es la relación entre la medida del eje menor y del eje mayor (valor máximo igual a 1 se corresponde con un círculo).

Propiedades de los objetos de elipse:

Application
Area
Center
Color
EndAngle
EndParameter

EndPoint
EntityName
EntityType
Handle
Layer
LineType
LinetypeScale
MajorAxis
MinorAxis
Normal
ObjectID
RadiusRatio
StartAngle
StartParameter
StartPoint
Visible

Métodos de los objetos de elipse:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Offset
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Los métodos son los mismos que lo ya estudiados, pero hay propiedades nuevas.

· EndAngle. Obtiene y/o asigna el ángulo final en radianes de un objeto elipse (o arco). El ángulo se considera desde el cero trigonométrico. Recorriendo el arco en el sentido antihorario, el primer extremo será el punto inicial y el segundo extremo el final. Un círculo cerrado serían 6.28 radianes.

La sintaxis para asignar un ángulo final a una elipse (o arco) ya dibujada será pues:

ObjGráfico.EndAngle = DblÁngulo

y la sintaxis para obtener el ángulo de una entidad ya dibujada será:

DblÁngulo = ObjGráfico.EndAngle

DblÁngulo es Double.

· EndParámeter. Sólo aplicable a elipses, obtiene y asigna el parámetro final de una elipse (variable de tipo Double). Los parámetros inicial y final de una elipse se calculan según la ecuación P(q ) = A Ž cos (q ) + B Ž sen (q ), donde A y B son la mitad del eje mayor y del menor respectivamente. El ángulo q será el inicial o final. Se pueden emplear los ángulos o los parámetros para crear una elipse. El parámetro final tiene un rango de 0 a 2 Ž PI.

Para asignar un parámetro final:

ObjGráfico.EndParameter = DblParamFinal

Para obtener un parámetro final:

DblParamFinal = ObjGráfico.EndParameter

· MajorAxis. Sólo aplicable a elipses, obtiene y asigna el punto extremo del eje mayor (es una matriz de tres elementos tipo Double). Sus coordenadas toman como origen el centro de la elipse y se miden en el SCO (Sistema de Coordenadas del Objeto).

La sintaxis para asignar un punto extremo de eje mayor a una elipse es:

ObjGráfico.MajorAxis = DblPtoEjeMayor

Para obtener un punto extremo de eje mayor de una elipse, la sintaxis es:

DblPtoEjemayor = ObjGráfico.MayorAxis

· MinorAxis. Enteramente similar a la propiedad anterior, pero obtiene el punto extremo del eje menor de una elipse. No se puede asignar un punto extremo de eje menor, únicamente obtener:

DblPtoEjeMenor = ObjGráfico.MinorAxis

· RadiusRatio. Sólo aplicable a elipses, define la relación entre el tamaño del eje menor de la elipse y el tamaño del eje menor. La sintaxis para asignar una relación:

ObjGráfico.RadiusRatio = DblRelación

Para obtener la relación de una elipse:

DblRelación = ObjGráfico.RadiusRatio

El valor máximo admitido para la variable Double DblRelación es 1, que significa que ambos ejes son iguales y por lo tanto se trata de un círculo.

· StartAngle. Igual que EndAngle pero para el ángulo inicial. Para asignar uno:

ObjGráfico.StartAngle = DblÁngulo

Para obtener uno:

DblÁngulo = ObjGráfico.StartAngle

DblÁngulo es Double.

· StartParámeter. Igual que EndParameter pero para el parámetro inicial. Para asignar uno:

ObjGráfico.StartParameter = DblParamInicial

Para obtener uno:

DblParamInicial = ObjGráfico.StartParameter

 

DOCE.5.4. Arcos

El método AddArc permite crear un arco de circunferencia que se dibuja desde el punto inicial al final en sentido contrario a las agujas del reloj. Estos puntos se calculan a partir de las propiedades StartAngle, EndAngle y Radius.

Para crear un arco hay que indicar el centro (array de tres valores Double), el radio (Double), el ángulo inicial (Double) en radianes y el ángulo final (Double) también en radianes. La sintaxis de AddArc es:

Set ObjArco = ObjColección.AddArc(DblCentro, DblRadio, DblÁngInic, DblÁngFin)

Propiedades de los objetos de arco:

Application
Area
Center
Color
EndAngle
EndPoint
EntityName
EntityType
Handle
Layer
LineType
LinetypeScale
Normal
ObjectID
Radius
StartAngle
StartPoint
Thickness
Visible

Métodos de los objetos de arco:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Offset
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Todos los métodos y propiedades de los arcos han sido ya explicados en las secciones anteriores.

 

DOCE.5.5. Puntos

Para añadir puntos como entidades gráficas se utiliza el método AddPoint, ya sea en cualquiera de las colecciones que lo poseen (Espacio Modelo, Papel o bloques). La manera es sencilla, ya que únicamente hay que suministrar al método un punto que es, como siempre, una matriz o array de tres elementos (coordenadas X, Y y Z) de tipo de dato Double.

La sintaxis para este método es:

Set ObjPunto = ObjColección.AddPoint(DblPunto)

Propiedades de los objetos de punto:

Application
Color
Coordinates
EntityName
EntityType
Handle
Layer
LineType
LinetypeScale
Normal
ObjectID
Thickness
Visible

Métodos de los objetos de punto:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Los métodos han sido ya estudiados y las propiedades se han visto todas excepto una nueva.

· Coordinates. Obtiene y/o asigna una matriz con las coordenadas de cada uno de los vértices del objeto dado; en el caso del punto hay un único vértice.

La variable que se asigna a estos vértices (si la hubiera) se declara con una sentencia tipo Dim Vértices (1 To n * 3) As Double, donde n es el número de vértices o puntos.

Para asignar una matriz de coordenadas a un objeto punto:

ObjGráfico.Coordinates = DblMatrizVértices

Y para obtenerla:

VarVértices = ObjGráfico.Coordinates

Donde VarVértices es una variable declarada como Variant. Recordemos que si queremos utilizar después las coordenadas habrá que hacer un trasvase a una matriz de tres elementos Double.

 

DOCE.5.6. Texto

El método AddText permite añadir texto en una línea al dibujo. Hemos de indicar la cadena de texto en cuestión (variable String), el punto de inserción en el SCU (matriz Double de tres valores) y la altura (Double). La sintaxis es pues que sigue:

Set ObjTexto = ObjColección.AddText(StrTexto, DblPtoIns, DblAltura)

Propiedades de los objetos de texto:

Application
Color
EntityName
EntityType
Handle
Heigth
HorizontalAlignment
InsertionPoint
Layer
LineType
LinetypeScale
Normal
ObjectID
ObliqueAngle
Rotation
ScaleFactor
StyleName

TextAlignmentPoint
TextGenerationFlag
TextString
Thickness
VerticalAlignment
Visible

Métodos de los objetos de texto:

ArrayPolar
ArrayRectangular
Copy
Erase
GetBoundingBox
GetXData
Highlight
IntersectWith
Mirror
Mirror3D
Move
Rotate
Rotate3D
ScaleEntity
SetXData
TransformBy
Update

Los métodos se han visto todos ya; las nuevas propiedades se estudian a continuación.

· Heigth. Obtiene y/o asigna la altura de un objeto. En el caso del texto se refiere a la altura de las letras mayúsculas. La sintaxis para asignar una altura a un objeto es:

ObjGráfico.Heigth = DblAltura

Y para obtenerla:

DblAltura = ObjGráfico.Heigth

Siendo DblAltura una variable declarada como Double.

· HorizontalAlignment. Obtiene o asigna la alineación horizontal de y a los textos exclusivamente. Las sintaxis son:

para asignar:

ObjTexto.HorizontalAlignment = IntAlineaciónH

para obtener:

IntAlineaciónH = ObjTexto.HorizontalAlignment

siendo los valores para IntAlineaciónH del tipo Integer, aunque también se admiten las siguientes constantes:

acHorizontalAlignmentLeft
acHorizontalAlignmentCenter
acHorizontalAlignmentRight
acHorizontalAlignmentAligned
acHorizontalAlignmentMiddle
acHorizontalAlignmentFit

· InsertionPoint. Esta propiedad obtiene y asigna el punto de inserción de una entidad. El punto de inserción es una matriz de tres elementos Double, como cualquier otro punto:

ObjGráfico.InsertionPoint = DblPtoIns

Con esta sintaxis asignamos un nuevo punto de inserción a un objeto. Para extraer u obtener el punto de inserción de una entidad (ahora Variant) utilizaremos:

VarPtoIns = ObjGráfico.InsertionPoint

· ObliqueAngle. Asigna y obtiene el ángulo de oblicuidad de un texto medido en radianes. Para valores positivos se produce una inclinación a la derecha; los valores negativos se transforman en su equivalente positivo para almacenarlos, para ello se les suma 2PI.

Para asignar un ángulo de oblicuidad:

ObjTexto.ObliqueAngle = DblÁngulo

Para obtener el ángulo de oblicuidad de un texto:

DblÁngulo = ObjTexto.ObliqueAngle

DblÁngulo es un variable de doble precisión Double.

· Rotation. Obtiene y/o asigna un ángulo de rotación en radianes (Double) para un texto, medido a partir del eje X y en sentido antihorario.

Para asignar:

ObjTexto.Rotation = DblÁngulo

Para obtener:

DblÁngulo = ObjTexto.Rotation

· ScaleFactor. Obtiene y/o asigna el factor de escala de anchura (Double) para una entidad de texto.

Para asignar:

ObjTexto.ScaleFactor = DblEscala

Para obtener:

DblEscala = ObjTexto.ScaleFactor

· StyleName. Obtiene y/o asigna el nombre (String) de estilo de texto (o acotación) empleado para el objeto. El estilo deberá estar definido en el dibujo, si no es así se producirá un error. A definir un estilo desde VBA ya aprenderemos más adelante. Si no se asigna estilo se asume por defecto el actual.

Para asignar:

ObjGráfico.StyleName = StrEstilo

Para obtener:

StrEstilo = ObjGráfico.StyleName

· TextAlignmentPoint. Obtiene y/o asigna la posición del punto de alineación del texto. Se trata pues de un array de tres elementos de tipo Double a la hora de asignar, y de una variable Variant a la hora de recoger los valores de un objeto texto.

Para asignar pues:

ObjTexto.TextAlignmentPoint = DblPtoAlineación

Para obtener:

VarPtoAlineación = ObjTexto. TextAlignmentPoint

· TextGenerationFlag. Obtiene y/o asigna el tipo de generación del texto. Es un valor Integer pero que posee también estas dos constantes:

acTextFlagBackward
acTextFlagUpsideDown

para aplicar una generación de "atrás hacia adelante" y de "arriba a abajo" respectivamente. Si se quieren aplicar los dos efectos se deben ejecutar dos instrucciones, una con cada valor.

Para asignar pues:

ObjTexto.TextGenerationFlag = IntGeneración

Para obtener:

IntGeneración = ObjTexto. TextGenerationFlag

· TextString. Obtiene y/o asigna la cadena de texto de una entidad texto. Se pueden incluir en la cadena (valor tipo String) los caracteres especiales de AutoCAD (los precedidos por %%).

Para asignar una cadena la sintaxis es:

ObjTexto.TextString = StrTexto

Para obtener una cadena la sintaxis es:

StrTexto = ObjTexto. TextString

· VerticalAlignment. Obtiene o asigna la alineación vertical de y a los textos exclusivamente. Las sintaxis son:

para asignar:

ObjTexto.VerticalAlignment = IntAlineaciónV

para obtener:

IntAlineaciónV = ObjTexto. VerticalAlignment

siendo los valores para IntAlineaciónV del tipo Integer, aunque también se admiten las siguientes constantes:

acVerticalAlignmentBaseline
acVerticalAlignmentBottom
acVerticalAlignmentMiddle
acVerticalAlignmentTop

Veamos a continuación un ejemplo de un programa que maneja textos.

Primero mostraremos es código del programa:

Option Explicit

Dim AcadDoc As Object
Dim AcadModel As Object
Dim ObjTexto As Object
Dim PuntoIns(1 To 3) As Double
Dim TextoV As String
Dim ColorV As Integer: Dim CapaV As String: Dim TipoLinV As String
Dim EstiloV As String: Dim AlturaV As Double: Dim OblicuidadV As Double
Dim AlV As String
Dim AlH As String
Dim PI As Double


Private Sub Aceptar_Click()
  On Error Resume Next
  PuntoIns(1) = Val(X.Text)
  PuntoIns(2) = Val(Y.Text)
  PuntoIns(3) = Val(Z.Text)
  TextoV = Texto.Text

  Select Case LCase(Color.Text)
    Case "porcapa"
      ColorV = 256
    Case "porbloque"
      ColorV = 0
    Case Else
      ColorV = Val(Color)
      If ColorV < 0 Or ColorV > 256 Then
        MsgBox ("Color no válido")
        Exit Sub
      End If
  End Select
  
  CapaV = Capa.Text
  TipoLinV = UCase(TipoLin.Text)
  EstiloV = UCase(Estilo.Text)
  AlturaV = Val(Altura.Text)
  OblicuidadV = (Val(Oblicuidad.Text) * 2 * PI) / 360

  If AlDerecha.Value = True Then AlH = "acHorizontalAlignmentRight"
  If AlIzquierda.Value = True Then AlH = "acHorizontalAlignmentLeft"
  If AlCentro.Value = True Then AlH = "acHorizontalAlignmentCenter"
  If AlSuperior.Value = True Then AlV = "acVerticalAlignmentTop"
  If AlMitad.Value = True Then AlV = "acVerticalAlignmentMiddle"
  If AlLíneaBase.Value = True Then AlV = "acVerticalAlignmentBaseLine"
  If AlInferior.Value = True Then AlV = "acVerticalAlignmentBottom"
  Set ObjTexto = AcadModel.AddText(TextoV, PuntoIns, AlturaV)
  ObjTexto.Color = ColorV
  ObjTexto.Layer = CapaV
  ObjTexto.Linetype = TipoLinV
  ObjTexto.StyleName = EstiloV
  ObjTexto.ObliqueAngle = OblicuidadV
  ObjTexto.HorizontalAlignment = AlH
  ObjTexto.VerticalAlignment = AlV
  End
End Sub


Private Sub Cancelar_Click() 
  End
End Sub

Private Sub UserForm_Initialize()
  Set AcadDoc = GetObject(, "AutoCAD.Application").ActiveDocument
  Set AcadModel = AcadDoc.ModelSpace
  PI = 3.14159
End Sub

Como vemos es bastante sencillo de entender, según lo estudiado ya acerca de los textos. Únicamente decir que estaría un poco incompleto, ya que sólo se controla —como ejemplo— que el usuario introduzca bien el número de color. Los demás controles (casillas vacías, estilos de texto existentes...) deberían introducirse para que el programa estuviera completo.

NOTA: La manera de controlar si un estilo de texto existe, entre otros muchos controles, se estudiará más adelante.

Veamos a continuación el cuadro diálogo perteneciente a este código:

  

NOTA: Recordemos poner a True la propiedad MultiLine de la casilla de edición en la que introducimos el texto.