Iterates through the rooms in the project and get the information of all the rooms
Exemple #1
0
        /// <summary>
        /// Class constructor
        /// </summary>
        /// <param name="commandData">Revit external command data</param>
        public RoomScheduleForm(ExternalCommandData commandData)
        {
            // UI initialization
            InitializeComponent();

            // reserve Revit command data and get rooms information,
            // and then display rooms information in DataGrideView
            m_commandData = commandData;
            m_document    = m_commandData.Application.ActiveUIDocument.Document;
            m_roomData    = new RoomsData(commandData.Application.ActiveUIDocument.Document);

            // bind levels and phases data to level and phase ComboBox controls
            GetAllLevelsAndPhases();

            // list all levels and phases
            this.levelComboBox.DisplayMember = "Name";
            this.levelComboBox.DataSource    = m_allLevels;
            this.levelComboBox.SelectedIndex = 0;

            this.phaseComboBox.DisplayMember = "Name";
            this.phaseComboBox.DataSource    = m_allPhases;
            this.phaseComboBox.SelectedIndex = 0;

            // if there is no phase, newRoomButton will be disabled.
            if (m_allPhases.Count == 0)
            {
                newRoomButton.Enabled = false;
            }

            // check to see whether current Revit document was mapped to spreadsheet.
            UpdateRoomMapSheetInfo();
        }
Exemple #2
0
        /// <summary>
        /// Check to see if we need to update spreadsheet data according to this Revit room.
        /// We don't need to update spreadsheet rooms if Revit room:
        /// . Which is one unplaced room.
        /// . The room has area which is zero.
        /// . Special room which doesn't have custom shared parameter at all.
        /// </summary>
        /// <param name="activeDocument">Current active document.</param>
        /// <param name="roomObj">Room object to be checked.</param>
        /// <param name="roomArea">Room area of this Revit room.</param>
        /// <param name="externalId">The value of custom shared parameter of this room.</param>
        /// <returns>Indicates whether it succeeded to get room area and shared parameter value.</returns>
        private static bool ValidateRevitRoom(Document activeDocument, Room room, ref double roomArea, ref String externalId)
        {
            roomArea   = 0.0f;
            externalId = String.Empty;
            if (null == room.Location || null == activeDocument.GetElement(room.LevelId))
            {
                return(false);
            }

            // get Area of room, if converting to double value fails, skip this.
            // if the area is zero to less than zero, skip the update too
            try
            {
                // get area without unit, then converting it to double will be ok.
                String areaStr = RoomsData.GetProperty(activeDocument, room, BuiltInParameter.ROOM_AREA, false);
                roomArea = Double.Parse(areaStr);
                if (roomArea <= double.Epsilon)
                {
                    return(false);
                }
            }
            catch
            {
                // parse double value failed, continue the loop
                return(false);
            }

            // get the shared parameter value of room
            Parameter externalIdSharedParam = null;
            bool      bExist = RoomsData.ShareParameterExists(room, RoomsData.SharedParam, ref externalIdSharedParam);

            if (false == bExist || null == externalIdSharedParam)
            {
                return(false);
            }
            else
            {
                externalId = externalIdSharedParam.AsString();
            }
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Clear all values of shared parameters
        /// Allow user to create more unplaced rooms and update map relationships between Revit and spreadsheet rooms.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearIDButton_Click(object sender, EventArgs e)
        {
            int nCount = 0;

            foreach (Room room in m_roomData.Rooms)
            {
                Parameter param  = null;
                bool      bExist = RoomsData.ShareParameterExists(room, RoomsData.SharedParam, ref param);
                if (bExist && null != param && false == String.IsNullOrEmpty(param.AsString()))
                {
                    param.Set(String.Empty);
                    nCount++;
                }
            }

            // update Revit rooms display
            if (nCount > 0)
            {
                UpdateFormDisplay(false);
            }
        }
Exemple #4
0
        /// <summary>
        /// Update mapped spread sheet when document is about to be saved or saved as
        /// This method will update spread sheet room data([Area] column) with actual area value of mapped Revit Room.
        /// or add Revit room to spreadsheet if it is not mapped to room of spreadsheet.        /// </summary>
        /// <param name="activeDocument">Current active document.</param>
        private void UpdateMappedSpreadsheet(Document activeDocument)
        {
            // Programming Routines:
            //
            // 1: Update spreadsheet when:
            //    a: there is room work sheet table;
            //    b: there is rooms data;
            //    c: shared parameter exists;
            // 2: Skip update and insert operations for below rooms:
            //    a: the rooms are not placed or located;
            //    b: the rooms whose shared parameter(defined by sample) are not retrieved,
            //       some rooms maybe don't have shared parameter at all, despite user create for Rooms category.
            // 3: Update spreadsheet rooms values by Revit room actual values.
            //    a: if shared parameter exists(is not null), update row by using this parameter's value;
            //    b: if shared parameter doesn't exist (is null), update row by Id value of room, which will avoid the duplicate
            //       ID columns occur in spreadsheet.
            // 4: Insert Revit rooms data to spreadsheet if:
            //    a: failed to update values of rooms (maybe there no matched ID value in spread sheet rows).
            //

            #region Check Whether Update Spreadsheet Data
            //
            // check which table to be updated.
            SheetInfo mappedXlsAndTable;
            bool      hasValue = m_docMapDict.TryGetValue(activeDocument.GetHashCode(), out mappedXlsAndTable);
            if (!hasValue || null == mappedXlsAndTable ||
                String.IsNullOrEmpty(mappedXlsAndTable.FileName) || String.IsNullOrEmpty(mappedXlsAndTable.SheetName))
            {
                DumpLog("This document isn't mapped to spreadsheet yet.");
                return;
            }

            // retrieve all rooms in project(maybe there are new rooms created manually by user)
            RoomsData roomData = new RoomsData(activeDocument);
            if (roomData.Rooms.Count <= 0)
            {
                DumpLog("This document doesn't have any room yet.");
                return;
            }
            #endregion

            // create a connection and update values of spread sheet
            int            updatedRows = 0; // number of rows which were updated
            int            newRows     = 0; // number of rows which were added into spread sheet
            XlsDBConnector dbConnector = new XlsDBConnector(mappedXlsAndTable.FileName);

            // check whether there is room table.
            // get all available rooms in current document once more
            int stepNo = -1;
            DumpLog(System.Environment.NewLine + "Start to update spreadsheet room......");
            foreach (Room room in roomData.Rooms)
            {
                // check Whether We Update This Room
                stepNo++;
                double roomArea   = 0.0f;
                String externalId = String.Empty;
                if (!ValidateRevitRoom(activeDocument, room, ref roomArea, ref externalId))
                {
                    DumpLog(String.Format("#{0}--> Room:{1} was skipped.", stepNo, room.Number));
                    continue;
                }

                // try to update
                try
                {
                    #region Update Spreadsheet Room
                    // flag used to indicate whether update is successful
                    bool bUpdateFailed = false; // reserve whether this room updated successfully.
                    // if room comment is empty, use <null> for mapped room, use <Added from Revit> for not mapped room in spread sheet.
                    bool bCommnetIsNull = false;

                    // get comments of room
                    String    comments;
                    Parameter param = room.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
                    comments = (null != param) ? (param.AsString()) : ("");
                    if (String.IsNullOrEmpty(comments))
                    {
                        // this room doesn't have comment value
                        bCommnetIsNull = true;
                        // use <null> for room with empty comment by default when updating spread sheet
                        comments = "<null>";
                    }

                    // create update SQL clause,
                    // when filtering row to be updated, use Room.Id.IntegerValue if "External Room ID" is null.
                    String updateStr = String.Format(
                        "Update [{0}$] SET [{1}] = '{2}', [{3}] = '{4}', [{5}] = '{6}', [{7}] = '{8:N3}' Where [{9}] = {10}",
                        mappedXlsAndTable.SheetName, // mapped table name
                        RoomsData.RoomName, room.Name,
                        RoomsData.RoomNumber, room.Number,
                        RoomsData.RoomComments, comments,
                        RoomsData.RoomArea, roomArea,
                        RoomsData.RoomID, String.IsNullOrEmpty(externalId) ? room.Id.IntegerValue.ToString() : externalId);

                    // execute the command and check the size of updated rows
                    int afftectedRows = dbConnector.ExecuteCommnand(updateStr);
                    if (afftectedRows == 0)
                    {
                        bUpdateFailed = true;
                    }
                    else
                    {
                        // count how many rows were updated
                        DumpLog(String.Format("#{0}--> {1}", stepNo, updateStr));
                        updatedRows += afftectedRows;

                        // if "External Room ID" is null but update successfully, which means:
                        // in spreadsheet there is existing row whose "ID" value equals to room.Id.IntegerValue, so we should
                        // set Revit room's "External Room ID" value to Room.Id.IntegerValue for consistence after update .
                        if (String.IsNullOrEmpty(externalId))
                        {
                            SetExternalRoomIdToRoomId(room);
                        }
                    }
                    #endregion


                    #region Insert Revit Room

                    // Add this new room to spread sheet if fail to update spreadsheet
                    if (bUpdateFailed)
                    {
                        // try to insert this new room to spread sheet, some rules:
                        // a: if the "External Room ID" exists, set ID column to this external id value,
                        //    if the "External Room ID" doesn't exist, use the actual Revit room id as the ID column value.
                        // b: use comments in room if room's description exists,
                        //    else, use constant string: "<Added from Revit>" for Comments column in spreadsheet.

                        String insertStr =
                            String.Format("Insert Into [{0}$] ([{1}], [{2}], [{3}], [{4}], [{5}]) Values('{6}', '{7}', '{8}', '{9}', '{10:N3}')",
                                          mappedXlsAndTable.SheetName,                                                           // mapped table name
                                          RoomsData.RoomID, RoomsData.RoomComments, RoomsData.RoomName, RoomsData.RoomNumber, RoomsData.RoomArea,
                                          (String.IsNullOrEmpty(externalId)) ? (room.Id.IntegerValue.ToString()) : (externalId), // Room id
                                          (bCommnetIsNull || String.IsNullOrEmpty(comments)) ? ("<Added from Revit>") : (comments),
                                          room.Name, room.Number, roomArea);

                        // try to insert it
                        afftectedRows = dbConnector.ExecuteCommnand(insertStr);
                        if (afftectedRows != 0)
                        {
                            // remember the number of new rows
                            String succeedMsg = String.Format("#{0}--> Succeeded to insert spreadsheet Room - Name:{1}, Number:{2}, Area:{3:N3}",
                                                              stepNo, room.Name, room.Number, roomArea);
                            DumpLog(succeedMsg);
                            newRows += afftectedRows;

                            // if the Revit room doesn't have external id value(may be a room created manually)
                            // set its "External Room ID" value to Room.Id.IntegerValue, because the room was added/mapped to spreadsheet,
                            // and the value of ID column in sheet is just the Room.Id.IntegerValue, we should keep this consistence.
                            if (String.IsNullOrEmpty(externalId))
                            {
                                SetExternalRoomIdToRoomId(room);
                            }
                        }
                        else
                        {
                            DumpLog(String.Format("#{0}--> Failed: {1}", stepNo, insertStr));
                        }
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    // close the connection
                    DumpLog(String.Format("#{0}--> Exception: {1}", stepNo, ex.Message));
                    dbConnector.Dispose();
                    RoomScheduleForm.MyMessageBox(ex.Message, MessageBoxIcon.Warning);
                    return;
                }
            }
            // close the connection
            dbConnector.Dispose();

            // output the affected result message
            String sumMsg = String.Format("{0}:[{1}]: {2} rows were updated and {3} rows were added into successfully.",
                                          Path.GetFileName(mappedXlsAndTable.FileName), mappedXlsAndTable.SheetName, updatedRows, newRows);
            DumpLog(sumMsg);
            DumpLog("Finish updating spreadsheet room." + System.Environment.NewLine);
        }
Exemple #5
0
        /// <summary>
        /// Update mapped spread sheet when document is about to be saved or saved as
        /// This method will update spread sheet room data([Area] column) with actual area value of mapped Revit Room.
        /// or add Revit room to spreadsheet if it is not mapped to room of spreadsheet.        /// </summary>
        /// <param name="activeDocument">Current active document.</param>
        private void UpdateMappedSpreadsheet(Document activeDocument)
        {
            // Programming Routines:
            //
            // 1: Update spreadsheet when:
            //    a: there is room work sheet table;
            //    b: there is rooms data;
            //    c: shared parameter exists;
            // 2: Skip update and insert operations for below rooms:
            //    a: the rooms are not placed or located;
            //    b: the rooms whose shared parameter(defined by sample) are not retrieved,
            //       some rooms maybe don't have shared parameter at all, despite user create for Rooms category.
            // 3: Update spreadsheet rooms values by Revit room actual values.
            //    a: if shared parameter exists(is not null), update row by using this parameter's value;
            //    b: if shared parameter doesn't exist (is null), update row by Id value of room, which will avoid the duplicate
            //       ID columns occur in spreadsheet.
            // 4: Insert Revit rooms data to spreadsheet if:
            //    a: failed to update values of rooms (maybe there no matched ID value in spread sheet rows).
            //

            #region Check Whether Update Spreadsheet Data
            //
            // check which table to be updated.
            SheetInfo mappedXlsAndTable;
            bool hasValue = m_docMapDict.TryGetValue(activeDocument.GetHashCode(), out mappedXlsAndTable);
            if (!hasValue || null == mappedXlsAndTable ||
                String.IsNullOrEmpty(mappedXlsAndTable.FileName) || String.IsNullOrEmpty(mappedXlsAndTable.SheetName))
            {
                DumpLog("This document isn't mapped to spreadsheet yet.");
                return;
            }

            // retrieve all rooms in project(maybe there are new rooms created manually by user)
            RoomsData roomData = new RoomsData(activeDocument);
            if (roomData.Rooms.Count <= 0)
            {
                DumpLog("This document doesn't have any room yet.");
                return;
            }
            #endregion

            // create a connection and update values of spread sheet
            int updatedRows = 0; // number of rows which were updated
            int newRows = 0; // number of rows which were added into spread sheet
            XlsDBConnector dbConnector = new XlsDBConnector(mappedXlsAndTable.FileName);

            // check whether there is room table.
            // get all available rooms in current document once more
            int stepNo = -1;
            DumpLog(System.Environment.NewLine + "Start to update spreadsheet room......");
            foreach (Room room in roomData.Rooms)
            {
                // check Whether We Update This Room
                stepNo++;
                double roomArea = 0.0f;
                String externalId = String.Empty;
                if (!ValidateRevitRoom(activeDocument, room, ref roomArea, ref externalId))
                {
                    DumpLog(String.Format("#{0}--> Room:{1} was skipped.", stepNo, room.Number));
                    continue;
                }

                // try to update
                try
                {

                    #region Update Spreadsheet Room
                    // flag used to indicate whether update is successful
                    bool bUpdateFailed = false; // reserve whether this room updated successfully.
                    // if room comment is empty, use <null> for mapped room, use <Added from Revit> for not mapped room in spread sheet.
                    bool bCommnetIsNull = false;

                    // get comments of room
                    String comments;
                    Parameter param = room.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
                    comments = (null != param) ? (param.AsString()) : ("");
                    if (String.IsNullOrEmpty(comments))
                    {
                        // this room doesn't have comment value
                        bCommnetIsNull = true;
                        // use <null> for room with empty comment by default when updating spread sheet
                        comments = "<null>";
                    }

                    // create update SQL clause,
                    // when filtering row to be updated, use Room.Id.IntegerValue if "External Room ID" is null.
                    String updateStr = String.Format(
                        "Update [{0}$] SET [{1}] = '{2}', [{3}] = '{4}', [{5}] = '{6}', [{7}] = '{8:N3}' Where [{9}] = {10}",
                        mappedXlsAndTable.SheetName, // mapped table name
                        RoomsData.RoomName, room.Name,
                        RoomsData.RoomNumber, room.Number,
                        RoomsData.RoomComments, comments,
                        RoomsData.RoomArea, roomArea,
                        RoomsData.RoomID, String.IsNullOrEmpty(externalId) ? room.Id.IntegerValue.ToString() : externalId);

                    // execute the command and check the size of updated rows
                    int afftectedRows = dbConnector.ExecuteCommnand(updateStr);
                    if (afftectedRows == 0)
                    {
                        bUpdateFailed = true;
                    }
                    else
                    {
                        // count how many rows were updated
                        DumpLog(String.Format("#{0}--> {1}", stepNo, updateStr));
                        updatedRows += afftectedRows;

                        // if "External Room ID" is null but update successfully, which means:
                        // in spreadsheet there is existing row whose "ID" value equals to room.Id.IntegerValue, so we should
                        // set Revit room's "External Room ID" value to Room.Id.IntegerValue for consistence after update .
                        if (String.IsNullOrEmpty(externalId))
                        {
                            SetExternalRoomIdToRoomId(room);
                        }
                    }
                    #endregion

                    #region Insert Revit Room

                    // Add this new room to spread sheet if fail to update spreadsheet
                    if (bUpdateFailed)
                    {
                        // try to insert this new room to spread sheet, some rules:
                        // a: if the "External Room ID" exists, set ID column to this external id value,
                        //    if the "External Room ID" doesn't exist, use the actual Revit room id as the ID column value.
                        // b: use comments in room if room's description exists,
                        //    else, use constant string: "<Added from Revit>" for Comments column in spreadsheet.

                        String insertStr =
                            String.Format("Insert Into [{0}$] ([{1}], [{2}], [{3}], [{4}], [{5}]) Values('{6}', '{7}', '{8}', '{9}', '{10:N3}')",
                            mappedXlsAndTable.SheetName, // mapped table name
                            RoomsData.RoomID, RoomsData.RoomComments, RoomsData.RoomName, RoomsData.RoomNumber, RoomsData.RoomArea,
                            (String.IsNullOrEmpty(externalId)) ? (room.Id.IntegerValue.ToString()) : (externalId), // Room id
                            (bCommnetIsNull || String.IsNullOrEmpty(comments)) ? ("<Added from Revit>") : (comments),
                            room.Name, room.Number, roomArea);

                        // try to insert it
                        afftectedRows = dbConnector.ExecuteCommnand(insertStr);
                        if (afftectedRows != 0)
                        {
                            // remember the number of new rows
                            String succeedMsg = String.Format("#{0}--> Succeeded to insert spreadsheet Room - Name:{1}, Number:{2}, Area:{3:N3}",
                                stepNo, room.Name, room.Number, roomArea);
                            DumpLog(succeedMsg);
                            newRows += afftectedRows;

                            // if the Revit room doesn't have external id value(may be a room created manually)
                            // set its "External Room ID" value to Room.Id.IntegerValue, because the room was added/mapped to spreadsheet,
                            // and the value of ID column in sheet is just the Room.Id.IntegerValue, we should keep this consistence.
                            if (String.IsNullOrEmpty(externalId))
                            {
                                SetExternalRoomIdToRoomId(room);
                            }
                        }
                        else
                        {
                            DumpLog(String.Format("#{0}--> Failed: {1}", stepNo, insertStr));
                        }
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    // close the connection
                    DumpLog(String.Format("#{0}--> Exception: {1}", stepNo, ex.Message));
                    dbConnector.Dispose();
                    RoomScheduleForm.MyMessageBox(ex.Message, MessageBoxIcon.Warning);
                    return;
                }
            }
            // close the connection
            dbConnector.Dispose();

            // output the affected result message
            String sumMsg = String.Format("{0}:[{1}]: {2} rows were updated and {3} rows were added into successfully.",
                Path.GetFileName(mappedXlsAndTable.FileName), mappedXlsAndTable.SheetName, updatedRows, newRows);
            DumpLog(sumMsg);
            DumpLog("Finish updating spreadsheet room." + System.Environment.NewLine);
        }
Exemple #6
0
        /// <summary>
        /// Class constructor
        /// </summary>
        /// <param name="commandData">Revit external command data</param>
        public RoomScheduleForm(ExternalCommandData commandData)
        {
            // UI initialization
            InitializeComponent();

            // reserve Revit command data and get rooms information,
            // and then display rooms information in DataGrideView
            m_commandData = commandData;
            m_document = m_commandData.Application.ActiveUIDocument.Document;
            m_roomData = new RoomsData(commandData.Application.ActiveUIDocument.Document);

            // bind levels and phases data to level and phase ComboBox controls
            GetAllLevelsAndPhases();

            // list all levels and phases
            this.levelComboBox.DisplayMember = "Name";
            this.levelComboBox.DataSource = m_allLevels;
            this.levelComboBox.SelectedIndex = 0;

            this.phaseComboBox.DisplayMember = "Name";
            this.phaseComboBox.DataSource = m_allPhases;
            this.phaseComboBox.SelectedIndex = 0;

            // if there is no phase, newRoomButton will be disabled.
            if (m_allPhases.Count == 0)
            {
                newRoomButton.Enabled = false;
            }

            // check to see whether current Revit document was mapped to spreadsheet.
            UpdateRoomMapSheetInfo();
        }