Forum Discussion

davidleal's avatar
davidleal
Iron Contributor
May 31, 2025

Office Script works on Web but provides a wrong result on Excel Desktop for updating formulas

I built an Office script to add FYXX (FY26, FY27, etc.) columns to three excel tables, and to expand the formulas accordingly for the following year. The script works as expected in the web browser but when I run the same Script in my Excel Desktop (Current Channel), the formulas don't get updated correctly in the last two Excel tables (where they have formulas). 

I suspect it is related to the refresh process during the Script execution, I followed some recommendations on the web on how to overcome this well-known problem, but I am not able to fix it. (most of the tricks are commented in the source code, because I could not make it work. The problem can be isolated in the following inner function:

function addFYXXCols(): void { // Logic for adding FYXX columns
  // Define the new column names
  for (var i = 1, addColNames = []; i <= colsNum; i++) { addColNames.push(FYCOL_PREFIX + (lastYearCounter + i)) }
  const lastCol = table.getColumnByName(lastFYXXColName)
  const lastRng = lastCol.getRangeBetweenHeaderAndTotal()
  const ROWS = lastRng.getRowCount()
  const regExUpdateFormula = new RegExp(`\\[${lastFYXXColName}\\]`, "g")
  const UPDATE_FORMULA = TABLE_NAME_SUFFIX_FORMULA.includes(tableName)
  const POS = lastFYXXColIdx + 1 // column position where to add the new column

  // Checking FYXX columns exist in COST table, before adding them to TCOST or HC Excel tables
  if (UPDATE_FORMULA) {
    const COST_TABLE_NAME = tableNames[0]
    const missingCols = findMissingCols(workbook.getTable(COST_TABLE_NAME), addColNames)
    if (missingCols.length > 0) {
      const MSG = `For adding '${addColNames}' columns in '${tableName}' they need to exist first in '${COST_TABLE_NAME}'. Please add missing columns '${missingCols}' and run it again.`
      Logger.error(MSG)
    }
  }
  Logger.trace(`Adding columns '${addColNames}' to Excel table: '${tableName}'.`)
  for (let j = 0; j < addColNames.length; j++) { // Iterating by new columns to add
    const COL_NAME = addColNames[j]
    const col = table.addColumn(POS + j)
    const newColRange = col.getRangeBetweenHeaderAndTotal()
    col.setName(COL_NAME) // Rename directly on the reference
    //table.getRangeBetweenHeaderAndTotal().getText() // forcing re-fresh of the table
    if (UPDATE_FORMULA) {  // The formula needs to be updated
      for (let i = 0; i < ROWS; i++) { // iterating by rows
        const lastCell = lastRng.getCell(i, 0)
        const FORMULA = lastCell.getFormula()
        if (FORMULA) { // if it has a formula, then update it
          const NEW_FORMULA = FORMULA.replace(regExUpdateFormula, `[${COL_NAME}]`)
          const newCell = newColRange.getCell(i, 0)
          //newCell.setValue("")  // prep the cell
          //table.getRangeBetweenHeaderAndTotal().getUsedRange()
          newCell.setFormula(NEW_FORMULA)
          //newCell.getUsedRange() // A force-refresh trigger, to make Excel "commit"
        }
      } // end for iterating by rows
    } // end if
    //flushTable(table)
    //table.getRangeBetweenHeaderAndTotal() // A force-refresh trigger, to make Excel "commit"
  } // end for iterating by columns
} // End function

I am attaching the Excel file, as you can see the formulas are not correct for the added columns FY26, FY27 in the tables TB_P4TCOST, TB_P4HC they are not consistent with the previous column for the same row, the only change by row should be the reference to the new added columns. I could not load the Office Script, so I am adding it the Excel file, under the tab Office Script.

It tested using the Office Script input parameters just modifying one of the tables with formula (table input argument: TOTAL_COST, HEADCOUNT for example), to check if there is any conflict processing more than one Excel Table, but the problem remains the same.

Here the screenshot of the Excel table, where the formulas are not correct.

The helper function flushTable, that is commented, was one of the solution I found on internet, but calling it didn't solve the problem:

/*Trick to force flush the table*/
  function flushTable(table: ExcelScript.Table) {
    const dummyCol = table.addColumn()
    dummyCol.setName("_temp")
    dummyCol.getRangeBetweenHeaderAndTotal().setValue("refresh")
    dummyCol.delete()
  }

The Logger is a singleton class I created to handle the logging process. Since it is an inner function it inherits variables and functions from the main/outer function. There is no issue with the source code since it works as expected in Web Excel, so it is a specific platform/version problem, I am looking for some workaround on how to fix it so it works for Excel Desktop too.

Any help is appreciated, thanks in advance for your help.

3 Replies

  • davidleal's avatar
    davidleal
    Iron Contributor

    Thanks, for pointing it out, interesting, I took a look at it, but I don't see anything similar, it is referring to errors, but not about different behavior between Web Excel and Desktop, unless I missed something, if that is the case, please let me know. Thanks!

    • davidleal's avatar
      davidleal
      Iron Contributor

      Thanks for sharing and for your help, I read it, but I was not able to find something related to my specific case. It seems my problem is related to the following: timing/refresh conflict caused by Excel Desktop's deferred rendering and batching model, but I am not able to find more specific details on my research.

Resources