exceltypescriptms-officeoffice-jsexcel-addins

Get new named cell with Excel JS API


We're using Excel JS API to get changed on worksheets.

Is there an event to get new named cells?

The only way that I see is to store the named cell collection (using NamedItemCollection) & compare it whenever we detect a change to worksheet.

For the moment I've implemented a function that gets all named cell with address and store them.

var namedItemsColl : NamedCell[] = [];
const namedItems : Excel.NamedItemCollection = ctx.workbook.names.load('items');
await ctx.sync();

for (let i = 0; i < namedItems.items.length; i++) {
      var it= namedItems.items[i].getRange().load('address');
      await ctx.sync();
      var namedCell : NamedCell = new NamedCell;
      namedCell.name = namedItems.items[i].name;
      namedCell.range = it.address;
      namedItemsColl.push(namedCell);
        }

Each time I get a change, I get the named cells collection again and compare it to the store one.

But that takes around 5s each time only to get the entire collection (with 1000 named cells).

Thanks


Solution

  • Actually I've found a workaround that without performance issue. I keep the collection in memory and compare it each time there is a change.

    But I cannot base this on the count of named items as some can be added/deleted.

    I get all items like this

    async function getNamedItems(ctx:Excel.RequestContext):Promise<NamedCell[]>{
        var namedItemsColl : NamedCell[] = [];
        const namedItems : Excel.NamedItemCollection = ctx.workbook.names.load('items');
        
        await ctx.sync();
    
        for (let i = 0; i < namedItems.items.length; i++) {
            var namedCell : NamedCell = new NamedCell;
            namedCell.name = namedItems.items[i].name;
            namedCell.range = namedItems.items[i].value;
            namedItemsColl.push(namedCell);
        }
    
        return namedItemsColl;
    }
    

    And here is how I compare :

    var namedItems: NamedCell[] =[];
    
        await getNamedItems(ctx).then(result => namedItems = result);
    
    for (let i = 0; i < namedItems.length; i++) {            
            if(namedCollection.find(x => x.name == namedItems[i].name) ==null)
            {
                namedcoll = new CellChangeDataClient;
                namedcoll.changeType = Excel.DataChangeType.rangeEdited;
                var nameItem : CellNameUpdate = new CellNameUpdate;
                nameItem.change='added';
                nameItem.name = namedItems[i].name;
                 nameItem.range = namedItems[i].range;
                namedcoll.namedItems = nameItem;
                changesArray.push(namedcoll);
            }
        }
        var tempCell: NamedCell|undefined;
    
    for (let i = 0; i < namedCollection.length; i++) {            
            tempCell= namedItems.find(x => x.name == namedCollection[i].name);
            if(tempCell == undefined)
            {
                namedcoll = new CellChangeDataClient;
                namedcoll.changeType = Excel.DataChangeType.rangeEdited;
                var nameItem : CellNameUpdate = new CellNameUpdate;
                nameItem.change='deleted';
                nameItem.name = namedCollection[i].name;
                namedcoll.namedItems=nameItem;
                changesArray.push(namedcoll);
            }
            else if(tempCell.range != namedCollection[i].range)
            {
                namedcoll = new CellChangeDataClient;
                namedcoll.changeType = Excel.DataChangeType.rangeEdited;
                var nameItem : CellNameUpdate = new CellNameUpdate;
                nameItem.change='updated';
                nameItem.name = tempCell.name;
                nameItem.range = tempCell.range;
                namedcoll.namedItems=nameItem;
                changesArray.push(namedcoll);
            }
        };