0

So I'm trying to put together code for replacing certain unique sentences into a list for every type of checkedbox.checked for example:

"uniquecode1" into:

  • List item1
  • List item2

I had managed to use the simple find and replace method from c# word interop find and replace everything But I still haven't found a way to convert those into a list item. There was a moment I thought why don't I do it this way?

for (int i = 0; i == checkedbox.Count; i++)
            {
                FindAndReplace(oWord, "uniquecode1", checkedbox[i]);
            }

and then I realize once the "uniquecode1" is gone it's pretty much failed. I really appreciate it if someone can give me an answer or at least a clue. This is my current code, I know it's dirty...

string[] Mycollection = new string[] { "One, Two, Three" };
            string temp;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "pdf files (*.pdf)|*.pdf";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;
            saveFileDialog1.ShowDialog();
            temp = saveFileDialog1.FileName;

            // Create an instance of Word.exe
            Microsoft.Office.Interop.Word.Application oWord = new Word.Application
            {
                // To make this instance of word invisible (Can still see it in the taskmgr).
                Visible = false
            };

            // Interop requires objects.
            object oMissing = System.Reflection.Missing.Value;
            object isVisible = true;
            object readOnly = true;     // Does not cause any word dialog to show up
            //object readOnly = false;  // Causes a word object dialog to show at the end of the conversion
            object oInput = textBox1.Text;
            object oOutput = temp;
            object oFormat = WdSaveFormat.wdFormatPDF;

            // Load a document into our instance of word.exe
            Document oDoc = oWord.Documents.Open(
                ref oInput, ref oMissing, ref readOnly, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                ref oMissing, ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing
                );

            // Make this document the active document.
            oDoc.Activate();
            //Replace Text1
            FindAndReplace(oWord, "<Input Module1>", richTextBox1.Text);
            //Replace Text to List1
            foreach(string lisText in Mycollection)
            {
                //program to convert Text into a bullet or number list
            }

                // Save this document using Word
                oDoc.SaveAs(ref oOutput, ref oFormat, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing
                );

            // Always close Word.exe.
            oWord.Quit(ref oMissing, ref oMissing, ref oMissing);

As per Sauntinsoft they used

string loadPath = @"..\..\example.docx";

            DocumentCore dc = DocumentCore.Load(loadPath);
            string[] myCollection = new string[] { "One", "Two", "Three", "Four", "Five" };

            ListStyle bullList = new ListStyle("Bullets", ListTemplateType.Bullet);
            dc.Styles.Add(bullList);
            int level = 0;

            List<Paragraph> parList = new List<Paragraph>();


            foreach (string listText in myCollection)
            {
                Paragraph p = new Paragraph(dc);
                p.Content.End.Insert(listText, new CharacterFormat() { Size = 14.0, FontColor = Color.Black });
                p.ListFormat.Style = bullList;
                p.ListFormat.ListLevelNumber = level;
                p.ParagraphFormat.SpaceAfter = 0;
                parList.Add(p);
            }

            Regex regex = new Regex(@"Hello", RegexOptions.IgnoreCase);


            foreach (ContentRange item in dc.Content.Find(regex).Reverse())
            {
                foreach (Paragraph p in parList.Reverse<Paragraph>())
                    item.End.Insert(p.Content);               
            }

            foreach (ContentRange item in dc.Content.Find(regex).Reverse())
            {
                item.Delete();
            }
            string savePath = Path.ChangeExtension(loadPath, ".replaced.docx");
            dc.Save(savePath, SaveOptions.DocxDefault);

            // Open the original and result documents for demonstration purposes.
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(loadPath) { UseShellExecute = true });
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(savePath) { UseShellExecute = true });
braX
  • 11,506
  • 5
  • 20
  • 33
  • IMO you should also consider how many **uniquecode1** in the Word you have, so it wont fail when your `checkbox count` is more than your **uniquecode1** `count`. – Raynoceros Feb 21 '20 at 07:18
  • I figured that it would be too troublesome to put so many **uniquecode1** in the word, so I put that idea away. I tried to use the _sautinsoft_ and it worked wonderfully, but god the prices are a big no. Right now I'm trying to find the equal code that has the same result as theirs – からげー Feb 21 '20 at 07:40
  • so you are only using _sautinsoft_ to do find and replace? what else you are using it for? – Raynoceros Feb 21 '20 at 07:47
  • I was, that is until I realize it needed a license to operate fully. I used Sautinsoft at first to find and replace texts, text into a list(Current problem) and text to images. – からげー Feb 21 '20 at 07:53
  • text into a list, can you explain more like how it do and demonstrate some of your examples. – Raynoceros Feb 21 '20 at 09:19
  • Edited with my code and Sautin's. I know that Interop.word and Sautin used an entirely different code, which is why I prepare this question for whoever in a tight spot just like mine and don't want to spend a buck. – からげー Feb 21 '20 at 10:24

1 Answers1

1

Doing it with the interop is a multi-step process. First it's necessary to find the target - the text being searched. Then insert the information into that Range and, finally, format it.

Word's Find.Execute returns a Boolean - when successful it's true and the Range on which Find is run is in the found location. So add the text to the Range, then format that Range, as demonstrated in the sample code*:

Word.Document doc = wdApp.ActiveDocument;
//Code from question
//Document oDoc = oWord.Documents.Open(
//            ref oInput, ref oMissing, ref readOnly, ref oMissing, ref oMissing,
//            ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
//            ref oMissing, ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

Word.Range rng = doc.Content;
Word.Find f = rng.Find;
object oTrue = true;
object missing = Type.Missing;

string searchTerm = "uniquecode1";

f.ClearFormatting();
f.Text = searchTerm;
bool found = f.Execute(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, Word.WdFindWrap.wdFindStop, ref missing, ref missing, Word.WdReplace.wdReplaceNone,
    ref  missing, ref missing, ref missing, ref missing);
if (found)
{
    rng.Delete();
    //Code from question
    //for (int i = 0; i == checkedbox.Count; i++)
    List<string> lst = new List<string> { "one", "two", "three" };
    foreach (string entry in lst)
    {
        rng.InsertAfter(entry + "\n");
    }
    rng.ListFormat.ApplyBulletDefault();
}

* Given the requirements as I understand them in the question, this could be done entirely using Find & Replace if:

  • The Replacement.Text can be one string. In this example, that would be possible by concatenating all the values into one string before the Find and assigning the string to f.Replacement.Text. Then the parameter Word.WdReplace.wdReplaceNone would be wdReplaceOne.
  • The bullets/numbering are defined as a named style. This would require a paragraph style in the document (or dynamically generated by the code) that links to a ListTemplate object that defines the bullet and/or numbering. Assuming that is present, the style can be assigned to Replacement.set_Style("stylename"); and then the parameter Format would need to be set to true.

This is essentially what's going on behind the scenes with the library you don't want to pay for.

Cindy Meister
  • 25,071
  • 21
  • 34
  • 43