PHPOffice / PHPExcel

ARCHIVED
Other
11.46k stars 4.19k forks source link

create formula from tokens #834

Closed duccoder closed 8 years ago

duccoder commented 8 years ago

Hi, how to rebuild formula from tokens

Ex:

$formulaParser = new \PHPExcel_Calculation_FormulaParser('=IF(T1<X2,"foo", T1+X2)');
dump($formulaParser->getTokens());

I receive:

screenshot at 2016-02-26 10 28 29

And I modify more value, ex: change X2 to T2 and now I need rebuild tokens to formula

Can anybody help me?

MarkBaker commented 8 years ago

What are you trying to achieve? Tokenising a formula is a part of the parsing process, prior to execution of the formula; it's not intended as a method for changing a formula in any way; it's not intended to be reversible.

If you need to change the formula, do it using the string value of that formula, using str_replace() or regexp (or similar)

duccoder commented 8 years ago

@MarkBaker Thank your reply, my job need change more string of formula. I think had util function support rebuildFormularFromTokens

So I should manually rebuild like:

/**
 * @param array $tokens
 * @return string
 */
public static function convertPHPExcelTokensToFormula(array $tokens)
{
    $formulaStack = ['='];
    /** @var \PHPExcel_Calculation_FormulaToken $token */
    foreach ($tokens as $token) {
        switch ($token->getTokenType()) {
            case \PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION:
                $formulaStack[] = $token->getValue();
                $formulaStack[] = 'Start' === $token->getTokenSubType() ? '(' : ')';
                break;
            case \PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND:
                $value = $token->getValue();
                if (\PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT === $token->getTokenSubType()) {
                    $value = '"'.$value.'"';
                }
                $formulaStack[] = $value;
                break;
            default:
                $formulaStack[] = $token->getValue();
                break;
            # @TODO implement unit test with more case
        }
    }

    return implode('', $formulaStack);
}