how to update images in word document quickly and efficiently which are added as fields(FieldType: includepicture)

AJ TSN 1 Reputation point
2020-10-27T14:00:21.717+00:00

what we tried as is working for us

  1. looping through the doc.paragraphs
  2. inside the loop we are reading the field code

-- the field is represented as

{INCLUDEPICTURE "M:\NVCSync\Testing 7.16.2020.1\Hotel Excel 7.16.1\ExcelTables\T_TestSum.emf"}

so for example we have image like T_TestSum.emf

3.after finding image we are selecting that image range, deleting it and adding the field again.(so that the refeshed image is updated)

Word.Field field = r.Fields.Add(r, Word.WdFieldType.wdFieldIncludePicture, "\"" + vtablelocation.Replace(@"\", @"\") + "\"", preserveformatting);

The above logic works for us, but we have performance bottle neck.

for 200+ images its taking over 120 secs to update.

other ways msdn suggests is

  1. select all fields in documents and update each field.
            doc.Range(ref start, ref end).Select();
            try
            {
                foreach (Word.Field field in doc.Fields)
                {
                    field.UpdateSource();
                }
            }
            catch (Exception ex)
            {
    
            } 
    
            the above code works for smaller documents, images update quickly.
            it fails to update the images if documents are bigger(we didnt get any errors)
    
  2. we tried to use async await way of updating the fields but its giving worst performance.

3.parallel.foreach seems to be working but with larger file and many images to update it fails giving us ContextSwitchDeadlock error.

private static async Task UpdateDocumentTableswithouttasking()
        {
            Word.Application appW = Globals.ThisAddIn.Application;
            Word.Document doc = appW.ActiveDocument;
            doc.Fields.ToggleShowCodes();
            try
            {
                Microsoft.Office.Interop.Word.Paragraphs DocPar = doc.Paragraphs;
                foreach (var par in DocPar)
                {
                    Word.Paragraph p = (Word.Paragraph)par;
                    string s = p.Range.Text.ToString();
                    Word.Range pb = p.Range;
                    if (!String.IsNullOrEmpty(s) && (s.Contains("INCLUDEPICTURE")) || (s.Contains("DOCVARIABLE") && s.Contains("PICTURECUSTOM")) && s != "\r")
                    {
                        var alignment = p.Range.ParagraphFormat.Alignment;
                        Word.WdColorIndex color = p.Range.HighlightColorIndex;
                        List<DocumentTables> lstDocTables = new List<DocumentTables>();
                        List<DocumentVars> lstDocFields = new List<DocumentVars>();
                        string[] arr = new string[] { };
                        string[] arrDocVarsAndPictures = new string[] { };
                        if (s.Contains("LINK"))
                        {
                            arrDocVarsAndPictures = s.Split(new string[] { "LINK" }, StringSplitOptions.None);
                        }
                        else
                        {
                            arrDocVarsAndPictures = s.Split(new string[] { "DOCVARIABLE" }, StringSplitOptions.None);
                        }
                        for (int cnt = arrDocVarsAndPictures.Length - 1; cnt >= 0; cnt--)
                        {
                            string strArr = arrDocVarsAndPictures[cnt].ToString();
                            string[] ArrwithImages = strArr.Split(new string[] { "INCLUDEPICTURE" }, StringSplitOptions.None);
                            if (ArrwithImages.Length > 0)
                            {
                                for (int cntImages = ArrwithImages.Length - 1; cntImages >= 0; cntImages--)
                                {
                                    string strArrWithImages = ArrwithImages[cntImages].ToString();
                                    //This means the field is for picture and used when mapping picture or showing error message.
                                    if (strArrWithImages.Contains("T_") || strArrWithImages.Contains("t_"))
                                    {
                                        try
                                        {
                                            string pattern = "\"";
                                            string SelectedField = "";
                                            if (strArrWithImages.Contains("T_"))
                                            {
                                                int i = strArrWithImages.IndexOf("T_");
                                                SelectedField = strArrWithImages.Substring(i + 0);
                                            }
                                            else if (strArrWithImages.Contains("t_"))
                                            {
                                                SelectedField = strArrWithImages.Substring(strArrWithImages.IndexOf("t_") + 0);
                                            }
                                            string[] arrF = SelectedField.Split(new string[] { pattern }, StringSplitOptions.None);
                                            string fieldName = arrF[0].Trim().Replace(strFileExtension, "").Replace(".jpg", "");

                                            var wrksht = "";
                                            if (strArrWithImages.Contains("Swrksht_"))
                                            {
                                                int i = strArrWithImages.IndexOf("Swrksht_");
                                                wrksht = strArrWithImages.Substring(i + 0);
                                                wrksht = wrksht.Split(new string[] { "_" }, StringSplitOptions.None)[1];
                                                if (wrksht == "T" && fieldName.Contains("_"))
                                                {
                                                    wrksht = "";
                                                }
                                            }
                                            foreach (Word.Field myMergeField in p.Range.Fields)
                                            {
                                                Word.Range rngFieldCode = myMergeField.Code;
                                                string fieldText = rngFieldCode.Text;
                                                string pattern1 = "\"";
                                                string SelectedField1 = "";
                                                if (fieldText.Contains("T_"))
                                                {
                                                    int i = fieldText.IndexOf("T_");
                                                    SelectedField1 = fieldText.Substring(i + 0);
                                                }
                                                else if (fieldText.Contains("t_"))
                                                {
                                                    SelectedField1 = fieldText.Substring(fieldText.IndexOf("t_") + 0);
                                                }
                                                if (SelectedField1.Contains("\\t"))
                                                {
                                                    pattern1 = "\\t";
                                                }

                                                string[] arrF1 = SelectedField1.Split(new string[] { pattern1 }, StringSplitOptions.None);
                                                string fieldName1 = arrF1[0].Trim().Replace(strFileExtension, "").Replace(".jpg", "");

                                                if (fieldName == fieldName1)
                                                {
                                                    myMergeField.Select();
                                                    Word.Range found = Globals.ThisAddIn.Application.Selection.Range;
                                                    Word.Selection s1 = Globals.ThisAddIn.Application.Selection;
                                                    s1.Range.Delete();
                                                    Word.Range r = Globals.ThisAddIn.Application.ActiveDocument.Range(found.Start, found.Start);

                                                    try
                                                    {
                                                        r.ParagraphFormat.Alignment = alignment;
                                                    }
                                                    catch (Exception ex)
                                                    {

                                                    }
                                                    //r.Select();
                                                    Globals.ThisAddIn.Application.Selection.Font.ColorIndex = Word.WdColorIndex.wdAuto;
                                                    TableInfo t = new TableInfo();
                                                    try
                                                    {
                                                        if (String.IsNullOrEmpty(wrksht))
                                                        {
                                                            t = ThisAddIn.lstTables.OrderBy(z => z.workSheetName).Where(x => x.Tablename == fieldName).FirstOrDefault();
                                                        }
                                                        else
                                                        {
                                                            t = ThisAddIn.lstTables.Where(x => x.Tablename == fieldName && x.worksheetCodename == wrksht).FirstOrDefault();
                                                        }

                                                        if (t != null)
                                                        {
                                                            if (!String.IsNullOrEmpty(t.Tablename))
                                                            {
                                                                //myMergeField.Update();
                                                                found.Font.ColorIndex = Word.WdColorIndex.wdBlack;
                                                                var vtablelocation = t.TableLocation.Replace("Swrksht_", "Swrksht_" + t.worksheetCodename + "_").Replace("Swrksht__", "Swrksht_").Replace("__", "_");
                                                                Word.Field field = r.Fields.Add(r, Word.WdFieldType.wdFieldIncludePicture, "\"" + vtablelocation.Replace(@"\", @"\\").Replace(strFileExtension, strFileExtension) + "\"", preserveformatting);
                                                                if (t.ApplySizing == 1)
                                                                {
                                                                    try
                                                                    {
                                                                        field.InlineShape.Height = (float)t.height;
                                                                    }
                                                                    catch
                                                                    {

                                                                    }
                                                                    try
                                                                    {
                                                                        field.InlineShape.Width = (float)t.width;
                                                                    }
                                                                    catch
                                                                    {

                                                                    }
                                                                }
                                                            }

                                                        }

                                                    }
                                                    catch (Exception ex)
                                                    {
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {

                                        }
                                    }
                                }
                            }
                        }
                        //}
                    }

                }


            }
            catch (Exception ex)
            {
                log.Error("\r\n" + "Error: Error occured while updating tables" + "\r\n" + ex);
            }
            doc.Fields.ToggleShowCodes();

            foreach (Word.Field field in doc.Fields)
            {
                var x = field.ShowCodes;
                if (x)
                {
                    field.ShowCodes = false;
                }
            }
        }   
Not Monitored
Not Monitored
Tag not monitored by Microsoft.
36,250 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Emi Zhang-MSFT 22,011 Reputation points Microsoft Vendor
    2020-10-28T07:56:34.05+00:00

    Hi @AJ TSN ,
    Based on your description, I suggest you post this issue to Word for Developer forum:

    https://social.msdn.microsoft.com/Forums/en-US/home?forum=worddev

    The reason why we recommend posting appropriately is you will get the most qualified pool of respondents, and other partners who read the forums regularly can either share their knowledge or learn from your interaction with us. Thank you for your understanding.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments