lunes, 10 de junio de 2013

Un ligero giro en el blog

A causa de una reorientación y búsqueda de mercado en mi empresa, me encuentro con el regalo (y no es ironía) de convertirme en un experto consultor (no de carnicería) sobre Cloud, en palabras mayores.

Así en el blog iré, de forma señalada, publicando aquellas cosas que no puedo publicar en XatakaWindows o en GenbetaDev, al ser puramente comerciales o no relacionada con las temáticas de ambos blog.

Eso no quita que siga escribiendo sobre código, gestión de proyectos o Un Poquito de Todo.

Gracias si sigues siendo fiel lector,

viernes, 3 de mayo de 2013

Mesa redonda "Cómo mejorar nuestras capacidades de comunicación", Abril 2013.

Ha pasado casi un mes desde la celebración de este evento, mi primer evento como organizador y promotor, y no había tenido tiempo para dejar reposar lo aprendido y poder hacer una crónica sobre lo ocurrido.

Primero, y antes que nada, darles las gracias a David Salgado y Vanesa Pizarro por apuntarse como ponentes a la primera. Gastar un sábado por la mañana y de forma totalmente altruista, merece mucho más que un fuerte aplauso.

A continuación, y no por ello menos agradecido, un gran gracias a Pablo Carballude que consiguió la sala en las instalaciones en Microsoft, el parking, y que ejerció de anfitrión para los que fuimos al evento.

Por último, agradecer mucho a los asistentes: Bruno Capuano, Victor González, Juan María Laó Ramos – que se vino desde Sevilla -, Roberto Luis Bisbé y el presente que escribe estas líneas (a mí mismo no me agradezco, que queda mal).

WP_20130406_001

La charla la inició Salgado, que no solamente fue interesantísima si no que se pudo alargar en el tiempo hasta quedar saciados de sabiduría por parte de uno de los mejores speakers del panorama técnico en España.

En mi caso me ha causado una epifanía que me ha llevado a plantearme que ciertamente quiero mejorar mi capacidad de compartir mis conocimientos y experiencias en público.

Una hora y media después arranco Vanesa, Community Manager profesional, que nos explicó de forma sencilla las técnicas que ayudarán a nuestros post a obtener un SEO lo más positivo posible. Incluyendo una plantilla que en Weblog SL, donde escribo, la utilizamos; pero que ella me ha dado buenas ideas que he puesto en acción y mejoran aún más la posición y visibilidad de mis artículos.

Por último, y en los últimos quince minutos, nos plantamos delante de Pablo, como coordinador y responsable del programa de Technical Rangers, y le planteamos varias dudas que nos estaban reconcomiendo desde hace tiempo.

La conclusión ha sido sencilla, a pesar de lo que parece, Microsoft no va a cerrar el programa.

El programa va a recibir un potente impulso en los próximos trimestres una vez que MS relaje la presión sobre Windows 8.

Se va a realizar una criba en el programa para que nos quedemos los que se adhieran a la Visión del programa: difundir el ecosistema de Microsoft desde un punto de vista técnico. Y así darles más valor a los miembros del programa, y que ser Technical Rangers no sea un mero “título” sin sentido, si no el reconocimiento de un buen trabajo.

Por último recibimos la buena noticia de que Devify.es no será el único sitio de reporte, que Pablo y David han reconocido que es muy incómodo y poco funcional. Y que están trabajando en una forma automatizada de obtener el ranking de cada TR y su aportación.

Mientras ha pasado un mes y el programa ha vuelto al “limbo”, por lo cual este es el artículo que marca el regreso a mi empuje personal (porque me da la gana y me apetece) del programa y que se plasmará en unos pocos días en otra Acción en Conjunto.

WP_20130406_002

Si eres un Technical Ranger, y estás leyendo estas líneas... ponte las pilas (si te apetece, claro).

martes, 26 de marzo de 2013

Excel Reader, una excelente dll para manejar ficheros Excel xls

Estoy metido en una aplicación que importa datos desde una Excel, los desmenuza y los inserta/actualiza en una base de datos SQL.

Como ya me he encontrado anteriormente con el dolor de trabajar con las Interop, me puse a buscar algo más sencillo y me encontré con un proyecto en Code Project de Liu Junfeng, del 2009.

Así de una forma mucho más sencilla puedo leer de libro que quiera, la fila y la celda oportuna.

Y no pongo un ejemplo, porque en la propia página vas a tener uno tan sencillo como el que estoy utilizando yo, y que cubre las necesidades de mi proyecto.

Espero que sea tan útil como lo ha sido para mí.

viernes, 22 de marzo de 2013

XAML, ajustar el tamaño de la página durante el diseño

Este es uno de esos inconveniente que se producen cuando se está aprendiendo y aún se es bastante ignorante sobre la tecnología que utilizo.

Trabajando en Visual Studio 2012, para una preciosa aplicación WPF con XAML, me encuentro que el compañero que ha realizado el diseño del interfaz ha bindeado el alto y ancho de las páginas.

Esto está muy bien para que se ajuste el tamaño a todo tipo de pantalla o dispositivo, pero tiene el inconveniente de que tiene dos efecto secundarios muy molestos:

1. El diseñador de Visual Studio le pone un ancho y alto prácticamente infinito y no hay forma de manipular de forma interactiva las pantallas.

2. Al estar calculando constantemente el inabarcable tamaño, cualquier actuación en el diseñador se hace con una lentitud insoportable.

¿Cual es la solución? Utilizar el tamaño en diseño.

Es decir, le indico al contenedor principal, en este caso una Page, que quiero que durante el diseño el tamaño de la misma sea lo suficientemente pequeño para ser editable. Y esto lo hago con las siguientes 4 líneas en el XAML que he separado con un salto de línea:

<Page x:Class="TSA_KMSPanel.View.ImportacionKMS"
     
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     
     
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     
mc:Ignorable="d"
     
d:DesignWidth="600"
     
d:DesignHeight="800"
   
     
Title="Gestion Listado Estatus"
     
Name="PageGestionListadoEstatus"
     
FontSize="14">

  • Primero hago la referencia al esquema xml de Blend en su versión 2008.
  • A continuación le digo que el prefijo del esquema “d” sea ignorado por el compilador. Si no haces esto VS2012 te avisa que no encuentra lo siguiente en el esquema y no te deja continuar, aunque en la realidad funciona perfectamente.
  • Le añado dos propiedades del esquema “d” que indican el ancho y alto de la página durante el diseño

Y con esto no solamente ahora puedo diseñar de forma visual mi pantalla, si no que la velocidad de manipulación ahora es más que aceptable.

lunes, 25 de febrero de 2013

Exportar un StreamWriter a texto con acentos y ñ

Manda narices que a estas alturas y con los lustros de picar código que llevo aún me pegue con los acentos y letras como la ñ al ir a exportar datos de la pantalla a un fichero de texto.

Así tengo un StreamWriter que bebe de un Grid, y que quiero guardar todos sus datos como un CSV (fichero de texto separados los valores por punto y coma, para ser abierto directamente dese una Excel).

Me volví loco intentando codificar directamente los valores que estaba añadiendo al StreamWriter, cuando lo que realmente hay que hacer es codificar el objeto stream en sí mismo.

Primero voy a poner la solución y luego, por si le valiera a alguien, el ejemplo completo de exportar el contenido de un objeto DataGrid de WPF a un fichero csv que se pueda abrir desde Excel.

var sw = new StreamWriter(rutaFichero, false, Encoding.UTF8);

Y con esto consigo que los acentos y la letra ñ me salgan perfecto en Excel.

Ahora el código completo:

public void Exportar_a_csv(DataGrid pDgHistorial)
        {
           
if (pDgHistorial.IsNotNull())
            {
                var sw = new StreamWriter(rutaFichero, false, Encoding.UTF8);
               
var separador = ";";

                foreach (DataGridColumn columna in pDgHistorial.Columns)
                {
                    sw.Write(columna.Header);
                    sw.Write(separador);
                }
                sw.Write(sw.NewLine);


               
foreach (var registro in pDgHistorial.Items)
                {
                   
var historial = (ClaseAlmacenadaEnElGrid)registro;
                    sw.Write(historial.PrimerCampo
));
                    sw.Write(separador);
                    sw.Write(historial.SegundoCampo);
                    sw.Write(sw.NewLine);
                }
                sw.Flush();
                sw.Close();
            }
        }

Y ahora explico dos cosas que tienes que tener muy en cuenta:

  • El objeto de WPF DataGrid, te almacena objetos tipados. A diferencia del GridView de asp.net. Así lo que recupero son una colección de objetos de una clase específica que he tenido que definir en el momento de la carga de datos en el control. En este caso ClaseAlmacenadaEnElGrid.
  • El parámetro RutaDelFichero, puede ser un string o, lo ideal, que lo recuperes del app.config de la aplicación.

Espero que resulte útil.

ConfigurationSettings.AppSettings está obsoleto

Pequeña tontería que quiero compartir.

Un compañero en una aplicación ha utilizado el siguiente código para acceder a claves den el fichero de configuración app.config:

string NombreFichero = ConfigurationSettings.AppSettings.Get("FicheroExportar");
string TipoFichero = ConfigurationSettings.AppSettings.Get("TipoFicheroExportar");

Lo cual hace que salte una alarma en Visual Studio avisándote que este código es obsoleto y que lo cambies por el actual.

La duda viene a que no es tan directo como el llamar a un nuevo namespace y ya está, pero vamos a empezar por eso:

using System.Configuration;

Esto no nos dará error alguno, pero si intentas introducir ConfigurationManager en el Intellisense no te vá a salir. Para ello debes hacer referencia del ensamblado adecuado en el proyecto, para lo cual pulso con el botón derecho encima del proyecto principal y escojo “Add Reference”.

image

Se me abre la ventana para seleccionar el ensamblado adecuado: System.Configuration. Fíjate que estoy en .NET 4.0.

image

Pulso aceptar y ahora si que si puedo utilizar el código correcto:

var nombreFichero = ConfigurationManager.AppSettings["FicheroExportar"];
var tipoFichero = ConfigurationManager.AppSettings["TipoFicheroExportar"];

Espero que sea útil.

miércoles, 6 de febrero de 2013

Recuperar un valor de un elemento de un XDocument

Que XML no es santo de mi devoción, como tampoco lo es JavaScript, es algo que destila en todo el blog. Y no lo es ninguna de las dos tecnologías por la misma razón, no son nada amigables en su aprendizaje.

Así me encuentro con la siguiente respuesta de un Webservice, que es básicamente un XmlElement con el body del mensaje SOAP en el innerXML.

<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <reactiveSecureClientResponse xmlns="http://irdeto.com/pisys/secureclient">
    <reactiveSecureClientResult>
      <code>1028</code>
      <message>OK</message>

    </reactiveSecureClientResult>
  </reactiveSecureClientResponse>
</soap:Body>

Del cual quiero extraer el valor de los elementos hijos code y message, y que he resaltado en negrita.

Pues bién, llevo casi 6 horas probando mil métodos y la primera aproximación, antes de refactorizarlo – y que va a ser otro artículo – es un tanto extravagante:

Primero convierto el XmlElement en un XDocument (cuidadín con liarte y utilizar XmlDocument, que se montan unos líos de aupa si mezclamos Linq to SQL con XmlDocumentde .NET).

XDocument documento = XDocument.Parse(cuerpoDelMensajeSoap.InnerXml);

¿Porqué XDocument.Parse() en vez de el conocido documento.LoadXml()? Ni idea, pero creo que es para joder. Porque ya me contarás porqué algo tan lógico como lo segundo lo cambian por algo tan raro (un constructor estático con parámetros) como lo primero.

A continuación tiro de las capacidades de Linq to XML para hacer una búsqueda que, personalmente, me parece rara de narices:

XElement code = (from XElement xmlElemento in documento.Descendants()
                       
where xmlElemento.Name.LocalName.Equals("code")
                       
select xmlElemento).FirstOrDefault();

El primer problemón que me encontré es que, a pesar de lo que dicta el sentido común, los xmlElemento que obtengo de los descendientes del XDocument (documento.Descendants()) componen su nombre con dos partes diferenciadas: el namespace y el nombre del nodo en sí.

<{http://irdeto.com/pisys/secureclient}code>1028</code>

Osea, que no solo hay que buscar por el Name del elemento, si no también por su nombre Local.

where xmlElemento.Name.LocalName.Equals("code")

Y así, y entonces si, podemos cargar el valor del nodo de marras que quería recuperar. Por cierto, te aconsejo comprobar primero si el XElement no es nulo para evitar una excepción por objeto no instanciado al querer recuperar el Value.

string codigo = (code != null) ? code.Value : string.Empty;

 

Ahora a refactorizar, que me “huele mal” cuando me tengo que traer dos valores,

public string ExtraerRespuestaDelBody(XmlElement cuerpoDelMensajeSoap)
        {

           
XDocument documento = XDocument.Parse(cuerpoDelMensajeSoap.InnerXml);

           
XElement code = (from XElement xmlElemento in documento.Descendants()
                       
where xmlElemento.Name.LocalName.Equals("code")
                       
select xmlElemento).FirstOrDefault();


           
string codigo = (code != null) ? code.Value : string.Empty;
 
           
return codigo;
        }