[Back to Blog](/blog) # BimRv SDK: Retrieve Calculated Table Cell Data

Evgeniy Tikhonov June 02, 2023 [\#rvt](/blog/tag/rvt) [\#rfa](/blog/tag/rfa)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

This article explains how to collect calculated cell data from OdBmDBViewSchedule and OdBmPanelScheduleView elements.

Regular tables have a schema that defines a set of fields and conditions for elements that are displayed in the table. These fields may be simple (represent a parameter ID) or calculatable (formulas). A TableData object is built based on the table schema.

The OdBmDBViewSchedule elements have internal metadata used to build the values in its cells. Fields defined in a schedule schema link table cells to the respective parameters specified by the fields. These parameters are related to elements collected using conditions based on a schedule category or a category and schedule filter rules.

The OdBmPanelScheduleView elements don't have fields and schemas, but each cell of a panel schedule template has a corresponding parameter.

The simple process of value retrieval consists of two steps:

1. Before extracting cell values from the table, you should recalculate them using the OdBmDBViewSchedule::refreshData() method for the OdBmDBViewSchedule class and the OdBmPanelScheduleView::refreshData() method for the OdBmPanelScheduleView class.
2. To retrieve the calculated values of the desired table section, the OdBmPanelScheduleView and OdBmDBViewSchedule classes override the getCellText() method of their ancestor OdBmTableView: OdBmDBViewSchedule::getCellText() and OdBmPanelScheduleView::getCellText().

Table cells also can be merged with their neighboring cells and information about the merged area can be retrieved using the getCellMergedArea() method. To obtain a table cell style, use the getTableCellStyle() method. The OdBmTableCellStyle elements have properties related to the cell text font and can be accessed by the methods used in the example below.

#### Example

This example shows the implementation of the OdBmTableViewToHTMLHelper class from the sample located in BimRv/Examples/TB\_Commands/Dump/TableDump.

1. Define and implement utility methods that will be used later.
    ```
    // Gets the HTML string representing this horizontal alignment.
    static OdString getAlignString(OdBm::HorizontalAlignmentStyle::Enum hAlignment) {
      switch (hAlignment)
      {
      case OdBm::HorizontalAlignmentStyle::Left:
        return L" align=\"left\"";
      case OdBm::HorizontalAlignmentStyle::Center:
        return L" align=\"center\"";
      case OdBm::HorizontalAlignmentStyle::Right:
        return " align=\"right\"";
      }
      return OdString::kEmpty;
    }
    static OdString colorToHtml(OdBmCmColor color) {
      return OdString().format(L"\"#%2.2X%2.2X%2.2X\"", color.red(), color.green(), color.blue());
    }
    static bool isWhiteColor(const OdBmCmColor& color) {
      return color.red() == 255 && color.green() == 255 && color.blue() == 255;
    }
    OdBmTableViewToHTMLHelper::OdBmTableViewToHTMLHelper(const OdBmTableViewPtr& pTableView)
      : m_pTableView(pTableView) {
    }
    void replaceIllegalCharacters(OdString& sText) {
      sText.replace(L"&", L"&");
      sText.replace(L"<", L"<");
      sText.replace(L">", L">");
      sText.replace(L"\"", L""");
      sText.replace(L"'", L"'");
      if (sText.isEmpty())
        sText = L" ";
    }
    ```
2. Define the class and necessary methods.
    ```
    class OdBmTableViewToHTMLHelper
    {
    public:
      /** \details
        Default constructor of OdBmTableViewToHTMLHelper class.
      */
      OdBmTableViewToHTMLHelper(const OdBmTableViewPtr&);
      /** \details
        Exports the table to the HTML file.
        \returns String representing the result of the export
      */
      OdString exportTable() const;
    private:
      OdString exportCell(OdBm::SectionType::Enum sectionId, OdUInt32 row, OdUInt32 col) const;
      OdString exportSection(OdBm::SectionType::Enum) const;
      OdBmTableViewPtr m_pTableView;
      
    ``````
    mutable std::set<std::pair<OdUInt32, OdUInt32>> writtenCells;
    };
    ```
    
    The constructor accepts a smart pointer to an OdBmTableView object and its descendants. The exportTable() method simply runs exportSection(OdBm::SectionType::Enum) on all possible sections in a table view (header, body, summary, and footer).
3. Implement the exportSection() method. 
    ```
    OdString OdBmTableViewToHTMLHelper::exportSection(OdBm::SectionType::Enum sectionId) const {
      OdBmTableSectionDataPtr pSection = m_pTableView->getData()->getSectionDataItem(sectionId);
      if (pSection.isNull())
return OdString::kEmpty;
OdString sSectionLeader = L"<table border=\"1\">\n ";
OdString sSectionTrailer = L"\n </table>";
OdString sRowLeader = L"<tr>\n";
OdString sRowTrailer = L"\n </tr>";
OdString sSection;
for (OdUInt32 row = 0; row < pSection->getNumberOfRows(); row++) {
OdString sSectionRow = sRowLeader+L" ";
for (OdUInt32 col = pSection->getFirstColumnNumber(); col < pSection->getNumberOfColumns(); col++) {
if (std::find(writtenCells.begin(), writtenCells.end(), std::make_pair(row, col)) != writtenCells.end())
continue;
sSectionRow += exportCell(sectionId, row, col);
}
sSection += sSectionRow + sRowTrailer;
}
writtenCells.clear();
return sSectionLeader + sSection + sSectionTrailer;
}

    ```
4. Implement the exportCell() method. 
    ```

OdString OdBmTableViewToHTMLHelper::exportCell(OdBm::SectionType::Enum sectionId, OdUInt32 row, OdUInt32 col) const {
OdString sCellLeader = L"<td";
OdString sCellTrailer = L"</td>";
OdString sCellLeaderTrailer = L">";
OdString sText = m_pTableView->getCellText(sectionId, row, col);
replaceIllegalCharacters(sText);
OdBmTableSectionDataPtr pSection = m_pTableView->getData()->getSectionDataItem(sectionId);
OdBmTableCellStylePtr pCellStyle;
OdBmTableCellMergedArea mergedArea;
OdString sCellStyle;
OdString sColSpan;
OdString sRowSpan;
OdString sFontStyleLeader;
OdString sFontStyleTrailer;
if (eOk == pSection->getCellMergedArea(row, col, mergedArea)) {
// If merged cell spans multiple columns
if (mergedArea.getLeft() != mergedArea.getRight()) {
sColSpan = OdString().format(L" colspan=\"%d\" ", mergedArea.getRight() - mergedArea.getLeft() + 1);
}
// If merged cell spans multiple rows
if (mergedArea.getTop() != mergedArea.getBottom()) {
sColSpan = OdString().format(L" rowspan=\"%d\" ", mergedArea.getBottom() - mergedArea.getTop() + 1);
}
// Remember all written cells related to the merge
for (OdUInt32 iMergedRow = mergedArea.getTop(); iMergedRow <= mergedArea.getBottom(); iMergedRow++) {
for (OdUInt32 iMergedCol = mergedArea.getLeft(); iMergedCol <= mergedArea.getRight(); iMergedCol++) {
writtenCells.insert(std::make_pair(iMergedRow, iMergedCol));
}
}
}
if (eOk == pSection->getTableCellStyle(row, col, pCellStyle)) {
// Horizontal alignment
sCellStyle += getAlignString(pCellStyle->getHorizontalAlignment());
// Write formatting attributes for the upcoming cell
// Background color
if (!isWhiteColor(pCellStyle->getBackgroundColor())) {
sCellStyle += L" bgcolor=" + colorToHtml(pCellStyle->getBackgroundColor());
}
// Write subtags for the cell
// Underline
if (pCellStyle->isFontUnderline()) {
sFontStyleLeader += L"<u>";
sFontStyleTrailer += L"</u>";
}
//Italic
if (pCellStyle->isFontItalic()) {
sFontStyleLeader += L"<i>";
sFontStyleTrailer += L"</i>";
}
//Bold
if (pCellStyle->isFontBold()) {
sFontStyleLeader += L"<b>";
sFontStyleTrailer += L"</b>";
}
}
return sCellLeader + sColSpan + sRowSpan + sCellStyle + sCellLeaderTrailer + sFontStyleLeader + sText + sFontStyleTrailer + sCellTrailer;
}
    ```



 

  



 ## Get started today

  **Try ODA software free for 60 days.   
No risk, no credit card required.**

 [ Try for Free    ](https://staging.opendesign.com/free-trial)
