En este post escribiremos el código necesario para que a través del lenguaje Visual Basic .NET podamos leer los datos de las celdas de una hoja de cálculo y tomar estos valores como coordenadas de vértices para dibujar una polilínea en AutoCAD.

En el post anterior, programamos el proceso inverso, es decir, exportamos las coordenadas de los vértices de una polilínea hacia una hoja de cálculo, además de forma opcional podíamos elegir si exportar también el nombre de la capa y como último ejemplo; cambiar el color de la entidad seleccionada.

En el post #5 de este tema agregamos un formulario de Windows con los controles necesarios para ambos ejemplos: “Exportar coordenadas de vértices de una polilínea desde AutoCAD a Excel” y otros para la operación inversa.

Para este segundo ejemplo debemos de comprobar que nuestro formulario tenga el siguiente diseño:

Completar el proyecto con el código necesario

Paso 1: Agregar el código para el botón “btnArchivoExcel” (Seleccionar el archivo de coordenadas…), que permitirá poder elegir el archivo que contiene los datos de las coordenadas a tomar en cuenta.

El código es el siguiente:

Private Sub btnArchivoExcel_Click(sender As Object, e As EventArgs) Handles btnArchivoExcel.Click
	Dim result As DialogResult = OpenFileDialog1.ShowDialog

	If result = Windows.Forms.DialogResult.OK Then
		lblRuta.Text = OpenFileDialog1.FileName
	Else
		lblRuta.Text = ""
	End If

End Sub

Este código mostrará el cuadro de diálogo “Abrir archivo de vértices” el cual te permitirá elegir los siguientes tipos de archivos: “Libro de Excel|.xlsx|Archivo de texto|.csv“.

Paso 2: Completar el código para el botón “Aceptar” (btnAceptar), que permita leer los datos desde Excel y dibujar la polilínea en AutoCAD.

El código deberá de formar parte de la condicional IF pero siempre y cuando el tab activo del control (TabControl1) sea el TabPage2 (“De Excel a AutoCAD”), en este caso sería lo falso de “selectedIndex = 0” es decir; ELSE.

El código es el siguiente:

Else
	If lblRuta.Text <> "" Then

		btnAceptar.DialogResult = DialogResult.OK
		Me.Visible = False

		' Cargar una nueva instancia de Excel.
		objApp = New Excel.Application()
		objBooks = objApp.Workbooks
		objBook = objBooks.Open(lblRuta.Text)
		objSheets = objBook.Worksheets

		For indHoja As Integer = 1 To objSheets.Count
			Using acTrans As Transaction = ACCADBaseDatos.TransactionManager.StartTransaction()

				'Dim CapaActual As String
				'CapaActual = ACADDocument.GetLispSymbol("Clayer")

				Dim Fila As Integer = 2
				Dim IndVertice As Integer = 0

				Dim x As Double
				Dim y As Double

				'Abrir la base de datos
				Dim acBlkTbl As BlockTable
				acBlkTbl = acTrans.GetObject(ACCADBaseDatos.BlockTableId,
						   OpenMode.ForRead)

				'Abrir la tabla de datos del model space para escritura
				Dim acBlkTblRec As BlockTableRecord
				acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),
							  OpenMode.ForWrite)

				'Crear la nueva polilinea
				Dim acPoly As Polyline = New Polyline()
				acPoly.SetDatabaseDefaults()

				'Hoja actual de Excel
				objSheet = objSheets(indHoja)

				While objSheet.Cells(Fila, 1).Value2

					'Obtener los datos de las celdas
					x = objSheet.Cells(Fila, 1).Value2
					y = objSheet.Cells(Fila, 2).Value2

					'Agregar cada vétice
					Dim ptv As Point2d = New Point2d(x, y)
					acPoly.AddVertexAt(IndVertice, ptv, 0, 0, 0)

					Fila += 1
					IndVertice += 1
				End While

				'Agregar el nuevo objeto y la entidad en la tabla de entidades de AutoCAD
				acBlkTblRec.AppendEntity(acPoly)
				acTrans.AddNewlyCreatedDBObject(acPoly, True)

				'Guardar el objeto en la base de datos de AutoCAD
				acTrans.Commit()
				ACCADEditor.WriteMessage("Se dibujó la polilinea a partir del archivo indicado.")
			End Using
		Next

		'Cerrar el archivo de Excel y salir
		objBook.Close(False)
		objApp.Quit()

		'Limpiar las variables
		objSheets = Nothing
		objBooks = Nothing
		objBook = Nothing
		objApp = Nothing
	Else
		Application.ShowAlertDialog("Seleccione primero el archivo de Excel a importar.")
	End If

El código completo del procedimiento para el evento “Click” del control “btnAceptar” sería el siguiente:

Private Sub btnAceptar_Click(sender As Object, e As EventArgs) Handles btnAceptar.Click

	Dim selectedTab As TabPage = TabControl1.SelectedTab
	Dim selectedIndex As Integer = TabControl1.SelectedIndex

	If selectedIndex = 0 Then

		Dim acSSPrompt As PromptSelectionResult = ACADDocument.Editor.GetSelection()

		If acSSPrompt.Status = PromptStatus.OK Then

			Dim acSSet As SelectionSet = acSSPrompt.Value

			Dim fila As Long
			Dim NumeroVertices As Integer

			' Cargar una nueva instancia de Excel.
			objApp = New Excel.Application()
			objBooks = objApp.Workbooks
			objBook = objBooks.Add
			objSheets = objBook.Worksheets
			objSheet = objSheets(1)
			range = objSheet.Range("A1", Reflection.Missing.Value)

			fila = 0

			btnAceptar.DialogResult = DialogResult.OK
			Me.Visible = False

			For Each acSSObj As SelectedObject In acSSet

				If Not IsDBNull(acSSObj) Then

					Using acTrans As Transaction = ACCADBaseDatos.TransactionManager.StartTransaction()

						'Abrir el objeto para editarlo
						Dim acEnt As Entity = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForWrite)
						Dim ColumnasConsiderar As Integer

						If Not IsDBNull(acEnt) Then

							Dim acEntPL As Polyline = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForRead)

							Dim Capa = acEntPL.Layer
							NumeroVertices = acEntPL.NumberOfVertices

							If chkExportarCapa.Checked = False Then
								ColumnasConsiderar = 2
							Else
								ColumnasConsiderar = 3
							End If

							range = range.Resize(NumeroVertices + 1, ColumnasConsiderar)

							Dim saRet(NumeroVertices + 1, ColumnasConsiderar)

							saRet(fila, 0) = "Este"
							saRet(fila, 1) = "Norte"

							If chkExportarCapa.Checked = True Then
								saRet(fila, 2) = "Capa"
							End If

							fila += 1

							For nCnt As Integer = 0 To NumeroVertices - 1

								Dim punto As Point2d = acEntPL.GetPoint2dAt(nCnt)

								Dim x As Double
								Dim y As Double

								x = punto.X
								y = punto.Y

								saRet(fila, 0) = x
								saRet(fila, 1) = y

								If chkExportarCapa.Checked = True Then
									saRet(fila, 2) = Capa
								End If

								fila += 1
							Next

							'Escribir los valores de la matriz en el rango (celdas)
							range.Value = saRet

							'Se cambia de color a la entidad seleccionada
							acEnt.ColorIndex = 3

							If chkEliminarEntidad.Checked = True Then
								acEnt.Erase()
							End If

							'Actualizar la base de datos
							acTrans.Commit()

						End If
					End Using
				End If
			Next

			objApp.Visible = True

			Application.ShowAlertDialog("Se exportaron " + NumeroVertices.ToString + " vertices.")
		Else
			Application.ShowAlertDialog("No se seleccionó nada.")
		End If

		objApp.UserControl = True

		'Limpiar las variables
		range = Nothing
		objSheet = Nothing
		objSheets = Nothing
		objBooks = Nothing
		objApp = Nothing

	Else
		If lblRuta.Text <> "" Then

			btnAceptar.DialogResult = DialogResult.OK
			Me.Visible = False

			' Cargar una nueva instancia de Excel.
			objApp = New Excel.Application()
			objBooks = objApp.Workbooks
			objBook = objBooks.Open(lblRuta.Text)
			objSheets = objBook.Worksheets

			For indHoja As Integer = 1 To objSheets.Count
				Using acTrans As Transaction = ACCADBaseDatos.TransactionManager.StartTransaction()

					'No se toman en cuenta estas 2 siguientes lineas, pero quedan de ejemplo:
					'Dim CapaActual As String
					'CapaActual = ACADDocument.GetLispSymbol("Clayer")

					Dim Fila As Integer = 2
					Dim IndVertice As Integer = 0

					Dim x As Double
					Dim y As Double

					'Abrir la base de datos
					Dim acBlkTbl As BlockTable
					acBlkTbl = acTrans.GetObject(ACCADBaseDatos.BlockTableId,
							   OpenMode.ForRead)

					'Abrir la tabla de datos del model space para escritura
					Dim acBlkTblRec As BlockTableRecord
					acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),
								  OpenMode.ForWrite)

					'Crear la nueva polilinea
					Dim acPoly As Polyline = New Polyline()
					acPoly.SetDatabaseDefaults()

					'Hoja actual de Excel
					objSheet = objSheets(indHoja)

					While objSheet.Cells(Fila, 1).Value2

						'Obtener los datos de las celdas
						x = objSheet.Cells(Fila, 1).Value2
						y = objSheet.Cells(Fila, 2).Value2

						'Agregar cada vétice
						Dim ptv As Point2d = New Point2d(x, y)
						acPoly.AddVertexAt(IndVertice, ptv, 0, 0, 0)

						Fila += 1
						IndVertice += 1
					End While

					'Agregar el nuevo objeto y la entidad en la tabla de entidades de AutoCAD
					acBlkTblRec.AppendEntity(acPoly)
					acTrans.AddNewlyCreatedDBObject(acPoly, True)

					'Guardar el objeto en la base de datos de AutoCAD
					acTrans.Commit()
					ACCADEditor.WriteMessage("Se dibujó la polilinea a partir del archivo indicado.")
				End Using
			Next

			'Cerrar el archivo de Excel y salir
			objBook.Close(False)
			objApp.Quit()

			'Limpiar las variables
			objSheets = Nothing
			objBooks = Nothing
			objBook = Nothing
			objApp = Nothing
		Else
			Application.ShowAlertDialog("Seleccione primero el archivo de Excel a importar.")
		End If

	End If

End Sub

Paso 3: Como paso final, guarda tu proyecto, vuelve a compilarlo, cárgalo en AutoCAD y ejecuta el comando, haz clic en el botón “Seleccionar el archivo de coordenadas…“, selecciona tu archivo con datos y verás cómo los datos leídos desde esa hoja de cálculo de Microsoft Excel te permiten dibujar una polilínea.

En este post de ejemplo se ha programado dibujar una entidad polilínea, pero con el conocimiento de cómo leer los datos a través de VB.NET, podrás acceder a datos de celdas para dibujar cualquier entidad o realizar cualquier operación para desarrollar una solución robusta.

Si deseas conocer más acerca del Paso 3, te recomiendo le des un vistazo al post #6.