/**
  * Called when this cell is modified.
  *
  * <p>The purpose of this method is to validate the cell state prior to modification.
  *
  * @see #setCellType(int)
  * @see #setCellFormula(String)
  * @see XSSFRow#removeCell(org.zkoss.poi.ss.usermodel.Cell)
  * @see org.zkoss.poi.xssf.usermodel.XSSFSheet#removeRow(org.zkoss.poi.ss.usermodel.Row)
  * @see org.zkoss.poi.xssf.usermodel.XSSFSheet#shiftRows(int, int, int)
  * @see
  *     org.zkoss.poi.xssf.usermodel.XSSFSheet#addMergedRegion(org.zkoss.poi.ss.util.CellRangeAddress)
  * @throws IllegalStateException if modification is not allowed
  */
 void notifyArrayFormulaChanging() {
   CellReference ref = new CellReference(this);
   String msg =
       "Cell "
           + ref.formatAsString()
           + " is part of a multi-cell array formula. "
           + "You cannot change part of an array.";
   notifyArrayFormulaChanging(msg);
 }
  /**
   * Set the cells type (numeric, formula or string)
   *
   * @throws IllegalArgumentException if the specified cell type is invalid
   * @see #CELL_TYPE_NUMERIC
   * @see #CELL_TYPE_STRING
   * @see #CELL_TYPE_FORMULA
   * @see #CELL_TYPE_BLANK
   * @see #CELL_TYPE_BOOLEAN
   * @see #CELL_TYPE_ERROR
   */
  public void setCellType(int cellType) {
    int prevType = getCellType();

    if (isPartOfArrayFormulaGroup()) {
      notifyArrayFormulaChanging();
    }
    if (prevType == CELL_TYPE_FORMULA && cellType != CELL_TYPE_FORMULA) {
      getSheet().getWorkbook().onDeleteFormula(this);
    }

    switch (cellType) {
      case CELL_TYPE_BLANK:
        setBlank();
        break;
      case CELL_TYPE_BOOLEAN:
        String newVal = convertCellValueToBoolean() ? TRUE_AS_STRING : FALSE_AS_STRING;
        _cell.setT(STCellType.B);
        _cell.setV(newVal);
        break;
      case CELL_TYPE_NUMERIC:
        _cell.setT(STCellType.N);
        break;
      case CELL_TYPE_ERROR:
        _cell.setT(STCellType.E);
        break;
      case CELL_TYPE_STRING:
        if (prevType != CELL_TYPE_STRING) {
          String str = convertCellValueToString();
          XSSFRichTextString rt = new XSSFRichTextString(str);
          rt.setStylesTableReference(_stylesSource);
          int sRef = _sharedStringSource.addEntry(rt.getCTRst());
          _cell.setV(Integer.toString(sRef));
        }
        _cell.setT(STCellType.S);
        break;
      case CELL_TYPE_FORMULA:
        if (!_cell.isSetF()) {
          CTCellFormula f = CTCellFormula.Factory.newInstance();
          f.setStringValue("0");
          _cell.setF(f);
          if (_cell.isSetT()) _cell.unsetT();
        }
        break;
      default:
        throw new IllegalArgumentException("Illegal cell type: " + cellType);
    }
    if (cellType != CELL_TYPE_FORMULA && _cell.isSetF()) {
      _cell.unsetF();
    }
  }
 /**
  * Sets formula for this cell.
  *
  * <p>Note, this method only sets the formula string and does not calculate the formula value. To
  * set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
  *
  * @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>. If the argument is <code>
  *     null</code> then the current formula is removed.
  * @throws org.zkoss.poi.ss.formula.FormulaParseException if the formula has incorrect syntax or
  *     is otherwise invalid
  * @throws IllegalStateException if the operation is not allowed, for example, when the cell is a
  *     part of a multi-cell array formula
  */
 public void setCellFormula(String formula) {
   if (isPartOfArrayFormulaGroup()) {
     notifyArrayFormulaChanging();
   }
   setFormula(formula, FormulaType.CELL);
 }