none
Creating Large Tables in Word Quickly RRS feed

  • Question

  • Hello All,

    I'm creating a sizable table (700+ rows) in a sizable document (215 pages).  
    It takes me roughly 5 minutes to create this table.

    I've escaped any document selection change events and have narrowed it down to just building the table.

    Without throwing up all my code on this page does anyone have tips to speed this up?

    I'm supporting Word 2010 and up and I have ScreenUpdating off.

    Also is it even possible to create and fill the table in memory, then stuff it into word versus instantiating like so:   table = range.Tables.Add(range, 2, 3);

    My theory is if the table is already apart of the document then every row I add and every cell I edit has some immediate impact in Word.  If I could just define the table, fill it, then jam it back into a Word range maybe it would be fast??!  I'm grasping at straws here but I'm taking any suggestion as a worthwhile approach no matter how far outside the box it is.


    Thank you,

    Nick Metnik

    Please mark my response as helpful if it has helped you in any way or as the answer if it is a valid solution.
    Blog
    LinkedIn


    • Edited by Nicklaus Metnik Friday, March 21, 2014 7:42 PM Added additional info
    Friday, March 21, 2014 7:30 PM

Answers

  • I don't know about table creation in memory, though you could create one as a string that consists of the relevant html coding, write that to a file, then import it. Indeed, you could skip the file creation/import; instead, copy the html string to the clipboard then insert it into Word in html format. For that, see: http://support.microsoft.com/kb/274326.

    At its most basic, the html code for a 2*2 table might look like:

    StrHTML = "<html>" & _
      "<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0" & _
      " style='border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;" & _
      " mso-padding-alt:0pt 0pt'>" & _
      " <tr>" & _
      "  <p class=MsoNormal>Cell A1</p>" & _
      "  </td>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell B1</p>" & _
      "  </td>" & _
      " </tr>" & _
      " <tr>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell A2</p>" & _
      "  </td>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell B2</p>" & _
      "  </td>" & _
      " </tr>" & _
      "</table>" & _
      "</html>"

    I'd probably be inclined to leave the finer points of the table's formatting for post-insertion processing.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Saturday, March 22, 2014 7:15 AM

All replies

  • If automatic column widths are enabled for a table, the constant re-calculation of the column widths after any string manipulation will slow down the macro’s execution. The impact can be significant with long tables. To avoid this, either set:
    Tbl.AllowAutoFit = False
    or:
    Tbl.AutoFitBehavior wdAutoFitFixed
    where 'Tbl' is a variable referencing your table.

    Another approach that might be much faster is to populate the document with the table content, but no table, then use the Text to Table conversion to turn the content into a table after that's done.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, March 21, 2014 11:01 PM
  • Thank you Paul.  I have it set to Fixed already thinking that may impact the speed.  The other approach will take some time to re-write but I'm willing to try anything at this point.  

    As far as you know is it possible to create a table in memory without it being committed/attached to a range then inserted afterwards?  I thought maybe I could accomplish this by creating a new range and initialize the table from that range but Word definitely does not want me to call "new Range()".  

    I'm also repeating the first two rows on every page by setting:  table.Rows[1].HeadingFormat = -1;

    I'm going to turn that off and give it a go then turn it back on at the end.  

    Thank you for your thoughts and help sir :)


    Thank you,

    Nick Metnik

    Please mark my response as helpful if it has helped you in any way or as the answer if it is a valid solution.
    Blog
    LinkedIn

    Saturday, March 22, 2014 5:18 AM
  • I don't know about table creation in memory, though you could create one as a string that consists of the relevant html coding, write that to a file, then import it. Indeed, you could skip the file creation/import; instead, copy the html string to the clipboard then insert it into Word in html format. For that, see: http://support.microsoft.com/kb/274326.

    At its most basic, the html code for a 2*2 table might look like:

    StrHTML = "<html>" & _
      "<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0" & _
      " style='border-collapse:collapse;border:none;mso-border-alt:solid windowtext .5pt;" & _
      " mso-padding-alt:0pt 0pt'>" & _
      " <tr>" & _
      "  <p class=MsoNormal>Cell A1</p>" & _
      "  </td>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell B1</p>" & _
      "  </td>" & _
      " </tr>" & _
      " <tr>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell A2</p>" & _
      "  </td>" & _
      "  <td>" & _
      "  <p class=MsoNormal>Cell B2</p>" & _
      "  </td>" & _
      " </tr>" & _
      "</table>" & _
      "</html>"

    I'd probably be inclined to leave the finer points of the table's formatting for post-insertion processing.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Saturday, March 22, 2014 7:15 AM
  • Hi Nick,

    Another thing to try is switching to Draft View versus Print Layout View. On large table based documents with lots of images being inserted, I've gotten better speed results by doing that.


    Kind Regards, Rich ... http://greatcirclelearning.com

    Monday, March 24, 2014 2:31 AM
  • Thank you Rich.  That saved me another 20 seconds.

    Thank you Paul!  I'm using your approach minus the clipboard part.  I'm building my string and delimiting by "\t".  The code below produces a table but it seems that Word could care less about my delimiter.  It's delimiting by my "\r\n" in my string and I don't see why?!

             

    range.Text = html.ToString().TrimEnd('\t');             

    Table table = range.ConvertToTable(WdTableFieldSeparator.wdSeparateByTabs, range.Text.Split('\t').Length / 3, 3);


    As you can see I'm stuffing the string in (it really isn't html in this case, just delimited text) then I'm specifying the row count and column count.

    This is definitely the correct approach since it now takes roughly 50 seconds to build my table which is a huge gain.


    Thank you,

    Nick Metnik

    Please mark my response as helpful if it has helped you in any way or as the answer if it is a valid solution.
    Blog
    LinkedIn

    Monday, March 24, 2014 3:07 PM
  • According to the VBA help, the Split delimiter is a single character. Thus it's only seeing the '\'.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, March 24, 2014 11:27 PM
  • You could also try building the table in Word 2003 XML or FLat OPC format (either way you will need to build a complete Word XML file, not just the XML for the table). Then you can use the .InsertXML property of the range to insert it.

    You can see what the XML for a particular table looks like by saving as Word 2003 XML or XML ("Flat OPC") format.

    Whether that will be slower or faster than inserting HTML I cannot tell you, but you will avoid a clipboard operation.

    If you want to insert data as well as structure, you may need to "escape" it if you have characters such as "<" and so on in your data.


    Peter Jamieson

    Tuesday, March 25, 2014 3:43 PM
  • Thank you all for your feedback.  Collectively each piece of advice was a great contribution.  My main goal was to gain speed and every comment was fruitful.

    I went with Paul's method.  Even though I shy from the clipboard this at least got me passed my issue.  

    Also ConvertToTable wouldn't work no matter what I did.

    I would try Peter's way above using XML but I'm at the point where I need to move on with whatever worked first although his way looks a lot more promising.  I don't have a lot of XML knowledge when it comes to Word anyway.

    One gotcha on the clipboard approach is if you have Skype and any browser is open the clipboard paste will error with "Command failed".  My quirky workaround is to politely kill open browsers (I hate it but that's good for now).

    Take care and thanks again!


    Thank you,

    Nick Metnik

    Please mark my response as helpful if it has helped you in any way or as the answer if it is a valid solution.
    Blog
    LinkedIn

    Tuesday, March 25, 2014 8:05 PM