none
Replace text in word document

    Question

  • Hi,

    I have created an out of browser application with elevated trust and have sucessfully opened a word document.
    However, I am trying to replace some text in the document but I'm not sure how to do this without referencing
    Word in Silverlight. Here is part of my code:

    If (AutomationFactory.IsAvailable)

    {

    dynamic word = AutomationFactory.CreateObject("Word.Application");

    word.visible = true;

    word.Documents.Open("C:\\Users\\cjones\\Documents\\Test.doc");

    object replaceAll = Word.WdReplace.wdReplaceAll;

        word.Selection.Find.ClearFormatting();
        word.Selection.Find.Text = "DEFAULTDATE";

        word.Selection.Find.Replacement.ClearFormatting();
        word.Selection.Find.Replacement.Text = DateTime.Today.ToShortDateString();

        word.Selection.Find.Execute(
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref replaceAll, ref missing, ref missing, ref missing, ref missing);

    word.Save();
    }

    it is with Word.WdReplace.wdReplaceAll; that I am stuck. Is there away around this?

    I appreciate any help,

    cheers,

    Chris

    Thursday, January 05, 2012 6:09 AM

Answers

  • Hi Chris, no offence, on another comp is gone.

    Reflector told me that wdReplaceAll is 2. Simply set the value and it works in SL4.

    Cheers, Greg

    Friday, January 06, 2012 7:24 AM

All replies

  • Hi Chris,

    check below solution

    http://www.dnzone.com/forum/topic/816/

    it may be solve your problem.

    Regards

    Savia

    Thursday, January 05, 2012 6:17 AM
  • Hi,

    to overcome the same problem I've created a simple Console app referencing Word. Thus I've had Intellisense support, what makes life much easier Cool. After you copy&paste your code to SL app.

    Thursday, January 05, 2012 6:18 AM
  • Hi Greg,

    The difference, is that in the consol app, you can reference word. This does not seem possible in Silverlight.

    Do you have some code you can share with me?

    Thanks

    Chris

    Thursday, January 05, 2012 6:27 AM
  • Yes, sure. This is from Console project:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using excel = Microsoft.Office.Interop.Excel;
    using deb = System.Console; //Diagnostics.Debug;
    using System.Runtime.InteropServices;
    namespace ConsoleCS
    {
        class Program
        {
            delegate int MathOp(int a, int b);
            static void Main(string[] args)
            {
                //Microsoft.Office.Interop.Excel.ApplicationClass excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
                excel.Application excelApp = new excel.Application();
                excel.Workbook workBook = excelApp.Workbooks.Open(@"\\GBV\Public\Documents\Copie de Inventar August 2011.xlsm", false, true);
                deb.WriteLine(workBook.Sheets.Count);
                //for (
                    int sheet = 8; 
                    //sheet <= 6; sheet++)
                {
                    excel.Worksheet worksheet = workBook.Sheets[sheet];
                    if (worksheet == null) throw new ArgumentNullException(string.Format("a{0}rgs", "ARG0"));
                    for (int row = 5; row < 10; row++)
                    {
                        //for (int col = 1; col < 7; col++)
                        //{
                        //    string str = worksheet.Cells[row, col].Text as string;
                        //    decimal preis;
                        //    decimal.TryParse(worksheet.Cells[row, col].Text, out preis);
                        //    deb.Write(worksheet.Cells[row, col].Text + " ");
                        //    var t = worksheet.Cells[row, col].ToString();
                        //}
                        decimal preis;
                        var val = worksheet.Cells[row, 6].Value;
                        if (decimal.TryParse(val.ToString(), out preis))
                            deb.WriteLine(preis);
                        else
                        {
                            deb.WriteLine("fail");
                        }
                        deb.WriteLine(worksheet.Cells[row, 6].Text + " ");
                    }
                    
                }
                workBook.Close(false);
                excelApp.Quit();
                deb.ReadLine();
            }
        }
    }

    in this one I can reference Excel (and I do). This is code in SL app, not referencing Office.

            public void Execute(ActionExecutionContext context)
            {
                _bgwk = new BackgroundWorker { WorkerReportsProgress = true,WorkerSupportsCancellation = true};
                _bgwk.ProgressChanged += (s, e) =>
                    _progressAction(e);
                
                _bgwk.RunWorkerCompleted += (s, e) =>
                                               {
                                                   _completedAction(e);
                                                   Completed(this, new ResultCompletionEventArgs { WasCancelled = _stop });
                                               };
    
                _bgwk.DoWork += (s, e) =>
                {
                    dynamic excelApp, workBook;
                    BackgroundWorker worker = s as BackgroundWorker;
                    if (worker == null)
                        Completed(this, new ResultCompletionEventArgs{Error = new Exception("Internal error."), WasCancelled = true});
                    string fileName = e.Argument as string;
                    try
                    {
                        excelApp = AutomationFactory.CreateObject("Excel.Application");
                        if (worker != null && worker.WorkerReportsProgress)
                            worker.ReportProgress(0, "Started");
                        workBook = excelApp.Workbooks.Open(fileName, 
                                                                   false, true);
                        if (worker.WorkerReportsProgress)
                            worker.ReportProgress(10, "Opened " + fileName);
                    }
                    catch (Exception)
                    {
                        throw new Exception("Excel unavailable");
                    }
                    int count = workBook.Sheets.Count;
    

    Is just extract from a bigger app built with Caliburn.Micro but you can see the point.

    Thursday, January 05, 2012 6:40 AM
  • Hi thanks for your feedback,

    When I attempt to reference a word PIA(Microsoft.Office.Interop.Word) in silverlight, I get the message:

    "You can't add a reference to Microsoft.Office.Interop.Word.dll as it was not built against the Silverlight runtime.
    Silverlight projects will only work with Silverlight assemblies"

    Any ideas why?

    Thursday, January 05, 2012 6:55 AM
  • Hi,

    you do not reference Office from SL! You shall work only through dynamic variables! What methods/properties are available you see in Console app. That's the point.

    Thursday, January 05, 2012 6:58 AM
  • Hi Chris

    FOLLOW UP

    the idea is to work with strongly typed Office objects in Console app and move the code to SL while replacing tese variables by dynamic, as Office types are not known. Methods and Properties are still available because are discovered at runtime. Somewhat similar to old COM Dispatch interfaces. Should you have any doubts, do not hesitate to ask.

    Thursday, January 05, 2012 7:11 AM
  • Hi Greg,

    Ok, I understand what you are saying. I've created a consol app and I'm first writing the code there. It helps to
    have intellisense.

    I appreciate your help,

    Chris

    Thursday, January 05, 2012 7:20 AM
  • Hi Greg,

    I can get my code to work in the consol app but it won't in Silverlight. Are there some methods/properties that are not supported in Silverlight when doing com automation, such as finding and replacing text.

    cheers,

    Chris

    Thursday, January 05, 2012 8:30 AM
  • Hi Chris,

    can you show me a sample? Console can do find/replace and through dynamic works not? I'd like to see it.

    Thursday, January 05, 2012 8:35 AM
  • Sure,

    Console code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using word = Microsoft.Office.Interop.Word;

    namespace Consoltesting
    {
        class Program
        {
            static void Main(string[] args)
            {
                word.Application wdapp = new word.Application();
                wdapp.Documents.Open("C:\\Users\\cjones\\Documents\\NetQT\\Templates\\NPProposal$.dot");
                wdapp.Visible = true;
                wdapp.ActiveDocument.SaveAs("C:\\Users\\cjones\\Documents\\NetQT\\Templates\\NPProposal$.doc");
                object missing = System.Type.Missing;
                object replaceAll = word.WdReplace.wdReplaceAll;
                wdapp.Selection.Find.ClearFormatting();
                wdapp.Selection.Find.Text = "DEFAULTDATE";
                wdapp.Selection.Find.Replacement.ClearFormatting();
                wdapp.Selection.Find.Replacement.Text = "05.12.2001";
                wdapp.Selection.Find.Execute(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref replaceAll, ref missing, ref missing, ref missing, ref missing);
                wdapp.ActiveDocument.Save();

            }
        }
    }

    Silverlight Code

    try
                {
                    dynamic word = AutomationFactory.CreateObject("Word.Application");
                   
                  
                    //Open template
                    word.Documents.Open("C:\\Users\\cjones\\Documents\\NetQT\\Templates\\NPProposal$.dot");
                    //Save doc document from template
                    word.ActiveDocument.SaveAs("C:\\Users\\cjones\\Documents\\NetQT\\Templates\\Test.doc");
                    
                     //Update default date
                    object missing = System.Type.Missing;
                    object replaceAll = word.WdReplace.wdReplaceAll; //Bugs here
                    word.Selection.Find.ClearFormatting();
                    word.Selection.Find.Text = "DEFAULTDATE";
                    word.Selection.Find.Replacement.ClearFormatting();
                    word.Selection.Find.Replacement.Text = "05.12.2001";
                    word.Selection.Find.Execute(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref replaceAll, ref missing, ref missing, ref missing, ref missing);

                    word.ActiveDocument.Save();
                    word.visible = true;
                   
                   
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    Thursday, January 05, 2012 8:45 AM
  • Hi Chris,

    in console app I got exception pretty quickly Frown. There's a similar thema here http://msdn.microsoft.com/en-us/library/ee441250(v=office.12).aspx but I don't know which version of Word you are supposed to use: 2003/2007/2010? Approach differs depending on version. I do not think it is a problem with dynamic/SL, rather with automating Word. Still interested? I would gladly invest some more time in investigation...

    Cheers, Greg

    Thursday, January 05, 2012 9:50 AM
  • Hi Greg,

    I am currently testing this on word 2007. I do not get an exception with the console app however.

    I'm still trying to fix this, so any help you can provide would be very much appreciated.

    Thanks,

    Chris

    Thursday, January 05, 2012 9:56 AM
  • Sorry, the question is about document type: docx family is essentally XML making usage of Word automation needless. Seems to be viable alternative presumed Open XML SDK is installed - is free, Word is not.

    Thursday, January 05, 2012 10:11 AM
  • Hi Chris, no offence, on another comp is gone.

    Reflector told me that wdReplaceAll is 2. Simply set the value and it works in SL4.

    Cheers, Greg

    Friday, January 06, 2012 7:24 AM
  • Hi Greg,

    That has worked perfectly, thanks a lot for your help.

    Cheers,

    Chris

    Friday, January 06, 2012 8:06 AM
  •  Word.WdReplace.wdReplaceAll;  es un enumerado

    1. wdReplaceAll- Replaces all found items

    2.-wdReplaceNone - Replaces none of the found items.

    3.- wdReplaceOne - Replaces the first found item.

    solucion:

    object replaceAll = 1; probado en silverligth 5

    Wednesday, May 23, 2012 1:25 PM