How to improve the performance of SetValue() in a spreadsheet macro?

I am trying to store CSV data to a worksheet via a macro. Data comes from 30+ distinct files, it is inconvenient to import each file via the menu. However, writing pieces of data to the worksheet takes several minutes with SetValue(). Is there a better way to load data in the macro?

Interestingly, if data is randomly generated, SetValue() is fast enough. Here is an example macro to illustrate the problem:

(async function()
{

    function generateData(nbRows) {
        let data = new Array(nbRows);
        
        for (let i = 0; i < nbRows; i++) {
            data[i] = [
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random(),
                Math.random()
            ];
        }
        
        return data;
    }
    
    async function fetchData(nbRows) {
        let url = 'https://tb1-ai.pages.emse.fr/edc1/20131113-YE.txt';
        let response = await fetch(url);
        let txt = await response.text();
        
        let data = txt
            .split('\n')
            .map(row => row.split('\t'));
        
        return data.slice(0, nbRows);
    }
    
    let sheet = Api.GetActiveSheet();
    
    for (let nbRows = 100; nbRows < 1e3; nbRows += 100) {
        let range = sheet.GetRange(`A1:M${nbRows}`);
        
        // uncomment either line
        //let data = generateData(nbRows);
        let data = await fetchData(nbRows);

        // note: fetchData() takes ~100ms 
        
        let t1 = Date.now();
        range.SetValue(data);
        let t2 = Date.now();
        
        console.log(`${nbRows} rows inserted in ${t2 - t1} ms`);

        // output: 100 rows inserted in 2620 ms
        // output: 200 rows inserted in 5323 ms
        // output: 300 rows inserted in 17608 ms
        // ...
    }

})();

Hello @victor.charpenay

Please share an example of macro that runs slowly.

By the way, there is an example of macro for importing data from CSV/TXT for Desktop Editors: Import CSV/TXT data | ONLYOFFICE
Maybe you can take a reference from there to adapt it for your needs. If I understand correctly, you are using Document Server, this sample will only work in Desktop Editors, so the modifications are required.

Thanks for your answer.

There already is a macro in my original post to illustrate my point. You can readily execute it and see execution times logged.

This macro fetches data from a server (~15,000 lines of TSV data) and inserts it in the active worksheet. This process is first run on the first 100 rows, then on the first 200 rows, etc. As I wrote in a comment in the macro, the execution time of SetValue() isn’t linear:

  • inserting 100 rows takes 2975 ms
  • inserting 200 rows takes 5323 ms
  • inserting 300 rows takes 17608 ms
  • inserting 400 rows takes 31873 ms
  • inserting 500 rows takes 64368 ms
  • inserting 600 rows takes 103157 ms
  • inserting 700 rows takes 158897 ms

To insert the entire content, it would take several hours.

Yet, the way data is inserted is very similar to what is shown in the example you point to. The only difference is that I use fetch instead of jQuery.

It seems that the file is in local network, can you share it separately?

By the way, new version 8.3.3 was released, try updating the instance to see if it makes any difference.

The resource located at https://tb1-ai.pages.emse.fr/edc1/20131113-YE.txt is meant to be public. What response do you get when you request it in your browser?

Thank you for the information about the update. I am not administrator of the instance I use, I am not in control.

GET request to this URL returns ERR_NAME_NOT_RESOLVED when running a macros. In the browser I only see This site can’t be reached. That is why I am asking to share a file to run tests.