miércoles, 28 de marzo de 2007

Generar y agregar un WebPart con C#

Tal vez no parezca realmente útil generar una WebPart mediante código para agregarlo a un sitio, pero nunca se aprende suficiente y menos en SharePoint.

El caso es que necesitaba que un sitio tuviera un WebPart, pero el contenido del WebPart no se sabría hasta que el usuario no seleccionara una serie de opciones, así que investigando y probando llegué a esta solución. Puede que no sea la solución más efectiva o elegante, pero por lo menos aprendí algo nuevo.

El método en cuestión es muy sencillo, solo hay que obtener el sitio que se quiera, su colección de WebPart de la página donde queramos agregarlo, construir el WebPart y añadirlo a la colección. Veamos el código:

Está en una imagen debido a problemas con las etiquetas del WebPart, espero que sea perfectamente legible.

Donde indica ruta_sitio es un string con la ruta relativa del sitio de SharePoint donde queremos agregar el WebPart (por ejemplo: “/sites/proyectos/”).

Donde pone Contenido del WebPart (donde si no) va nuestro código HTML con el WebPart que queremos generar, cualquier cosa que se nos ocurra. En el HTML podemos integrar cualquier dato que podamos obtener del modelo de objetos de SharePoint.

lunes, 26 de marzo de 2007

Gráficos en SharePoint

Como se suele decir una imagen vale más que mil palabras, así que extrapolándolo a SharePoint, una gráfico vale más que mil listados. Bueno, tal vez sea un poco exagerado, pero lo cierto es que un gráfico bien pensado complementa y da mucha riqueza a un sitio y además mostramos información, no solo datos como con las listas.
Lo más cómodo y a mi parecer indicado para hacer gráficos es tener una base de datos en nuestro SQL Server donde almacenar las consultas que hagamos, de las cuales se nutrirá nuestro gráfico. En esta base de datos crearemos un usuario con permisos de lectura que usaremos para acceder desde SharePoint. También crearemos una nueva vista de todos los datos de las listas y bibliotecas de nuestro SharePoint, la consulta será:

SELECT li.tp_Title, ud.*
FROM [BD SharePoint].dbo.UserData ud INNER JOIN
     [BD SharePoint].dbo.Lists li ON
     li.tp_ID = ud.tp_ListId

De esta vista podremos extraer los datos de una lista concreta mediante el campo tp_Title realizando una consulta y guardándola en una nueva vista. Muy interesante resultan los gráficos de barras para extraer las medias en encuestas o los gráficos circulares para porcentajes por ejemplo de tipos de contenido, todo depende de nuestra pericia con las consultas SQL. Aquí van dos ejemplos:



Para poder poner nuestro gráfico en SharePoint necesitamos tener instalado los Office Web Components.
Una vez tengamos los Office Web components agregamos la WebPart Gráfico Dinámico de Office que está en la galería de servidor virtual.

Al agregarlo a nuestra página nos dará la opción de conectarse a un origen de datos externo y al pulsar sobre ella seleccionamos agregar una conexión con SQL Server.
Nos saldrá un asistente donde primero deberemos poner el nombre de nuestro servidor y la opción de usar nombre de usuario y contraseñas, donde pondremos el usuario que nos creamos en nuestra base de datos para las vistas, el cual tenía acceso de lectura.

En el siguiente paso seleccionamos nuestra base de datos y la vista con los datos para nuestro gráfico.
En el último paso marcamos la casilla para guardar la contraseña en el archivo y almacenamos el archivo de conexión en una biblioteca de SharePoint donde todos los usuarios tengan acceso, si no habrá usuarios que no puedan visualizar el gráfico.

Una vez tenemos todo esto ya solo queda pelearse con las opciones de la WebPart para dejar nuestro gráfico como nos guste.

Un sitio bien configurado al que le agreguemos un gráfico puede ser un gran sitio. Podemos por ejemplo configurar un sitio para evaluación de proveedores o clientes, donde tengamos la ficha con la información del cliente, unas listas con sus pedidos y lo complementemos con unos gráficos sobre su media en las evaluaciones y sobre sus pedido o histórico de ventas.

Además de todo esto los gráficos entran mas por los ojos, sobre todo si tienen unos buenos colores.

miércoles, 21 de marzo de 2007

Disponible la Web del V CAIQ


Como anuncié anteriormente, los días 19, 20 y 21 de Abril se celebrará en Almería el V Congreso Andaluz de Ingeniería Química.

El V CAIQ contará con el patrocinio y colaboración de numerosas empresas del sector y asociaciones, muy especialmente AIQU, asociación organizadora del congreso.

No dudeis en visitar la Web del V CAIQ que ya se encuentra operativa, donde podéis encontrar toda la información del congreso.

miércoles, 7 de marzo de 2007

E=MC2 ¿Es realmente cierto?


Científicos del NEC Research Institute de Princeton han conseguido superar en 300 veces la velocidad de la luz.

Los investigadores manipularon un vapor de átomos irradiados por laser que acelera la velocidad de las ondas de luz, produciendo que un pulso atravesara la cámara preparada con el vapor unas 300 veces más rápido que si lo hiciera en el vacío.

El hecho invita a pensar que Albert Einstein no estaba en lo cierto en su teoría de la relatividad, ya que según esta nada puede viajar más rápido que la luz. Pero parece ser que la teoría de la relatividad es relativa. Me explico, nada con masa puede viajar más rápido que la luz.

Lo mas curioso del experimento es que el pulso salió de la cámara antes de entrar en ella. Cito textualmente del artículo original "cuando las ondas de luz están distorsionadas, el pulso viaja hacia delante en el tiempo", parece de ciencia ficción.

La investigación del NEC se publicara en la revista Nature.

Artículo original en CBC News.

lunes, 5 de marzo de 2007

Creación de Informes Word de Listas de SharePoint

Todos conocemos las bondades de SharePoint, pero a pesar de tener toda la información que se pueda desear bien almacenada y organizada y de las herramientas de filtro, búsqueda, vistas y demás, se sigue queriendo tener un informe en papel para distribuir, anotar, leer, etc.
Para solventar esa ‘necesidad’ de imprimir de los usuarios se puede crear una aplicación de escritorio para generar informes de las listas que nos interesen. Para ello crearemos una aplicación Windows Form en la que usaremos los WebService que nos brinda SharePoint y el modelo de objetos de Microsoft Word.


Primero deberemos obtener los elementos de la lista que nos interesa. Para usar el WebService que nos hace falta debemos agregar una referencia web a nuestro proyecto, para ello pulsamos con el botón derecho en “Referencias Web” y seleccionamos agregar. En la zona URL ponemos “http://spserver/_vti_bin/lists.asmx” (donde spserver es la ruta del sitio donde se halla la lista que nos interesa) y cambiamos el nombre de referencia web por “WSList” para que nos sea más fácil a la hora de programar. También deberemos añadir los espacios de nombres System.Net y System.Xml para poder implementar el siguiente método:

public bool obtenerElementos()
{
  try
  {
    WSList.Lists lista = new WSList.Lists();
    lista.Credentials = new NetworkCredential(usuario, password, dominio);

    lista.Url = "http://spserver/_vti_bin/lists.asmx";

    XmlDocument xmlDoc = new XmlDocument();
    XmlNode nodeQ = xmlDoc.CreateNode(XmlNodeType.Element, "Query","");
    XmlNode nodeVF = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields","");
    XmlNode nodeQO = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions","");

    XmlNode xmlNode = lista.GetListItems("Noticias",null,nodeQ,nodeVF,null,nodeQO);

    string xpathQuery = "//*[local-name() = 'data' and namespace-uri() = 'urn:schemas-microsoft-com:rowset']/*[local-name() = 'row' and namespace-uri() = '#RowsetSchema']";

    noticias = xmlNode.SelectNodes(xpathQuery);

    return true;
  }
  catch(Exception ex)
  {
    return false;
  }
}

Con este método ya tenemos almacenados los elementos de nuestra lista de Noticias en un objeto XmlElement que lo declararemos de forma global para la aplicación. Ahora solo queda crear el informe en Word.

Para poder crear un informe en Word deberemos primero agregar unas referencias a nuestro proyecto. Para ello seleccionamos agregar nueva referencia y en la pestaña COM seleccionamos “Microsoft Word Object Library” y la agregamos.

Para poder implementar el método hemos de poner en nuestro código la llamada a la librería de Word, using Word = Microsoft.Office.Interop.Word. Y el código de nuestro método para generar un informe en Word es:
public string crearInformeWord()
{
/* Creamos la aplicacion word y el documento */
Word._Application oWord;
  Word._Document oDoc;
  oWord = new Word.Application();

  for(int i=0; i'<'noticias.Count; i++)
  {
    try
    {
      object oMissing = System.Reflection.Missing.Value;
/* \endofdoc es un bookmark predefinido
* para el final del documento */
      object oEndOfDoc = "\\endofdoc";

/* Creamos un nuevo documento de Word */
      oDoc = oWord.Documents.Add(ref oMissing,ref oMissing,ref oMissing,ref oMissing);
      object oRng;

/* Creamos el párrafo para insertar el titulo */
Word.Paragraph oParrafoTitulo;

/* Establecemos la referencia del parrafo
* al final del documento */
      oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;
      oParrafoTitulo = oDoc.Content.Paragraphs.Add(ref oRng);

/* El texto del párrafo será el título de la noticia */
      oParrafoTitulo.Range.Text = noticias[i].Attributes[“ows_Title”].Value;
      oParrafoTitulo.Range.Font.Name = "Tahoma"; //Fuente de la letra
      oParrafoTitulo.Range.Font.Size = 12; //Tamaño de la letra
      oParrafoTitulo.Range.Font.Bold = 1; //Negrita SI/NO
      oParrafoTitulo.Format.SpaceAfter = 12; //Espacio con el parrafo siguiente
      oParrafoTitulo.Range.InsertParagraphAfter(); //Inserta el párrafo

/* Creamos el párrafo para insertar el cuerpo */
      Word.Paragraph oParrafoCuerpo;

/* Establecemos la referencia del parrafo al final del documento */
      oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;
      oParrafoCuerpo = oDoc.Content.Paragraphs.Add(ref oRng);

/* El texto del párrafo será la descripción de la noticia */
      oParrafoCuerpo.Range.Text = noticias[i].Attributes[“ows_Descripcion”].Value;
      oParrafoCuerpo.Range.Font.Name = "Tahoma"; //Fuente de la letra
      oParrafoCuerpo.Range.Font.Size = 10; //Tamaño de la letra
      oParrafoCuerpo.Range.Font.Bold = 0; //Negrita SI/NO
      oParrafoCuerpo.Format.SpaceAfter = 6; //Espacio con el parrafo siguiente
      oParrafoCuerpo.Range.InsertParagraphAfter(); //Inserta el párrafo

/* Salto de página para poner una noticia en cada página del informe
* Solo saltamos de página si no es la última noticia */
      if(i+1 < noticias.Count)
      {
        Word.Paragraph oParaSalto;
        oRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;
        oParaSalto = oDoc.Content.Paragraphs.Add(ref oRng);
        object oPageBreak = Word.WdBreakType.wdPageBreak;
        oParaSalto.Range.InsertBreak(ref oPageBreak);
      }

    }
    catch(Exception ex)
    {
/* Muy importante ponerlo también en el catch
* Ya que si falla y no se pone Word queda abierto en segundo plano */
      oWord.Visible = true;
    }
  }
}

También podemos generar una tabla con todas las noticias:

public string crearTablaWord()
{
/* Creamos la aplicación Word y el documento */
  Word._Application oWord;
  Word._Document oDoc;
  oWord = new Word.Application();

  try
  {
/* Calculo del numero de filas
* para poner en cada fila dos noticias (2 columnas) */
    int filas = 1;

    if(noticias.Count%2 == 1)
    {
      filas = (noticias.Count/2)+1;
    }
    else
    {
      filas = noticias.Count/2;
    }

/* Creamos el objeto tabla */
    Word.Table oTable;

/* Establecemos la posición al final del documento */
    Word.Range wrdRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;

/* Indicamos el numero de filas y columnas */
    oTable = oDoc.Tables.Add(wrdRng, filas, 2, ref oMissing, ref oMissing);
    oTable.Range.ParagraphFormat.SpaceAfter = 6;
    oTable.Columns.Borders.Enable = 1; //ponemos bordes a la tabla
oTable.Range.Font.Bold = 0;

/* Agregamos el texto a las celdas */
    int r, c, pos;
    pos = 0;
    string text;
    for(r = 1; r '<'= filas; r++)
    {
      for(c = 1; c '<'= 2; c++)
      {
/* Controlamos si en la última celda no se va a escribir nada */
      if(r==filas && c==2)
      {
        text = "Título: ";
        oTable.Cell(r, c).Range.Text = text;
        text = "Autor: ";
        oTable.Cell(r, c).Range.Text += text;
        text = "Creado: ";
        oTable.Cell(r, c).Range.Text += text;
      }
      else
      {
/* Ponemos el titulo, autor y fecha de creación de la noticia */
          text = "Título: "+ noticias[pos].Attributes["ows_title"].Value;
          oTable.Cell(r, c).Range.Text = text;
          text = "Autor: "+ noticias[pos].Attributes["ows_Author"].Value;
          oTable.Cell(r, c).Range.Text += text;
          text = "Creado: "+ noticias[pos].Attributes["ows_Created"].Value;
          oTable.Cell(r, c).Range.Text += text;
        }

        pos++;
      }
    }
  }
  catch(Exception ex)
  {
/* Muy importante ponerlo también en el catch ya que si falla
* y no se pone, Word queda abierto en segundo plano */

    oWord.Visible = true;
  }

  oWord.Visible = true;
}

Si queremos que nuestro informe quede mejor, podemos crear una plantilla de Word con un encabezado y pie de página, donde podremos poner un logo, número de páginas, etc y crear el informe a partir de esa plantilla. Para hacer esto solo habrá que cambiar lo siguiente al principio del método:

/* Hay que cambiar esto */
oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);

/* Por esto otro */
object oPlantilla = "c:\\plantilla.dot";
oDoc = oWord.Documents.Add(ref oPlantilla,ref oMissing,ref oMissing, ref oMissing);

Con esto tenemos un generador de informes de cualquier lista de SharePoint que a más de un usuario le puede interesar.

viernes, 2 de marzo de 2007

No es una producción de Jerry Bruckheimer


Vía Xataka me he encontrado con este vídeo, en el cual se ve una nueva investigación para mejorar el transporte ferroviario, pero por lo que se ve se podría aplicar a muchos tipos de transporte (habéis visto los coches en Minority Report).

Se trata básicamente de enfriar un imán con nitrógeno líquido y al ponerlo sobre una superficie metálica el imán la repele pero a su vez la atrae, permitiendo al tren levitar sobre los raíles pero sin separarse de ellos ni salirse. Las vías pueden estar debajo, en el lateral o incluso encima del medio de transporte. El único inconveniente es que se evapore el nitrógeno líquido.

Ya me veo subiendo a mi 117º piso en mi coche.