You could try turning off "Validating" and see if that speeds things up.
app.Validating = 0;
When the script is done, turn it back on:
app.Validating = 1;
I'm actually doing that, along with temporarily turning off notifications (Pre/Post InsertElement, ChangeElement, SetAttrValue, etc.), and app.Displaying, Reformating, AutoSave, AutoBackup. All those together reduce the total time about a second or two on inserting something like 250 elements, no difference on smaller numbers.
It seems as if FrameMaker is doing something, automatically, but I don't what that is. (I don't even know how to describe it.) When the element is inserted at the end, it's like FrameMaker goes through the compelte node, starting with the first element (first child of the parent), all the way to the last element just inserted. I tried reversing how elements are inserted, inserting new elements at the beginning instead of at the end and get the same results.
For S&G's, I added Console("Delete " + $.hiresTimer); to the part of the function that deletes the previous elements before the new elements are inserted. The first element deleted takes the longest and progressively takes less and less time as each element is deleted.
Any other thoughts are appreciated.
If I turn off ApplyFormatRules (app.ApplyFormatRules = 0;) before inserting the elements (then turning it back on at the end), it takes under a second to delete the previous elements and add all 250+ new elements.
The element being inserted is defined as "General rule: <EMPTY>" and "Text format - rules In all contexts. - Text range.", the element doesn't take up space or adds new paragraph. But since ApplyFormatRules is off when the elements are inserted, each element is inserted in a new paragraph. So now I get 250 empty paragraphs. Turning ApplyFormatRules back on, turning on app.Reformatting, and then doc.Reformat() doesn't change anything.
If I manually select just one of the inserted elements or their parent, select the Element Def in the Catalog and click Change, the new inserted elements are then reformatted properly and the paragraphs go away. So, I save the last inserted element object reference and added the following at the end of the function right before I turn back on the Displaying, Reformating, and Notifications:
app.ApplyFormatRules = 1;
LastInsElemRef.ElementDef = GVdoc.GetNamedElementDef(myElemDefName);
Which works and all happens within a second or so. Still, I'm curious if there is a better way, or at least a more definitive explanation of why or what is happening. Any thoughts?
I've seen this behavior ever since I started with the FDK over a decade ago. I never figured out why the operations progressively took longer.
My recommendation is to use copy/paste, rather than the insertion of a new object every time. That is, insert one, stick it on the clipboard, then paste the rest. It seems to work much better for me.
I seriously considered trying copy/paste and started to modify the code to do so. But I couldn't let it go, the answer had to be right there in front of me, just it's been too long since I've worked with this stuff, I'm not able to see it. Then it dawned on me what is happening.
In an earlier test, I placed a timer on each action that is looped through. For example, I start with an container element that has 200 children elements, each with a specific/unique model number attribute. All 200 existing elements are deleted and then replaced with 250 new elements with a different value for the model number attribute. The timer was placed after the Element.Delete() method and ElementDef.NewElementInHierarchy() method. What I noticed with the timer is that each element deleted was deleted faster than the previous element (so it progressively took less and less time to delete an element). And of course the opposite was noticed for inserting elements, each element inserted took longer than the previous element inserted.
These elements can be inserted in two areas of the structure, one of the areas has fewer format rules that impact the formatting and is actually a little quicker. This led me to the cause being the EDD format rules. The area that takes longer has quite a few extensive format rules that apply. Every time an element is inserted or deleted, FrameMaker runs through those rules to format the content of the elements. Since the rules apply to parent, first, last, next, previous, etc., FrameMaker has to apply format rules to all the elements in the structure that the rules apply to (which are extremely complex because of the various elements, attribute values, and combinations that can be inserted).
Removing or thinning down the FormatRules in the EDD, it does get quicker. But each of the FormatRules are needed. So using app.ApplyFormatRules = false; right before the elements are deleted and inserted works great. But the key is to set ApplyFormatRules back to true before deleting the last element to be deleted and before inserting the last element to be inserted, so it will cycle through all the format rules of the EDD for all the elements in the hierarchy those format rules apply to. Setting ApplyFormatRules to true and assigning the ElementDef to the last element also works [EleId.ElementDef = GV_doc.GetNamedElementDef(insElemType);], but only before any other functions are performed or different elements are added.
doc.Reformat() isn't going to reformat the content correctly after the fact because the element was created without the format rules, so it just reformats the content of the elements without the format rules.
The FDK version that was created 10 years ago had the same problem of running slow when a large number of elements were being inserted, but was still an improvement over having to manually insert each element and type in the attribute value, so it was lived with.
It's now working amazingly fast. I hope my explanation of what I think is happening, including the cause/solution, is understandable.