Looking for a condensed version of my app script to optimize speed and efficiency

In my script, users input data and run the script by clicking a button. The script then appends the data to two different tabs and clears the data entry tab. However, I encountered an issue where I had to manually hard code each cell for appending, causing the script to search through empty rows as well. I need help optimizing the script to only target non-empty rows and append those to the next tab in order to reduce execution time. The button function must remain unchanged. Below is the script that appends data from the "Verify" tab:

function verify() {
  const mainFunctionName = "verify"; // function name Mf this function.
  const alartFunctionName = "alert4";
  const drawings = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("VERIFY").getDrawings();
  const drawing = drawings.filter((e) => e.getOnAction() == mainFunctionName);
  if (drawing.length == 1) {
    drawing[0].setOnAction(alartFunctionName);
    SpreadsheetApp.flush();
   vf();
    drawing[0].setOnAction(mainFunctionName);
  } 
}
function alert4() {
  SpreadsheetApp.getUi().alert("NOW SAVING");
}

function vf() {
// Same content as before
}

Answer №1

Here's a different approach to try:

function updateValues() {
  const sheet = SpreadsheetApp.getActive();
  const verifySheet = sheet.getSheetByName("VERIFY");
  const index5Sheet = sheet.getSheetByName("INDEX5");
  const index6Sheet = sheet.getSheetByName("INDEX6");
  const range1 = ["B1", "C6", "C7", "C8", "C9"];
  const range2 = ["B10", "B11", "B1", "B2", "B3", "B4", "B5", "D6", "D7", "D8", "D9", "E9", "F9", "B12"];
  const range3 = ["M15", "M16", "M17", "M18", "M19", "M20", "M21", "M22", "M23", "M24", "M25", "M26", "M27", "M28", "M29", "M30", "M31", "M32", "M33", "M34", "M35", "M36", "M37", "M38", "M39"];
  const valuesToSet = verifySheet.getRange("A15:N39").getValues().map(([a, b, c, d, e, f, g, h, i, j, k, l, m, n]) => [a, l, b, c, d, e, f, g, h, i, j, n]);
  index5Sheet.getRange(index5Sheet.getLastRow() + 1, 1, valuesToSet.length, valuesToSet[0].length).setValues(valuesToSet);
  const updatedValues = range2.map(value => verifySheet.getRange(value).getValue());
  range1.forEach(value => verifySheet.getRange(value).clearContent());
  range3.forEach(value => verifySheet.getRange(value).clearContent());
}

Answer №2

This might not be shorter, but it is definitely quicker.

Instead of using multiple arrays with A1 notation for disjointed and rearranged cells, I recommend using array indices for better performance.

Fetching data using getValue() from the same sheet multiple times can significantly impact the performance of your script.

Many Google App Script beginners tend to use A1 notation for ranges, whereas I prefer using array indices. This utility function can help transition between the two methods smoothly.

My approach involves fetching all values from the sheet at once using getDataRange().getValues(). Then, by utilizing my utility function getIndices(cell), you can convert A1 notation to row and column indices, allowing you to access values swiftly and construct a row array.

The structure of my test sheet resembles the following:

https://i.stack.imgur.com/yRqZm.png

Code.gs

function testTheFunction() {
  try {
    let cells1 = ["B1","C2","D3"];
    let cells2 = ["E3","D2","C3","B2","A3"];
    let spread = SpreadsheetApp.getActiveSpreadsheet();
    let values = spread.getSheetByName("Sheet1").getDataRange().getValues();
    console.log(getArrayValues(cells1,values));
    console.log(getArrayValues(cells2,values));
  }
  catch(err) {
    console.log(err);
  }
}

/**
 * @param {string} cells[].cell - the spreadsheet cell in A1 notation
 * @param {number} values[].value - the spreadsheet cell value
 * @return {number} results[].value - an array of values
 */
function getArrayValues(cells,values) {
  try {
    let results = [];
    cells.forEach( cell => {
        let indices = getIndices(cell);
        results.push(values[indices.row][indices.col]);
      }
    );
    return results;
  }
  catch(err) {
    console.log(err);
  }
}

/**
 * @param {string} cell - the spreadsheet cell in A1 notation
 * @returns {Object} object - containing row and col
 */
function getIndices(cell) {
  try {
    let parts = cell.match(/[a-z]+/i);
    if( !parts ) throw "incorrect cell ["+cell+"]";
    parts = parts[0];
    let col = 0;
    let i = 0;
    while( i<parts.length ) {
      let char = parts.charCodeAt(i);
      col = 26*col+char-64;
      i++;
    }
    parts = cell.match(/\d+/);
    if( !parts ) throw "incorrect cell ["+cell+"]";
    row = parseInt(parts[0]);
    return { row: row-1, col: col-1 };
  }
  catch(err) {
    console.log(err);
  }
}

Execution log

6:46:18 AM  Notice  Execution started
6:46:20 AM  Info    [ 11, 22, 33 ]
6:46:20 AM  Info    [ 43, 32, 23, 12, 3 ]
6:46:20 AM  Notice  Execution completed

Example

function vf() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const pt = ss.getSheetByName("VERIFY");
  let values = pt.getDataRange().getValues();
  .
  .
  . 
  const pfv = ["A15","L15","B15","C15","D15","E15","F15","G15","H15","I15","J15","N15",];
  const pfr = getArrayValues(pfv,values);
  .
  .
  .

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The React component designed to consistently render video frames onto a canvas is unfortunately incompatible with iOS devices

I'm facing an issue with my code snippet that is supposed to draw video frames on a canvas every 42 milliseconds. It's working perfectly on all platforms and browsers except for iOS. The video frames seem unable to be drawn on canvas in any brows ...

Swap two pairs of elements in an array in a random order

I have a list of team members and also 2 substitute players: team = Samson, Max, Rowan, Flynn, Jack subs = Struan, Harry I am facing a challenge in randomly swapping the 2 subs into the team. The difficulty lies in ensuring that only these 2 elements are ...

Form an item using an array

Is there a way to efficiently convert this array into a map? Here is how the array looks: var array = [{ "id" : 123 }, { "id" : 456 }, { "id" : 789 }]; The desired output should be: var result = { "123": { id: 123 } , "456": { id: 456 } , ...

I have a specific resolution in mind where I want to run jQuery code during window scrolling

I have a jQuery code that I want to run only when the resolution is greater than 950px. If not, I risk losing the responsive logo. My goal is to create a navigation bar similar to the one on the Lenovo homepage. $(document).ready(function(){ //left ...

Determine which scroll bar is currently in use

I'm running into an issue with multiple scrollbars on my page - they just don't seem to be functioning correctly: <div class="dates-container" v-for="id in ids"> <overlay-scrollbars :ref="`datesHeader` ...

Unexpected behavior with scrollTop

Note Reopening bounty as I forgot to award it last time. This question has already been answered by Master A.Woff. I am looking for a way to automatically scroll to a specific row when a user expands it, so that the content is immediately visible witho ...

How can I force an element to overflow without being affected by its parent's overflow style in CSS/HTML/JS, even if the parent is

I've come across many inquiries on this subject, but the proposed solutions never seem to work when dealing with ancestors that have absolute positioning. Take this example: <div id='page'> <div id='container' style= ...

An unexpected page transition occurs when attempting to delete a link

I've successfully created an HTML table that dynamically adds rows and provides an option to delete the current row. Each row represents data retrieved from MongoDB, and upon clicking the delete button, I aim to delete the corresponding item from the ...

Updating a Json array by including a new property using the Gson library

Using Gson, I am serializing a list of objects in the following manner: String responseMessage = new Gson().toJson(pages.get(pagenumber)); Now, I want to include an additional property that can be accessed in JavaScript, which is not related to the list ...

Exploring the capabilities of React testing-library for interacting with the DOM within a React application

I've been working on developing custom developer tools after finding inspiration from Kent C Dodds' insightful article here. One of the challenges I encountered was automatically populating values in a form that I created. My approach involved u ...

Ways to retrieve a designated object linked to a specific value within a JavaScript structure

I am facing a challenge where I need to set a javascript property object with values from another property object within the same instance. Currently, I have the following object: var PLAYER = { slides: { { slide_id: 60, slide_content: 'c ...

I am encountering a "TypeError: topics.forEach is not a function" error when attempting to retrieve metadata for topics using my kafkajs client in Node.js/express.js. Can anyone help me understand why

I am attempting to retrieve the metadata of my Kafka brokers' topics using the kafkajs admin client within my Node.js + express.js server. Here is the content of my index.js file, serving as the main entrypoint for npm: 'use strict'; cons ...

Implementing Knockout.js with JqueryUI Autocomplete: Access the complete object instead of just the value

I have implemented a custom binding for a JQueryUI auto complete feature that works well. However, I am looking to modify it so that it returns the Item object, which can then be pushed to another array. Can someone provide guidance on how to achieve this ...

HTML/JavaScript - Ways to show text entered into an input field as HTML code

One dilemma I'm facing involves a textarea element on my website where users input HTML code. My goal is to showcase this entered HTML code in a different section of the webpage. How should I approach this challenge? The desired outcome is similar to ...

Closing the video on an HTML5 player using an iPad

My task is to incorporate a video into a website with a button to close and stop the video. Once closed, an image will appear below. Everything works perfectly on all browsers. The issue arises on the iPad... On the iPad, the "close" button does not wor ...

Nuxt and Express server are unable to receive API requests when in production mode and the /dist directory

My Nuxt app is running smoothly on my local server, with all API requests working perfectly using the serverMiddleware property in nuxt.config.js. However, when I run yarn generate, the path to the API server gets lost and no data is loaded. Here are some ...

Changing the URI in accordance with the previous URI

I am encountering an issue in my React application where multiple updates of the URI are being made within the same event by adding query parameters using the router.push function from various locations in the code. However, some updates are getting lost b ...

Is there a way to customize the color of the bar displaying my poll results?

My poll features two results bars that are currently both blue. I attempted to change the color of these bars but was unsuccessful. I've searched for solutions on stack overflow, specifically How can I change the color of a progress bar using javascr ...

Three.js fails to load due to Require.js issue

Having encountered a JavaScript error in browser (on the last line mentioned above) with generated code from TypeScript: define(["require", "exports", "three", "jquery", "./test"], function (require, exports, THREE, jQuery, Test) { var Main = (function () ...

Error encountered with CORS in a Socket.io Express HTTP server backend

While developing an app that utilizes express for the backend, I decided to incorporate socket.io for real-time chat functionality. Everything was working flawlessly on postman until my front end react code triggered a cors error when making a GET request ...