Application: RoomSchedule
Revit Platform: Architecture
Revit Version: 2011.0
First Released For: 2008.2
Programming Language: C#
Skill Level: High
Category: Rooms/Spaces
Type: ExternalCommand, ExternalApplication

Subject: Room creation and modification; Excel data import and export.
Summary: 
This sample demonstrates: how to retrieve spread sheet data, how to create rooms without placing them and how to update spreadsheet data with data of rooms mapped to.

Classes: 
Autodesk.Revit.UI.IExternalCommand
Autodesk.Revit.DB.Document
Autodesk.Revit.DB.Architecture.Room
Autodesk.Revit.DB.Level
Autodesk.Revit.DB.Phase
Autodesk.Revit.DB.Category
Autodesk.Revit.DB.Parameters.BuildInParameter
Autodesk.Revit.DB.Parameters.Definition
Autodesk.Revit.DB.Parameters.DefinitionGroup
Autodesk.Revit.DB.Parameters.InstanceBinding

Autodesk.Revit.DB.Events.DocumentSaving
Autodesk.Revit.DB.Events.DocumentSavingAs
Autodesk.Revit.DB.Events.DocumentClosed

System.Data.OleDb.OleDbConnection
System.Data.OleDb.OleDbCommand
System.Data.DataTable

Project Files: 
Command.cs
This file contains the class Command which inherits from IExternalCommand interface and implements the Execute method, this class will pop up Room Schedule form.

CtrlApplication.cs
This file contains the class CrtlApplication which implements IExternalApplication interface, this class will subscribe DocumentSaving/SavingAs event in OnStartup method and unregister these events in OnShutdown method.
The OnStartup method will subscribe 

RoomScheduleForm.cs
This file contains a Form class which consists of two DataGridView controls and three ComboBox controls. The data from spreadsheet and available rooms, levels and phases will be displayed in these controls. 

RoomsData.cs
This file will be used to retrieve available rooms, levels and phases data from current Revit project and generate rooms DataTable data for display in DataGridView control.

XlsDBConnector.cs
This file will be used to connect to Excel spreadsheet file (.xls), retrieve available tables and generate DataTable data for display in DataGridView control; besides, this class will be used to update spreadsheet data or insert new data to spreadsheet.

EventsReactor.cs
This file defines the class EventsReactor which contains three delegates methods for DocumentSaving/SavingAs/Closing events, the delegate methods will implement accordingly update when they are raised.
Class EventsReactor also includes methods which implement update for spreadsheet and Revit rooms; when update, related logging information will be dumped to log file(RoomSchedule.log) for your review later.

Description: 
This sample uses OleDb.OleDbConnection, OleDb.OleDbCommand and relevant Revit classes mostly to synchronize spreadsheet based room schedule with Revit rooms. This sample implements two functionalities: import room schedule from spreadsheet and update room area fields in spreadsheet by using data from Revit.
-	To deal with .xls file (read, update), use OleDb.OleDbConnection, OleDbCommand, DataTable classes of .NET.
-	To create rooms in specified phase, use Creation.Document.NewRoom(Phase).
-	To get specified element you want, use Document.get_Elements(Filter) method.
-	To get parameters of room, use Room.get_Parameter(String paramName) method.
-	To get all rooms in each PlanTopology, use PlanTopology.Rooms property.
-	DocumenSaving/DocumentSavedAs/DocumentClosed of controlled application level subscribed and implements related functionality.
-	Class DefinitionFile, DefinitionGroup, Definition and InstanceBinding will be used to create shared parameter for rooms.

Instructions: 
1.	Copy the provided .addin file under sample folder to install folder of your Revit and specify full paths for dll. .  
2.	Before running this sample, please make sure the Excel file has a work sheet which must contain “ID”, “Room Area “, “Room Name”, “Room Number”, “Room Comments” columns at first row, the ID and Area columns should be number values, the other columns should be text value, and the spreadsheet should be writeable too. Under project folder there is one Excel file named RoomSchedule.xls, you can use this file as example to define your data or import this file directly in below steps.  
3.	Run this sample directly, the “Room Schedule” form will pop up, all the available levels and phases will be listed in ComboBox controls separately.
4.	Click “Import Excel...” button will allow you to select one spreadsheet file. This sample will retrieve all available work sheets in this sheet file and list them in ComboBox control. 
5.	Select the work sheet which defines the rooms, and then all room data in this sheet will be displayed in DataGridView control.
6.	Select one phase and click “Create Unplaced Rooms” will create rooms (without placing them) according to the spread sheet rooms’ data (The new unplaced rooms’ properties will set by the relevant columns in spreadsheet data). A shared parameter named “External Room ID” will be added to Room category and the parameter value is mapped to spread sheet rooms’ ID. Document Save, SaveAs events will be subscribed too after rooms’ creation.
7.	Check “Show All Rooms” will display all available rooms (placed and unplaced rooms) in current project; select one level will filter all rooms which are in selected level.
8.	Exit this sample, click the “Room” in Revit Basic tab, select the created rooms in above steps and place them. Click Save/SaveAs command to save project: After Save dialog this sample will update the “Room Area”, “Room Name”, “Room Number” and “Room Comments” column data of work sheet by the actual values of mapped and placed room. You can open log file(RoomSchedule.log) to review details of update.
9.	If there are new rooms which were created and placed by user manually, these rooms will be added into spreadsheet when save or save as is called, the “Room Comments” column in spread will be set to “<Added from Revit>” if the room doesn’t have comments. Besides, the “External Room ID” parameter of new room will be set to room’s id value after adding.
10.	When creating unplaced rooms, the new rooms’ name, number and comments properties will be set by the “Room Name”, “Room Number” and “Room Comments” column values in room sheet automatically. 
11.	If spreadsheet room was already mapped by Revit room, new creation will be skipped (some message will be popped up), because more than one Revit room maps to same one spreadsheet room is not allowed. Click “Clear External Room ID” button will clear the existing maps (all values of shared parameter will to set to null) and allow user to create more unplaced rooms.

Notes: 
1.	The sample is not supported with 64-bit Revit since there is no 64-bit Jet OLE DB Provider available.
2.	Because of limitations of Excel ISAM driver, if there is both number data and text data in Name, Number or Comments columns in Excel file, please format number data to text type by adding a single quotation in front of data as prefix, text format will make sample’s read and update operations work well. Again, generally the Rooms created manually or by API will have text Name, and the Comments column will be filled with text “<null>” if Revit room doesn’t have Comments value, so you’d better make sure there is no number data in Name and Comments column.  
3.	The Name and Comments of Room should not contain single quote (‘) because it will conflict with SQL query line.