Office con C#

13/12/2004 - 10:13 por Miguel Tubia | Informe spam
Hola a todos,
necesito una ayudita con un problema que tengo en un proyecto bajo C#.
Una parte del proyecto es un gestor de documentación (algo básico, pero
bueno), en el parte de la documentación de la empresa se guardará en el
servidor (bien seguro con permisos y eso y a la que solo tendrá acceso el
proceso con el que corre el servicio de windows que hace de servidor del
sistema - está hecho con remoting - o esa es la idea).
Para guardar los ficheros, lo busca, lo elige y, tras leerlo se pasan los
datos como arrays de bytes al servidor y luego se pasan a disco. Eso va
bien, el problema que se plantea ahora es el paso inverso. La idea era que,
cuando lo quiera visualizar, guardarlo en el dir. temporal del usuario y
abrir el programa con el que se visualizará. Pero la mayoría está con Word y
Excel, y los usuarios lo querrán modificar. Y si lo abren, lo modifican y lo
guardan, ellos pensarán que están guardando el doc. de evrdad cuando en
realidad guarda el temporal y el de verdad ni se entera. Lo que estamos
planteando es, si se puede, que no sabemos, "incrustar" el word y el excel
en la aplicación y poder controlar cuando guarda el documento. O abrir
nosotros el word y poder controlarlo.
Hemos mirando y solo hemos visto la segunda opción, con Office XP (es el que
tenemos) y las Office XP Primary Interop Assemblies. Ahora estamos mirando
como usarlas, pero en teoría abrimos un documento pero no sabemos como hacer
que realmente se "abra" el Word para que el usuario pueda interactuar con
él, y así poder controlar cuando guarda el doc, etc... ¿Alguien nos puede
echar una mano con esto?
¿Alguien sabe si se puede incrustar un doc o un xls como un objeto más en un
formulario? ¿Alguna idea?
Muchas gracias por todo
Un saludo

Preguntas similare

Leer las respuestas

#11 hermes_b1
17/12/2004 - 15:07 | Informe spam
Hola todos, AYUDAAAAAAAAAAA yo tengo que hacer esto:
para ver si tienen el mecanismo y su codigo de como se debe realizar.
MUCHAS GRACIAS. RICARDO

LES PASO MI PROBLEMA
1- Tengo una pagina web donde los usuarios necesitan hacer calculos
economicos. Para ello estos ingresarán datos a un formulario en dicha pag.
WEB. Esta será la informacion necesaria para realizar los cálculos.
2- Para procesar esos datos armé un libro en excel que deseo colocar en el
servidor (sin acceso a los usuarios) para que tomando los datos que
ingresaron a la pag WEB, haga los calculos del lado del servidor.
3- Por último, al resultado deseo mostrarlo en la pag WEB para que sea
utilizado por cada usuario que haya ingresado datos. Esto lo deso hacer
así para proteger el libro de excel por posibles cambios mal
intencionados, actualizar el libro mas facilmente sin tener que crear
downloads a los usuarios cada vez que haya modificaciones en el metodo de
calculo. etc..
PD: Cada vez que un usuario ingresa datos, se consideran datos propios que
no son iguales a los que otro usuario desea calcular, por lo tanto cada
vez que uno termina de usar el excel, este debe quedar nuevamente listo
para usar por otro usuario.
PD: se puede hacer multiusuario para algunos casos? que opinan.
GRACIAS AMIGOS
Respuesta Responder a este mensaje
#12 hermes_b1
17/12/2004 - 15:07 | Informe spam
Hola todos, AYUDAAAAAAAAAAA yo tengo que hacer esto:
para ver si tienen el mecanismo y su codigo de como se debe realizar.
MUCHAS GRACIAS. RICARDO

LES PASO MI PROBLEMA
1- Tengo una pagina web donde los usuarios necesitan hacer calculos
economicos. Para ello estos ingresarán datos a un formulario en dicha pag.
WEB. Esta será la informacion necesaria para realizar los cálculos.
2- Para procesar esos datos armé un libro en excel que deseo colocar en el
servidor (sin acceso a los usuarios) para que tomando los datos que
ingresaron a la pag WEB, haga los calculos del lado del servidor.
3- Por último, al resultado deseo mostrarlo en la pag WEB para que sea
utilizado por cada usuario que haya ingresado datos. Esto lo deso hacer
así para proteger el libro de excel por posibles cambios mal
intencionados, actualizar el libro mas facilmente sin tener que crear
downloads a los usuarios cada vez que haya modificaciones en el metodo de
calculo. etc..
PD: Cada vez que un usuario ingresa datos, se consideran datos propios que
no son iguales a los que otro usuario desea calcular, por lo tanto cada
vez que uno termina de usar el excel, este debe quedar nuevamente listo
para usar por otro usuario.
PD: se puede hacer multiusuario para algunos casos? que opinan.
GRACIAS AMIGOS
Respuesta Responder a este mensaje
#13 Miguel Tubia
17/12/2004 - 16:47 | Informe spam
Jejeje, pues sí, bienvenido al idílico mundo de automation!!! jajajaja
lo de inplace, por lo que he leído, no funciona, pero quién sabe, tampoco he
tenido mucho tiempo de darle leña, quién sabe
Muchas gracias por tus ocnsejos, siempre viene bien saber las trabas con las
que se ha encontrado un pofesional ;)
De todos modos lo que yo quería hacer era muy simple por el momento, ya
llegarán tiempos más difíciles, jejejje
Muchas gracias por todo, ya volveré haciendo sopitas :'(
Un saludo

"Braulio Diez" escribió en el mensaje
news:
Hola miguel !

Bienvenido al maravilloso mundo de automation ! XDDD

No sabía que lo de "inplace" ya no funcionaba en .net, se supone que


.net
soporte COM sin problemas y debería de poderse poner. Lo cierto es que era
algo un poquito inestable y a lo mejor por eso han decidido quitarlo de
enmedio (con in-place si te pegaba un casque Ms Word, te lo pegaba tu
aplicación también, con embedded no pasa eso).

A mi me toco trabajar un par de años haciendo filigranas con el


Automation
de office, trabajaba con VC++ 6.0, con .net he hecho cosas de automation


con
Excel.

Un par de consejos:

- Ten cuidado con la versión de Ms Word que soportas para tu


automation,
intenta trabajar con la última que te permita el cliente (la de Word 97 va
regular, a ser posible de 200 para arriba, y si quieres tener bastante
control la 2002 o 2003).

- Cuando quieras sacar una funcionalidad automática (por ejemplo, poner
una celda con color gris y centrada...), dale a grabar una macro en Word,


eso
te generar un codigo en VBA que puedes pasar a automation facilmente.

- Ojo, con el idioma de Word instalado, para algunas cosas te hara


falta
coger la ventana en concreto, y a veces esos nombre dependen del idioma


del
MS Word que estas instalado.

- Otra cosilla, si te hace falta coger el Handle a la ventana de Word,
está se llama "OpusApp", si te metes a hacer cosas "raras" al final


acabaras
tirando de ahí :-)

Buena suerte
Braulio

"Miguel Tubia" wrote:

> Hola,
> voy a comentar mis progresos a ver si a alguien le sirven de algo y, ya
> puestos, a ver si alguien me corrige y complementa.
> Por lo que he visto, es algo chunga la opción de poner un objeto de


office
> "inplace", pues esto se realizaba en VB 6 mediante objetos OLE que no


están
> dsponibles en .NET. En .NET, si solo se quiere visualizar se puede usar


el
> objeto WebBrowser en un formulario para visualizar un objeto de Office.
> Pero para lo que yo quiero eso no me sirve. Necesito saber cuando el


usuario
> graba los cambios, etc... Así que necesito la forma que, siguiendo la
> nomenclaturia que menciona Braulio en su mensaje donde me lo explica, se
> llama "Embedded".
> De esta forma he conseguido abrir un documento de word ya existente y
> comenzar a ver los eventos. Aquí está el código que uso:
>
> //-PEGO
>
> using System;
>
> using System.Threading;
>
> using System.Runtime.InteropServices;
>
> using System.IO;
>
> namespace OfficeOper
>
> {
>
> public class CWord : IDisposable
>
> {
>
> #region Variables de datos de documentacion
>
> /// Ruta local donde se ha copiado
>
> /// </summary>
>
> private object ruta;
>
> #endregion
>
> #region Variables con los datos de word
>
> /// <summary>
>
> /// Aplicación Word
>
> /// </summary>
>
> private Microsoft.Office.Interop.Word.Application wordApp=null;
>
> /// <summary>
>
> /// Documento actual a tratar
>
> /// </summary>
>
> private Microsoft.Office.Interop.Word.Document doc=null;
>
> /// <summary>
>
> /// Indica si la aplicación es creada por nosotros o el word ya


estaba
> abierto
>
> /// </summary>
>
> private bool isNewApp = false;
>
>
> /// <summary>
>
> /// Indica si la clase ha sido liberada
>
> /// </summary>
>
> private bool disposed = false;
>
> #endregion
>
> #region Constructores y metodos de control de la instancia
>
> public CWord(object ruta)
>
> {
>
> this.ruta=ruta;
>
> // Chequea si el WORD está ya abierto
>
> try {
>
> wordApp > >


(Microsoft.Office.Interop.Word.Application)Marshal.GetActiveObject("Word.App
> lication");
>
> isNewApp = false;
>
> }
>
> catch {
>
> wordApp = null;
>
> }
>
> // Lo abre si no lo está
>
> if(wordApp == null) {
>
> try {
>
> wordApp = new
> Microsoft.Office.Interop.Word.ApplicationClass();
>
> isNewApp = true;
>
> }
>
> catch {
>
> wordApp = null;
>
> }
>
> }
>
> wordApp.Visible=true;
>
> wordApp.DocumentBeforeClose+=new
>


Microsoft.Office.Interop.Word.ApplicationEvents3_DocumentBeforeCloseEventHan
> dler (wordApp_DocumentBeforeClose);
>
> this.doc=wordApp.Documents.Open(ref ruta, ref CDocuOper.missing,


ref
> CDocuOper.falso, ref CDocuOper.falso, ref CDocuOper.missing, ref
> CDocuOper.missing, ref CDocuOper.missing, ref CDocuOper.missing,


ref
> CDocuOper.missing, ref CDocuOper.missing, ref CDocuOper.missing, ref
> CDocuOper.cierto, ref CDocuOper.missing, ref
> CDocuOper.missing, ref CDocuOper.missing);
>
> wordApp.DocumentBeforeSave+=new
>


Microsoft.Office.Interop.Word.ApplicationEvents3_DocumentBeforeSaveEventHand
> ler(wordApp_DocumentBeforeSave);
>
> wordApp.Activate();
>
> }
>
> public void Dispose() {
>
> Dispose(true);
>
> GC.SuppressFinalize(this);
>
> }
>
> protected virtual void Dispose(bool disposing) {
>
> if(!this.disposed) {
>
> if(disposing) {
>
> //Liberar recursos
>
> }
>
> if(wordApp != null) {
>
> try {
>
> if(isNewApp && wordApp.Documents.Count == 0) {
>
> object arg1 > > Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
>
> object arg2 = null;
>
> object arg3 = null;
>
> wordApp.Quit(ref arg1, ref arg2, ref arg3);
>
> // Espera hasta que Word cierra
>
> for(;;) {
>
> Thread.Sleep(100);
>
> try {
>
> //Cuando Word se cierra esta llamada


lanza
> una excepción
>
> string dummy = wordApp.Version;
>
> }
>
> catch {
>
> break;
>
> }
>
> } //for
>
> }
>
> }
>
> catch {}
>
> wordApp = null;
>
> }
>
> }
>
> disposed = true;
>
> }
>
> ~CWord() {
>
> Dispose(false);
>
> }
>
> #endregion
>
> public Microsoft.Office.Interop.Word.Application Application {
>
> get {
>
> return wordApp;
>
> }
>
> }
>
> private void
> wordApp_DocumentBeforeClose(Microsoft.Office.Interop.Word.Document Doc,


ref
> bool Cancel) {
>
> //Aqui sabemos si un fichero que se cierra ha sido modificado y


grabado
>
> if (this.doc.Saved)
>
> {
>
> Console.WriteLine("Este fichero ha sido grabado");
>
> //Poner el código para gestionar la grabación de datoa
>
> }
>
> File.Delete((string)this.ruta);
>
> }
>
> private void
> wordApp_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc,


ref
> bool SaveAsUI, ref bool Cancel) {
>
> //Código para gestionar cuando se pulsa para salvar los


datos
>
> }
>
> }
>
> }
>
>
>
> //--FIN
>
>
>
> Parte del código lo he cogido de CodeProject.
>
> Esepro que esto le pueda servir a alguien, aunq sea para empezar.
>
> Aún queda mucho por hacer, pero eso ya son particularidades de cada


proyecto
> (eventos a gestionar, etc...).
>
> Un saludo
>
>
>
Respuesta Responder a este mensaje
#14 Miguel Tubia
17/12/2004 - 16:47 | Informe spam
Jejeje, pues sí, bienvenido al idílico mundo de automation!!! jajajaja
lo de inplace, por lo que he leído, no funciona, pero quién sabe, tampoco he
tenido mucho tiempo de darle leña, quién sabe
Muchas gracias por tus ocnsejos, siempre viene bien saber las trabas con las
que se ha encontrado un pofesional ;)
De todos modos lo que yo quería hacer era muy simple por el momento, ya
llegarán tiempos más difíciles, jejejje
Muchas gracias por todo, ya volveré haciendo sopitas :'(
Un saludo

"Braulio Diez" escribió en el mensaje
news:
Hola miguel !

Bienvenido al maravilloso mundo de automation ! XDDD

No sabía que lo de "inplace" ya no funcionaba en .net, se supone que


.net
soporte COM sin problemas y debería de poderse poner. Lo cierto es que era
algo un poquito inestable y a lo mejor por eso han decidido quitarlo de
enmedio (con in-place si te pegaba un casque Ms Word, te lo pegaba tu
aplicación también, con embedded no pasa eso).

A mi me toco trabajar un par de años haciendo filigranas con el


Automation
de office, trabajaba con VC++ 6.0, con .net he hecho cosas de automation


con
Excel.

Un par de consejos:

- Ten cuidado con la versión de Ms Word que soportas para tu


automation,
intenta trabajar con la última que te permita el cliente (la de Word 97 va
regular, a ser posible de 200 para arriba, y si quieres tener bastante
control la 2002 o 2003).

- Cuando quieras sacar una funcionalidad automática (por ejemplo, poner
una celda con color gris y centrada...), dale a grabar una macro en Word,


eso
te generar un codigo en VBA que puedes pasar a automation facilmente.

- Ojo, con el idioma de Word instalado, para algunas cosas te hara


falta
coger la ventana en concreto, y a veces esos nombre dependen del idioma


del
MS Word que estas instalado.

- Otra cosilla, si te hace falta coger el Handle a la ventana de Word,
está se llama "OpusApp", si te metes a hacer cosas "raras" al final


acabaras
tirando de ahí :-)

Buena suerte
Braulio

"Miguel Tubia" wrote:

> Hola,
> voy a comentar mis progresos a ver si a alguien le sirven de algo y, ya
> puestos, a ver si alguien me corrige y complementa.
> Por lo que he visto, es algo chunga la opción de poner un objeto de


office
> "inplace", pues esto se realizaba en VB 6 mediante objetos OLE que no


están
> dsponibles en .NET. En .NET, si solo se quiere visualizar se puede usar


el
> objeto WebBrowser en un formulario para visualizar un objeto de Office.
> Pero para lo que yo quiero eso no me sirve. Necesito saber cuando el


usuario
> graba los cambios, etc... Así que necesito la forma que, siguiendo la
> nomenclaturia que menciona Braulio en su mensaje donde me lo explica, se
> llama "Embedded".
> De esta forma he conseguido abrir un documento de word ya existente y
> comenzar a ver los eventos. Aquí está el código que uso:
>
> //-PEGO
>
> using System;
>
> using System.Threading;
>
> using System.Runtime.InteropServices;
>
> using System.IO;
>
> namespace OfficeOper
>
> {
>
> public class CWord : IDisposable
>
> {
>
> #region Variables de datos de documentacion
>
> /// Ruta local donde se ha copiado
>
> /// </summary>
>
> private object ruta;
>
> #endregion
>
> #region Variables con los datos de word
>
> /// <summary>
>
> /// Aplicación Word
>
> /// </summary>
>
> private Microsoft.Office.Interop.Word.Application wordApp=null;
>
> /// <summary>
>
> /// Documento actual a tratar
>
> /// </summary>
>
> private Microsoft.Office.Interop.Word.Document doc=null;
>
> /// <summary>
>
> /// Indica si la aplicación es creada por nosotros o el word ya


estaba
> abierto
>
> /// </summary>
>
> private bool isNewApp = false;
>
>
> /// <summary>
>
> /// Indica si la clase ha sido liberada
>
> /// </summary>
>
> private bool disposed = false;
>
> #endregion
>
> #region Constructores y metodos de control de la instancia
>
> public CWord(object ruta)
>
> {
>
> this.ruta=ruta;
>
> // Chequea si el WORD está ya abierto
>
> try {
>
> wordApp > >


(Microsoft.Office.Interop.Word.Application)Marshal.GetActiveObject("Word.App
> lication");
>
> isNewApp = false;
>
> }
>
> catch {
>
> wordApp = null;
>
> }
>
> // Lo abre si no lo está
>
> if(wordApp == null) {
>
> try {
>
> wordApp = new
> Microsoft.Office.Interop.Word.ApplicationClass();
>
> isNewApp = true;
>
> }
>
> catch {
>
> wordApp = null;
>
> }
>
> }
>
> wordApp.Visible=true;
>
> wordApp.DocumentBeforeClose+=new
>


Microsoft.Office.Interop.Word.ApplicationEvents3_DocumentBeforeCloseEventHan
> dler (wordApp_DocumentBeforeClose);
>
> this.doc=wordApp.Documents.Open(ref ruta, ref CDocuOper.missing,


ref
> CDocuOper.falso, ref CDocuOper.falso, ref CDocuOper.missing, ref
> CDocuOper.missing, ref CDocuOper.missing, ref CDocuOper.missing,


ref
> CDocuOper.missing, ref CDocuOper.missing, ref CDocuOper.missing, ref
> CDocuOper.cierto, ref CDocuOper.missing, ref
> CDocuOper.missing, ref CDocuOper.missing);
>
> wordApp.DocumentBeforeSave+=new
>


Microsoft.Office.Interop.Word.ApplicationEvents3_DocumentBeforeSaveEventHand
> ler(wordApp_DocumentBeforeSave);
>
> wordApp.Activate();
>
> }
>
> public void Dispose() {
>
> Dispose(true);
>
> GC.SuppressFinalize(this);
>
> }
>
> protected virtual void Dispose(bool disposing) {
>
> if(!this.disposed) {
>
> if(disposing) {
>
> //Liberar recursos
>
> }
>
> if(wordApp != null) {
>
> try {
>
> if(isNewApp && wordApp.Documents.Count == 0) {
>
> object arg1 > > Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
>
> object arg2 = null;
>
> object arg3 = null;
>
> wordApp.Quit(ref arg1, ref arg2, ref arg3);
>
> // Espera hasta que Word cierra
>
> for(;;) {
>
> Thread.Sleep(100);
>
> try {
>
> //Cuando Word se cierra esta llamada


lanza
> una excepción
>
> string dummy = wordApp.Version;
>
> }
>
> catch {
>
> break;
>
> }
>
> } //for
>
> }
>
> }
>
> catch {}
>
> wordApp = null;
>
> }
>
> }
>
> disposed = true;
>
> }
>
> ~CWord() {
>
> Dispose(false);
>
> }
>
> #endregion
>
> public Microsoft.Office.Interop.Word.Application Application {
>
> get {
>
> return wordApp;
>
> }
>
> }
>
> private void
> wordApp_DocumentBeforeClose(Microsoft.Office.Interop.Word.Document Doc,


ref
> bool Cancel) {
>
> //Aqui sabemos si un fichero que se cierra ha sido modificado y


grabado
>
> if (this.doc.Saved)
>
> {
>
> Console.WriteLine("Este fichero ha sido grabado");
>
> //Poner el código para gestionar la grabación de datoa
>
> }
>
> File.Delete((string)this.ruta);
>
> }
>
> private void
> wordApp_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc,


ref
> bool SaveAsUI, ref bool Cancel) {
>
> //Código para gestionar cuando se pulsa para salvar los


datos
>
> }
>
> }
>
> }
>
>
>
> //--FIN
>
>
>
> Parte del código lo he cogido de CodeProject.
>
> Esepro que esto le pueda servir a alguien, aunq sea para empezar.
>
> Aún queda mucho por hacer, pero eso ya son particularidades de cada


proyecto
> (eventos a gestionar, etc...).
>
> Un saludo
>
>
>
Respuesta Responder a este mensaje
#15 Miguel Tubia
17/12/2004 - 16:50 | Informe spam
Hola Ricardo,
la verdad, no tengo ni idea del tema :( pero si es un proyecto web, conozco
un paquete, Aspose, que seguramente te ayude en tu problema, mira en
http://www.aspose.com/
Ya siento por esta respuesta escueta pero acaba de venir el jefe tocando las
p*******s XD. Luego si tengo más tiempo miramos más a fondo el asunto.
Suerte
Un saludo
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida