Abrir ficheros Excel 2003 en una ventana diferente cada uno

No hay cosa que más me fastidie que el maldito Excel, y su manía de abrir todos los ficheros excel en la misma ventana, lo que hace que cuando quieres comparar o copiar algo, termine siendo un follón y termines metiendo la pata.

Bueno pues para evitarlo, aquí mi truco para Windows XP y Office 2003:

  1. Ir a «Mi PC > Herrramientas > Opciones de carpeta > Tipos de archivo«
  2. Buscar en la lista «XLS«
  3. Pulsar «Opciones avanzadas«
  4. Quitar el tick a «Explorar en la misma ventana«
  5. En la lista de «Acciones«, pulsar «Abrir» y luego «Editar«
  6. Te encontraras en el apartado «Aplicación utilizada para realizar la acción» con algo como:

    «C:\Archivos de programa\Microsoft Office\OFFICE11\EXCEL.EXE» /e

    Substituir por:

    «C:\Archivos de programa\Microsoft Office\OFFICE11\EXCEL.EXE» «%1»

  7. Eliminar cualquier cosa que ponga en «Mensaje DDE«.
  8. «Aceptar > Aceptar > etc…«

Sin tener que reiniciar, cada vez que abras un excel, se te abrirá en una ventana nueva.

Please follow and like us:

Excel y .NET, malos amigos (III): ¿Como poner una imagen en un rango de celdas?

Otra nueva guerra con Excel, desde C#. Ahora el problema era introducir una imagen en un rango de celdas. Un verdadero problema, ya que la imagen tenia que ajustarse a ellas aunque se deformara. Además tenía que funcionar en Office 2003 y 2007. ¿Más madera?, no importa soy informático :P.

Pues bien, primer intento, me pongo manos a la obra y a tirar líneas:

// Rango donde se intertará la imagen
Microsoft.Office.Interop.Excel.Range r1;
r1 = (Microsoft.Office.Interop.Excel.Range) objSheet.get_Range("F5", "AB37");
r1.Select(); //Es necesario seleccinar un rango para poder insertar

// Objeto de todas las imagenes del excel
Microsoft.Office.Interop.Excel.Pictures oPictures =
(Microsoft.Office.Interop.Excel.Pictures)objSheet.Pictures(System.Reflection.Missing.Value);

//La ruta de la imagen donde esta la imagen a insertar,
//OJO es necesario indicar bien la ruta, de lo contrario marcará el siguiente error
//"Error en el método Insert de la clase Pictures" y pues eso despista ya que solo es
//la ruta y no la implementacion del método
string pathTEMP_BMP = System.IO.Path.GetTempFileName();
this._datos.im.Save(pathTEMP_BMP, System.Drawing.Imaging.ImageFormat.Bmp);

// Crear un objeto Picture de Office
Microsoft.Office.Interop.Excel.Picture p =
oPictures.Insert(pathTEMP_BMP, System.Reflection.Missing.Value);
// Redimensionar
p.Width = (double) r1.Width;
p.Height = (double) r1.Height;

Bueno, pues un medio «Fail». Funciona bien en 2003, pero cuando se abre con Excel 2007, la imagen no se ajusta al rango «r1» de celdas. Miro a la pantalla con resignación torera y exclamo mi mítico: «Me cago en tó».

Vale, no desesperemos, tras bucear un poco por internet, veo este articulo que me da otra buena idea. No usar el objeto «Pictures» de Excel, si no usar el «Shapes». Vamos a intentarlo:

// Eliminamos apartir de la línea 17 en adelante y incluimos esto
objSheet.Shapes.AddPicture(pathTEMP_BMP, 
               Microsoft.Office.Core.MsoTriState.msoFalse, 
               Microsoft.Office.Core.MsoTriState.msoCTrue,
               float.Parse(r1.Left.ToString()), float.Parse(r1.Top.ToString()), 
               float.Parse(r1.Width.ToString()), float.Parse(r1.Height.ToString())); 

Perfecto, ahora si funciona bien en 2003, y 2007. Pero lo que cuesta hacer la cosas bien :).

Please follow and like us:

Excel y .NET, malos amigos (II): Proteger un Excel y su contenido

Por desgracia, mis problemas con el maldito Excel no han acabado. Pero ni mucho menos.

Nuevo problema, nueva comedura de cabeza. Necesito proteger el contenido de un Excel, mediante programación (en C#) para que un usuario no pueda ni modificar sus valores ni el formato de las celdas.

Existen varias protecciones que se pueden aplicar: a Celda, a Hoja (Worksheet en MSDN) y a Libro (Workbook en MSDN).

La protección del libro, nos permite proteger la estructura general del libro, el orden de las hojas, añadir mas, o eliminar. El protección de la hoja, es la parte mas interesante, nos permite un montón de cosas, desde prohibir modificar contenido, hasta ordenar las filas/columnas.

Un código de ejemplo es este, que restringe por completo las acciones del usuario:

// Protejo una hoja en particular:
objSheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.Sheets["Hoja 1"];
objSheet.Activate();
objSheet.Protect("clave", true, true, true, false, false, false, false, false, false, false, false, false, false, false, false);
// Protejo el libro completo:
m_Excel.Application.ActiveWorkbook.Protect("clave 2", true, false);

Si queréis, saber mas, solo visitar las urls que os he dejamos mas arriba para dar los permisos que queráis, y no los mas restrictivos.

Please follow and like us:

Excel y .NET, malos amigos: Cambiar el rango de datos a un gráfico

Como casi todos los hemos programado algo para .NET, hemos visto la potencia que tiene. Pero cuando ponemos de nuevo los pies en la tierra es cuando tenemos que volver a usar los objetos COM de Windows.

Arrrrggg… Malditos. ¡Luego me preguntarán que porqué odio a muerte el Office!.

Imaginaros el caso: Un excel «plantilla», donde solo hay que rellenar ciertos datos, pero con unas columnas de datos de longitud dinámica, puede haber desde 10 a 300. Como no, la cosa se complica, también quieren un gráfico que sea variable (es decir, si solo hay 5 datos, que muestre 5, y si hay mas pues mas…). Todo esto se arregla fácilmente con una macro o con una complicada función de esas que trae excel.

Pero ya que el excel lo rellena un programa en .NET (C# para ser mas exactos) lo vamos ha hacel elegantemente:

// Elegir el Gráfico a modificar, es curioso pero si tipo lo declarais con "Chart" en vez de "_Chart" también funciona
Microsoft.Office.Interop.Excel._Chart chart = (Microsoft.Office.Interop.Excel._Chart)objWorkbook.Charts["Mi gráfico"];

// Ahora a cambiar las series que tienen que estar definidas, se podria utilizar el nombre tambien
// FILA es un double donde esta la fila donde acaban los datos
serie = (Microsoft.Office.Interop.Excel.Series) chart.SeriesCollection(1);
serie.XValues = objSheet.get_Range("A4", "A" + Math.Floor(Fila));
serie.Values = objSheet.get_Range("C4", "C" + Math.Floor(Fila));
// Otra serie que tiene el gráfico
serie = (Microsoft.Office.Interop.Excel.Series) chart.SeriesCollection(2);
serie.Values = objSheet.get_Range("D4", "D" + Math.Floor(Fila));

Tachán… tus gráficos con datos dinámicos en un par de líneas. Eso si, tras mucho pensar 🙂

Please follow and like us: