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;
                }
            }
        }
Example #2
0
 public bool HasStarted()
 {
     if (transaction is object)
     {
         return(transaction.HasStarted());
     }
     if (subTransaction is object)
     {
         return(subTransaction.HasStarted());
     }
     return(false);
 }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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;
        }