public static void ExecuteSubTransaction(Document document, Action action) { using (var subTransaction = new SubTransaction(document)) { try { if (subTransaction.Start() == TransactionStatus.Started) { action?.Invoke(); } if (subTransaction.Commit() != TransactionStatus.Committed) { subTransaction.RollBack(); } } catch (Exception) { if (subTransaction.HasStarted()) { subTransaction.RollBack(); } throw; } } }
public bool HasStarted() { if (transaction is object) { return(transaction.HasStarted()); } if (subTransaction is object) { return(subTransaction.HasStarted()); } return(false); }
/// <summary> /// Some preparation and check before creating room. /// </summary> /// <param name="curPhase">Current phase used to create room, all rooms will be created in this phase.</param> /// <returns>Number indicates how many new rooms were created.</returns> private int RoomCreationStart() { int nNewRoomsSize = 0; // transaction is used to cancel room creation when exception occurs SubTransaction myTransaction = new SubTransaction(m_document); try { // Preparation before room creation starts Phase curPhase = null; if (!RoomCreationPreparation(ref curPhase)) { return(0); } // get all existing rooms which have mapped to spreadsheet rooms. // we should skip the creation for those spreadsheet rooms which have been mapped by Revit rooms. Dictionary <int, string> existingRooms = new Dictionary <int, string>(); foreach (Room room in m_roomData.Rooms) { Parameter sharedParameter = room.LookupParameter(RoomsData.SharedParam); if (null != sharedParameter && false == String.IsNullOrEmpty(sharedParameter.AsString())) { existingRooms.Add(room.Id.IntegerValue, sharedParameter.AsString()); } } #region Rooms Creation and Set myTransaction.Start(); // create rooms with spread sheet based rooms data for (int row = 0; row < m_spreadRoomsTable.Rows.Count; row++) { // get the ID column value and use it to check whether this spreadsheet room is mapped by Revit room. String externaId = m_spreadRoomsTable.Rows[row][RoomsData.RoomID].ToString(); if (existingRooms.ContainsValue(externaId)) { // skip the spreadsheet room creation if it's mapped by Revit room continue; } // create rooms in specified phase, but without placing them. Room newRoom = m_document.Create.NewRoom(curPhase); if (null == newRoom) { // abort the room creation and pop up failure message myTransaction.RollBack(); MyMessageBox("Create room failed.", MessageBoxIcon.Warning); return(0); } // set the shared parameter's value of Revit room Parameter sharedParam = newRoom.LookupParameter(RoomsData.SharedParam); if (null == sharedParam) { // abort the room creation and pop up failure message myTransaction.RollBack(); MyMessageBox("Failed to get shared parameter, please try again.", MessageBoxIcon.Warning); return(0); } else { sharedParam.Set(externaId); } // Update this new room with values of spreadsheet UpdateNewRoom(newRoom, row); // remember how many new rooms were created, based on spread sheet data nNewRoomsSize++; } // end this transaction if create all rooms successfully. myTransaction.Commit(); #endregion } catch (Exception ex) { // cancel this time transaction when exception occurs if (myTransaction.HasStarted()) { myTransaction.RollBack(); } MyMessageBox(ex.Message, MessageBoxIcon.Warning); return(0); } // output unplaced rooms creation message String strMessage = string.Empty; int nSkippedRooms = m_spreadRoomsTable.Rows.Count - nNewRoomsSize; if (nSkippedRooms > 0) { strMessage = string.Format("{0} unplaced {1} created successfully.\r\n{2} skipped, {3}", nNewRoomsSize, (nNewRoomsSize > 1) ? ("rooms were") : ("room was"), nSkippedRooms.ToString() + ((nSkippedRooms > 1) ? (" were") : (" was")), (nSkippedRooms > 1) ? ("because they were already mapped by Revit rooms.") : ("because it was already mapped by Revit rooms.")); } else { strMessage = string.Format("{0} unplaced {1} created successfully.", nNewRoomsSize, (nNewRoomsSize > 1) ? ("rooms were") : ("room was")); } // output creation message MyMessageBox(strMessage, MessageBoxIcon.Information); return(nNewRoomsSize); }
/// <summary> /// Some preparation and check before creating room. /// </summary> /// <param name="curPhase">Current phase used to create room, all rooms will be created in this phase.</param> /// <returns>Number indicates how many new rooms were created.</returns> private int RoomCreationStart() { int nNewRoomsSize = 0; // transaction is used to cancel room creation when exception occurs SubTransaction myTransaction = new SubTransaction(m_document); try { // Preparation before room creation starts Phase curPhase = null; if (!RoomCreationPreparation(ref curPhase)) { return 0; } // get all existing rooms which have mapped to spreadsheet rooms. // we should skip the creation for those spreadsheet rooms which have been mapped by Revit rooms. Dictionary<int, string> existingRooms = new Dictionary<int, string>(); foreach (Room room in m_roomData.Rooms) { Parameter sharedParameter = room.get_Parameter(RoomsData.SharedParam); if (null != sharedParameter && false == String.IsNullOrEmpty(sharedParameter.AsString())) { existingRooms.Add(room.Id.IntegerValue, sharedParameter.AsString()); } } #region Rooms Creation and Set myTransaction.Start(); // create rooms with spread sheet based rooms data for (int row = 0; row < m_spreadRoomsTable.Rows.Count; row++) { // get the ID column value and use it to check whether this spreadsheet room is mapped by Revit room. String externaId = m_spreadRoomsTable.Rows[row][RoomsData.RoomID].ToString(); if (existingRooms.ContainsValue(externaId)) { // skip the spreadsheet room creation if it's mapped by Revit room continue; } // create rooms in specified phase, but without placing them. Room newRoom = m_document.Create.NewRoom(curPhase); if (null == newRoom) { // abort the room creation and pop up failure message myTransaction.RollBack(); MyMessageBox("Create room failed.", MessageBoxIcon.Warning); return 0; } // set the shared parameter's value of Revit room Parameter sharedParam = newRoom.get_Parameter(RoomsData.SharedParam); if (null == sharedParam) { // abort the room creation and pop up failure message myTransaction.RollBack(); MyMessageBox("Failed to get shared parameter, please try again.", MessageBoxIcon.Warning); return 0; } else { sharedParam.Set(externaId); } // Update this new room with values of spreadsheet UpdateNewRoom(newRoom, row); // remember how many new rooms were created, based on spread sheet data nNewRoomsSize++; } // end this transaction if create all rooms successfully. myTransaction.Commit(); #endregion } catch (Exception ex) { // cancel this time transaction when exception occurs if (myTransaction.HasStarted()) { myTransaction.RollBack(); } MyMessageBox(ex.Message, MessageBoxIcon.Warning); return 0; } // output unplaced rooms creation message String strMessage = string.Empty; int nSkippedRooms = m_spreadRoomsTable.Rows.Count - nNewRoomsSize; if (nSkippedRooms > 0) { strMessage = string.Format("{0} unplaced {1} created successfully.\r\n{2} skipped, {3}", nNewRoomsSize, (nNewRoomsSize > 1) ? ("rooms were") : ("room was"), nSkippedRooms.ToString() + ((nSkippedRooms > 1) ? (" were") : (" was")), (nSkippedRooms > 1) ? ("because they were already mapped by Revit rooms.") : ("because it was already mapped by Revit rooms.")); } else { strMessage = string.Format("{0} unplaced {1} created successfully.", nNewRoomsSize, (nNewRoomsSize > 1) ? ("rooms were") : ("room was")); } // output creation message MyMessageBox(strMessage, MessageBoxIcon.Information); return nNewRoomsSize; }