Generar un fichero de EXCEL con ASP

Una entrada rápida: queremos que una página ASP en lugar de mostrarnos la información en el navegador lo que haga sea generar un fichero de EXCEL y que se descargue en nuestro equipo ¿Es posible? Sí.

Solo necesitamos añadir dos cabeceras al inicio del documento:

Response.ContentType="application/vnd.ms-excel"
Response.AddHeader "Content-Disposition", "attachment; filename=NombreFichero.xls"

Visual Studio 2015: Borrar una solución

Pues nada, que me han actualizado a Visual Studio 2015 y que andaba yo intentado borrar un proyecto, de hecho la solución completa, que me había liado creándolo… y no encontraba la manera de hacerlo. ¿Cómo va esto? ¿cómo borro toda la solución? Bueno, los menús los tengo en inglés, así que os cuento paso a paso:

  • En el explorador de soluciones (Solution Explorer) seleccionáis la solución que queréis borrar.
  • Después, en la barra de menú superior os váis a Archivo (File) y allí pulsáis Cerrar Solución (Close Solution).
  • Y para acabar, os vais a la carpeta donde teníais guardado el proyecto y allí borráis todos los archivos.

Y listo, solución borrada.

Notación Húngara: Una convención de .NET y Delphi

Como muchos sabéis, porque lo he comentado por aquí alguna vez, las prácticas del ciclo de FP las hice en una empresa que trabajaba en .NET y allí tuve mi primera experiencia con la llamada Notación Húngara. Esta fue creada por el programador húngaro Charles Simonyi, famoso por haber sido el padre de Bravo (el primer editor WYSIWYG) y uno de los responsables de Micosoft Office.

Aunque en Delphi no acabó de tener éxito, la notación húngara sí ha sido muy utilizada dentro de los desarrollos de la propia Microsoft. Dicha notación consiste en añadir antes del nombre de las variables uno o varios caracteres que indican su tipo. Esta técnica era muy útil hace años, si bien en la actualidad tiene muchos detractores, dado que actualmente es sencillo conocer el tipo de una variable sin tener que leerla en su declaración, por lo que se considera que esta notación sólo añade complejidad a la hora de programar.

Los prefijos a usar más habituales son:

  • a: Array
  • b: Booleano
  • by: Byte
  • c: Caracter de un byte
  • d: Tipo numérico de alta precisión (double o float)
  • dw: Tipo numérico de alta precisión
  • e: Evento o enumeración
  • f: Puede ser función o flags
  • fn: Función
  • g: Tipo delegado
  • h: Puede ser Hashtable o Handle
  • hdc: Handle a un contexto de dispositivo
  • hwnd: Handle a un contexto de ventana
  • i: Entero
  • ID: Identificador
  • l: Entero largo, de 32 bits. También puede ser ‘lock’, para definir objetos de control tipo candado
  • lbl: Objeto label
  • lp: Puntero a entero de 32 bits
  • lpfn: Puntero a una función que devuelve un entero largo
  • lpsz: Puntero a una función que devuelve una cadena terminada en cero
  • n: Entero de 16 bits o tipo enumerado
  • o: Objeto
  • p: Puntero
  • pt: Coordenadas empaquetas en un entero de 32 bits
  • rgb: Valor de color rgb empaquetado en un entero de 32 bits
  • s: Cadena de texto
  • sz: Cadena de texto terminada en cero
  • t: Variable tipo struct
  • txt: Caja de texto
  • v: Variable
  • w: Entero de 16 bits
  • x: Coordenada x.
  • y: Byte. También puede ser una coordenada y.

Otra de las cosas que se achaca a esta nomenclatura es la inexistencia de un estándar claro, lo que puede llevar a confusiones a la hora del mantenimiento del código.

Implementar un árbol de datos genérico en VB.NET

Curiosamente Visual Basic .NET no incluye una clase de tipo árbol genérica, cosa que descubrí en mi último trabajo, donde me vi obligado a definir e implementar un árbol genérico con diversos métodos, incluyendo uno de búsqueda recursivo (que no incluiré en el ejemplo porque se basaba en los índices de la base de datos, por lo que no sería un método genérico), y que finalmente quedó a medio hacer por finalizarse mi periodo en la empresa.

El árbol genético en cuestión requiere de dos clases: una clase árbol y una clase nodo. La idea es que la clase nodo tenga una colección de otros nodos dentro (sus hijos), para crear la estructura de árbol. También tienen un método que dice si el árbol está vacío y si un nodo es una «hoja» (es decir, si carece de hijos). El método de búsqueda ya depende del tipo de árbol que quieras construir y de por qué propiedad quieras buscar, pero hay algoritmos generales por toda la red. Aquí os dejo el código de las dos clases:

Public Class Tree(Of T)
 Private m_Root As TreeNode(Of T) = Nothing
 <Description("El nodo raíz del árbol."), _
 Category("Data")> _
 Public Property Root() As TreeNode(Of T)
 Get
 Return m_Root
 End Get
 Set(ByVal value As TreeNode(Of T))
 m_Root = value
 End Set
 End Property

Public Sub Vaciar()
 m_Root = Nothing
 End Sub

Public Function IsEmpty() As Boolean
 If(Not m_Root Is Nothing)
 Return true
 End If
 Return false
 End Function

Public Function MakeRoot(ByVal node_item As T) As TreeNode(Of T)
 m_Root = New TreeNode(Of T)(node_item)
 Return m_Root
 End Function

Public Overrides Function ToString() As String
 Return m_Root.ToString()
 End Function
 End Class

Public Class TreeNode(Of T)
 Public NodeObject As T
 Public Children As New List(Of TreeNode(Of T))

Public Sub New(ByVal node_object As T)
 NodeObject = node_object
 End Sub

Public Function AddChild(ByVal node_item As T) As TreeNode(Of T)
 Dim child_node As New TreeNode(Of T)(node_item)
 Children.Add(child_node)
 Return child_node
 End Function

Public Shadows Function ToString(Optional ByVal indent As Integer = 0) As String
 Dim texto As String
 texto = New String(" "c, indent) & NodeObject.ToString & vbCrLf

For Each child As TreeNode(Of T) In Children
 texto &= child.ToString(indent + 3)
 Next child

Return texto
 End Function

Public Function IsEmpty() As Boolean
 If(Not Children Is Nothing)
 Return false
 End If
 Return true
 End Function

End Class

En fin, espero que este texto os sea de ayuda, suerte con la implementación de la búsqueda, que es lo más complejo, pero un árbol perfectamente equilibrado es una forma de optimizar tu programa y ahorrar recursos en las búsquedas.