Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Transactions and Document Events

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
Troy_Gates
3048 Views, 10 Replies

Transactions and Document Events

I am trying to figure out a way to undo a previous transaction that I have committed from a future transaction. 

 

Backstory: I am doing some stuff during the DocumentPrintingEventArgs event and then allowing the print to happen. Then I am reverting all the stuff I did after the print using the DocumentPrintedEventArgs event as I don't want the changes to be permanent.

 

This is taking a lot of code to do, plus the larger/more complex the model, the longer it takes the code to run. I was wondering if I could roll back the previous transaction that happened during the PrintingEvent from the PrintedEvent? Or is it possible for a transaction to span these two events?

 

Thanks

10 REPLIES 10
Message 2 of 11
jeremytammik
in reply to: Troy_Gates

Dear Troy,

 

The only possibility that I know of that remotely aproaches what you are asking for is to wrap all of your transactions in a transaction group, commit the transactions that you need to commit, and then roll back the entire transaction group without committing it.

 

However, I do not know whether it is possible to launch a call to print within an open transaction group. I suspect not.

 

Here are two exlanation of transactions, sub-transactions, transaction groups and using transaction groups:

 

http://thebuildingcoder.typepad.com/blog/2013/04/transactions-sub-transactions-and-transaction-group...

 

http://thebuildingcoder.typepad.com/blog/2015/02/using-transaction-groups.html

 

That covers about all that you can achieve in this area programmatically.

 

If you really have to launch the print command, and that cannot be achieved within your own open transaction group, then I guess you would have to take recourse to the Revit Undo command instead, to roll back the already committed transactions.

 

I do not know whether the Undo command can be driven programmatically, e.g. using the PostCommand method:

 

http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.3

 

If all else fails, how about saving your document before printing it, creating a copy for the complicated printing process you describe, and then reverting back to the original document once that is done?

 

Please KISS, always and everywhere!

 

https://en.wikipedia.org/wiki/KISS_principle

 

Also please let us know how it goes and how you end up solving this. 

 

It sounds like an interesting topic for a more in-depth discussion  🙂

 

I hope this helps.

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 11
arnostlobel
in reply to: jeremytammik

Hello Troy:

 

I am afraid there is no solution to what you want to do. There is no tie between the pair of events (pre and post printing) and any transactions that happen during either of the events are unrelated.

 

Revit API does not allow undoing transactions for a reason: mainly to avoid external application to block each other. However, even if undoing was allowed, it is unlikely to help in cases like yours, because you can never be sure that your transaction was the latest finished and it is impossible to undo transaction that are further down the undo stack (without undoing later transactions, of course). There may be number of application subscribed to printing events, and it may be different applications subscribed to each of the two events. Any of the applications in any of the events can have multiple transaction that they would not like to be redone by some other application. There is simply no way around that problem.

 

Jeremy mentioned using transaction groups to wrap your transactions in, but that is not an option in this case either. For your transactions happen during an event (not a command) we do not allow any even handler to leave any transaction-related scope (such a transaction, transaction group, etc.) open upon returning from the handler. If Revit sees such a scope left open, it forces it to close and then deletes everything that the handler has done to the model.

 

Like I said, there is really nothing that can be done. It's not like we haven't thought about it, but considering all the implications we cannot provide a save and stable solution.

 

I would of course like to ask you why does it need to be redone what you needed to do before printing. I assume you need to add something that gets printed, but why cannot that stay with the model? Of course you have your reasons for it; I am just wondering.

 

Thank you

Arnošt Löbel
Message 4 of 11
Troy_Gates
in reply to: arnostlobel

Thank you both. I knew it was kind of a shot in the dark, but was hopeful there might be a way. I will continue on with my original route of undoing everything through my own code.

Message 5 of 11
jeremytammik
in reply to: Troy_Gates

Dear Troy,

 

Thank you for raising it.

 

I published it for posterity:

 

http://thebuildingcoder.typepad.com/blog/2015/09/family-category-element-ids-transaction-undo-and-up...

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 11
DG_Odeh
in reply to: Troy_Gates

Reviving this thread as I came across the same exact problem as Troy.

 

I need to perform adjustments to object styles before printing, and I am doing that within the Printing event.

 

However, this changes need to be rolled back once the print is over. Right now I am keeping track of my changes and undoing them in a separate transaction in the Printed event. The issue is that the changes are far reaching and the model needs to be completely regenerated both when the changes are applied (before print) and when they are reverted (after print). If I undo the first transaction manually the document doesn't need to regenerate and it takes half the time.

 

Arnost, you mentioned there is no reliable way to allow an application to Undo a previous Transaction and I understand all the points you raised. For the sake of speculation, would it be possible to allow the API to Undo a transaction by name, and perform the operation only if that's the last transaction in the Undo Stack?

Message 7 of 11
RPTHOMAS108
in reply to: DG_Odeh

If you could undo the last transaction by name and that transaction turned out not to be your transaction then how would that help you? Would you abandon your need to change the object styles back, if last transaction found is not yours?

 

Have you considered applying a temporary view template to the views and then switching back afterwards? This perhaps may not cause as much delay because the objects used would be there already and you are just using them or not.

Message 8 of 11
jlpgy
in reply to: arnostlobel

Hi Arnost Lobel:

I have noticed that in PostableCommand enumeration in RevitAPIUI.dll ver. 2019, there is a Undo value.

单身狗;代码狗;健身狗;jolinpiggy@hotmail.com
Message 9 of 11
stefanome
in reply to: DG_Odeh

I would love to be able to undo the last command by name.

 

In my case I have a modeless form with a list of items and when I click an item, something is created in Revit. After clicking 20-30 times I end up with an ugly and useless undo stack.

 

I would like to do something like Undo("TempStuff"); or if (UndoStep[0].Name == "TempStuff") Undo();

 

In Inventor I would use transient geometries, but in Revit I need to create actual geometries, which end up bothering the undo stack.

Message 10 of 11
rhanzlick
in reply to: Troy_Gates

As an answer to the original question, would committing/assimilating all transactions/groups, printing, then calling Document.Close(false); work? this might allow you to make changes, then print, then close the document without saving.

 

for stefanomeci, you can start a transaction, do some things, then roll back? or assimilate all of your changes into a transactionGroup (this will clean up the Undo stack). As far as I know, transactions are always Last-In-First-Out. meaning transactions can only be rolled-back in reverse chronological order.

Message 11 of 11
DG_Odeh
in reply to: arnostlobel


@arnostlobel wrote:

 

Like I said, there is really nothing that can be done. It's not like we haven't thought about it, but considering all the implications we cannot provide a save and stable solution.

 


Four years later the Undo command was added to the PostableCommands Enum, without knowledge of what the last transaction name is afaik. Is this a stable solution? Why can't we access a list of Transaction to check if a certain transaction is last? We could use a GUID as the Transaction name! 🙂

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community