Question

I have a DataGridView in my Form. What i am trying to do is if a user select a row and press Button(button_1) data from that row should be send to a word document and replace a number according to the column[i]. Now with the code below
Problem 1 when i select one row and click the button, data finds and replaces number in Word file, But it replaces all the occurrences of for example "1" but i only want it to be done once because i want to do it for each row. Problem 2 if a user select More than one row only last selected row data is exported. Any Ideas??

    private void button1_Click(object sender, EventArgs e)
    {

        string SendPath = "";

        if (openFileDialogWord.ShowDialog(this) == DialogResult.OK)
        {
            SendPath =  (openFileDialogWord.InitialDirectory + openFileDialogWord.FileName).ToString();
        }


        WordDoc(SendPath);
    }



    public void WordDoc(string getfilename)
    {



        object FileName = getfilename; //The filepath goes here


        //Create word Application Object
        Word.Application word = new Word.Application();

        //Create word document Object
        Word.Document doc = null;

        //Create word Missing Object
        object missing = System.Type.Missing;

        object readOnly = false;
        object isVisible = false;
        // make visible Word application
        word.Visible = true;

        try
        {
            doc = word.Documents.Open(ref FileName, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing);
            doc.Activate();




            string Column1;
            string Column2;

            foreach (DataGridViewRow rows in dataGridView1.SelectedRows)
            {


                Column1 = rows.Cells[1].Value.ToString();
                Column2 = rows.Cells[2].Value.ToString();

                this.FindAndReplace(word, "1", Column1);
                this.FindAndReplace(word, "2", Column2);

            }

            MessageBox.Show("Complete");


        }
        catch (Exception ex)
        {
            MessageBox.Show("Error : " + ex.Message);
        }
    }



    private void FindAndReplace(Word.Application word, object findText, object replaceText)
    {
        object matchCase = true;
        object matchWholeWord = true;
        object matchWildCards = false;
        object matchSoundsLike = false;
        object matchAllWordForms = false;
        object forward = true;
        object format = false;
        object matchKashida = false;
        object matchDiacritics = false;
        object matchAlefHamza = false;
        object matchControl = false;
        object read_only = false;
        object visible = true;
        object replace = 2;
        object wrap = 1;
        word.Selection.Find.Execute(ref findText, ref matchCase,
        ref matchWholeWord, ref matchWildCards, ref matchSoundsLike,
        ref matchAllWordForms, ref forward, ref wrap, ref format,
        ref replaceText, ref replace, ref matchKashida,
        ref matchDiacritics,
        ref matchAlefHamza, ref matchControl);
    }
Was it helpful?

Solution

The Problem was with this Part

object replace = 2;

I found the solution at DreaminCode

Replaced object replace = 2; with object replace = 1; and it is working Perfect.

OTHER TIPS

If you are interested, you can try our 3rd party GemBox.Document library to get required effect in easier manner. Issues with your current approach are following:

  1. using hardcoded strings "1", "2",... as placeholders is error-prone
  2. it is hard or even impossible to import multiple rows with search & replace without having complicated template file
  3. your application can only be ran on computers which have MS Word installed, since it uses Word Interop.

With our component you can easily perform data import of all selected DataGridView rows to a Word document. Here is a sample C# code how to do it using the mail merge:

        // Create data source for DataGridView.
        var people = new DataTable()
        {
            Columns = 
            {
                new DataColumn("Name", typeof(string)),
                new DataColumn("Surname", typeof(string))
            },
            Rows =
            {
                { "John", "Doe" },
                { "Fred", "Nurk" },
                { "Hans", "Meier" },
                { "Ivan", "Horvat" }
            }
        };

        // Create DataGridView and show it to select rows.
        var dataGridView = new DataGridView()
        {
            DataSource = people,
            Dock = DockStyle.Fill
        };
        new Form() { Controls = { dataGridView } }.ShowDialog();

        // Get selected items which will be used as data source for mail merge.
        var selectedItems = dataGridView.SelectedRows.Cast<DataGridViewRow>().Select(dgvRow => dgvRow.DataBoundItem).ToArray();

        // Create template document which is usually created with MS Word application and loaded with GemBox.Document library.
        // This code just shows the structure of the template document.
        var doc = new DocumentModel();
        doc.Sections.Add(
            new Section(doc,
                new Table(doc,
                    new TableRow(doc,
                        new TableCell(doc,
                            new Paragraph(doc,
                                new Run(doc, "Name") { CharacterFormat = { Bold = true } })),
                        new TableCell(doc,
                            new Paragraph(doc,
                                new Run(doc, "Surname") { CharacterFormat = { Bold = true } })))
                    {
                        RowFormat = { RepeatOnEachPage = true }
                    },
                    new TableRow(doc,
                        new TableCell(doc,
                            new Paragraph(doc,
                                new Field(doc, FieldType.MergeField, "RangeStart:SelectedPeople"),
                                new Field(doc, FieldType.MergeField, "Name"))),
                        new TableCell(doc,
                            new Paragraph(doc,
                                new Field(doc, FieldType.MergeField, "Surname"),
                                new Field(doc, FieldType.MergeField, "RangeEnd:SelectedPeople")))))
                { 
                    TableFormat = { PreferredWidth = new TableWidth(100, TableWidthUnit.Percentage) } 
                }));

        // Execute mail merge. All selected people will be imported into the document.
        doc.MailMerge.Execute(selectedItems, "SelectedPeople");

        // Save document in DOCX and PDF formats.
        doc.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SelectedPeople.docx"));
        doc.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SelectedPeople.pdf"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top