Schedule Classes

Schedule views use several supporting classes.

TableView is a class that represents a view that shows a table and it is the base class for ViewSchedule and PanelScheduleView. It has an associated TableData class which contains one or more sections. For ViewSchedule, there is only one header and one body section.

The TableSectionData class represents a contiguous set of cells arranged in rows and columns. For a ViewSchedule the cell contents of TableSectionData are generated from the ScheduleDefinition and parameters. Also, for ViewSchedules, while the header section has read/write permissions, the body section is read-only.

Working with data in a schedule

The actual data for a table is contained in the TableData class. Although the TableData object cannot be obtained directly from the TableView class, both child classes have a GetTableData() method. For ViewSchedule, this method returns a TableData object. For a PanelScheduleView, GetTableData() returns a PanelScheduleData object, which derives from the TableData base class. The TableData class holds most of the data that describe the style of the rows, columns, and cells in a table. PanelScheduleData provides additional methods related specifically to panel schedules.

Working with rows, columns and cells

Data in a table is broken down into sections. To work with the rows, columns and cells of the TableData, it is necessary to get the a TableSectionData object. TableData.GetSectionData() can be called with either an integer to the requested section data, or using the SectionType (i.e. Header or Body).

The TableSectionData class can be used to insert or remove rows or columns, format cells, and to get details of the cells that make up that section of the schedule, such as the cell type (i.e. Text or Graphic) or the cell's category id.

In the following example, a new row is added to the header section of the schedule and the text is set for the newly created cell. Note that the first row of the header section defaults to the title when created with the UI.

Code Region: Inserting a row

public void CreateSubtitle(ViewSchedule schedule)
{
    TableData colTableData = schedule.GetTableData();

    TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
    tsd.InsertRow(tsd.FirstRowNumber + 1);
    tsd.SetCellText(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber, "Schedule of column top and base levels with offsets");
}

Also note, in the code example above, it uses the properties FirstRowNumber and FirstColumnNumber. In some sections the row or column numbers might start with 0, or they might start with 1. These properties should always be used in place of a hardcoded 0 or 1.

In the following example, a new single-category schedule is created with a custom header section.

Code Region: Customizing the header section

public static void CreateSingleCategoryScheduleWithSimpleHeaderSection(Document doc)
{
    using (Transaction t = new Transaction(doc, "Create single-category with custom headers"))
    {
        // Build schedule
        t.Start();
        ViewSchedule vs = ViewSchedule.CreateSchedule(doc, new ElementId(BuiltInCategory.OST_Windows));

        AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_HEIGHT));
        AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.WINDOW_WIDTH));
        AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.ALL_MODEL_MARK));
        AddRegularFieldToSchedule(vs, new ElementId(BuiltInParameter.ALL_MODEL_COST));

        doc.Regenerate();

        // Get header section
        TableSectionData data = vs.GetTableData().GetSectionData(SectionType.Header);

        int rowNumber = data.LastRowNumber;
        int columnNumber = data.LastColumnNumber;

        // Get the overall width of the table so that the new columns can be resized properly
        double tableWidth = data.GetColumnWidth(columnNumber);

        data.InsertColumn(columnNumber);
        data.InsertColumn(columnNumber);

        // Refresh data to be sure that schedule is ready for text insertion
        vs.RefreshData();

        //Set text to the first header cell
        data.SetCellText(rowNumber, data.FirstColumnNumber, "Special Window Schedule Text");

        // Set width of first column
        data.SetColumnWidth(data.FirstColumnNumber, tableWidth / 3.0);

        //Set a different parameter to the second cell - the project name
        data.SetCellParamIdAndCategoryId(rowNumber, data.FirstRowNumber + 1, new ElementId(BuiltInParameter.PROJECT_NAME),
                                            new ElementId(BuiltInCategory.OST_ProjectInformation));
        data.SetColumnWidth(data.FirstColumnNumber + 1, tableWidth / 3.0);

        //Set the third column as the schedule view name - use the special category for schedule parameters for this
        data.SetCellParamIdAndCategoryId(rowNumber, data.LastColumnNumber, new ElementId(BuiltInParameter.VIEW_NAME),
                                            new ElementId(BuiltInCategory.OST_ScheduleViewParamGroup));
        data.SetColumnWidth(data.LastColumnNumber, tableWidth / 3.0);

        t.Commit();
    }
}

public static void AddRegularFieldToSchedule(ViewSchedule schedule, ElementId paramId)
{
    ScheduleDefinition definition = schedule.Definition;

    // Find a matching SchedulableField
    SchedulableField schedulableField =
        definition.GetSchedulableFields().FirstOrDefault<SchedulableField>(sf => sf.ParameterId == paramId);

    if (schedulableField != null)
    {
        // Add the found field
        definition.AddField(schedulableField);
    }
}

The style of rows, columns, or individual cells can be customized for schedules. This includes the ability to set the border line style for all four sides of cells, as well as cell color and text appearance (i.e. color, font, size). For regular schedules, this can only be done in the header section of the table.

In the example below, the font of the subtitle of a ViewSchedule (assumed to be the second row of the header section) is set to bold and the font size is set to 10.

Code Region: Formatting cells

public void FormatSubtitle(ViewSchedule colSchedule)
{
    TableData colTableData = colSchedule.GetTableData();

    TableSectionData tsd = colTableData.GetSectionData(SectionType.Header);
    // Subtitle is second row, first column
    if (tsd.AllowOverrideCellStyle(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber))
    {
        TableCellStyle tcs = new TableCellStyle();
        TableCellStyleOverrideOptions options = new TableCellStyleOverrideOptions();
        options.FontSize = true;
        options.Bold = true;
        tcs.SetCellStyleOverrideOptions(options);
        tcs.IsFontBold = true;
        tcs.TextSize = 10;
        tsd.SetCellStyle(tsd.FirstRowNumber + 1, tsd.FirstColumnNumber, tcs);
    }
}