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

Using RxJS v5 for Sending a POST Request with Parameters

Snippet of my RxJS code: .mergeMap(action => { const user = store.getState().user; return ajax.post(`${config.API_BASE_URL}/api/v1/rsvps`, { rsvp: { meetup_id: action.payload, user_id: user.id, } }) .map(action => calenda ...

Send the user to the login page once their email has been verified

On my website, I have a process where users need to verify their email by clicking on a link sent through emails. When the user clicks on this verification link, I want them to be redirected to a page thanking them for confirming their account and then a ...

Link a distinctive number to a specific element

I am searching for a method to link a DOM element with a distinct number that is not assigned to any other element in the DOM. Using an Id attribute is not an option as not all elements possess such an identifier. One potential approach is to obtain a num ...

The power of relative URLs in AJAX calls

Why does Javascript handle relative URLs differently than standard HTML? Consider the URL provided: http://en.wikipedia.org/wiki/Rome. Launch a Firebug console (or any other Javascript console) and type in the following: var x = new XMLHttpRequest(); x.op ...

unable to locate the PHP file on the server

Struggling to make an API call via POST method to retrieve data from a PHP file. Surprisingly, the code functions properly on another device without any hiccups. However, every time I attempt to initiate the call, I encounter this inconvenient error messag ...

AngularJS: Utilizing bold text to enhance the separation of concerns between controllers and templates

In my AngularJS version 1 application with Ecmascript 6, I have a requirement to display a string where one part is in normal weight and the other part is bold. For instance, consider the following scenarios: Will start now Will start in 6 minutes Will ...

Tips for bringing a particular tab into focus when a page initially loads

My webpage features custom links (tabs) that display content when clicked. By default, the first tab is selected and its content is shown, while the rest are set to display:none. Clicking on any other link will assign the 'selected' class to it, ...

Should front-end and back-end share Typescript data modeling through classes or interfaces?

I'm currently exploring the best approach to share the same data types between the client (React) and the server (Express + Socket.IO). Within my game, there are various rooms each storing the current status, such as: class GameRoom { players: P ...

Navigating through nested JSON objects in React to display data effectively

I have been struggling for hours to find a solution to this problem with no success. I really need your assistance. The task at hand involves looping through a JSON file and creating a user interface that consists of multiple columns, each containing vari ...

A capability that operates on an array of pairs as its parameter, where the primary component of each pair signifies the superior category of the secondary

I'm grappling with developing a TypeScript function that takes an array of Tuples as input. Each tuple should consist of two elements, where the first element acts as a parent type to the second element - essentially, the second element must extend th ...

Troubleshooting Bootstrap bug caused by rollupPluginBabelHelpers

I am currently working on a Bootstrap 4 website. I noticed that in Internet Explorer, the modal works fine when opened for the first time, but then displays an error in the console and does not open when trying to do so a second time on the same window. On ...

Managing the position of the caret within a content-editable div

I need help with editing a contenteditable div in HTML <div contenteditable="true" id="TextOnlyPage"></div> Here is my jQuery code: var rxp = new RegExp("(([0-9]+\.?[0-9]+)|([0-9]+))", "gm"); $('#TextOnlyPage').keyup(function( ...

Cutting-edge framework for Single Page Applications

Can you assist me in identifying the most recent framework suitable for creating single page applications? Your help is greatly appreciated. Thank you. ...

Implementing relative pathing in front-end development while using ExpressJS for the back-end

I'm currently in the process of developing an application with Express 4.14. When it comes to routing, I have a situation where the incoming request is "https://example.com/page", and I am using res.sendFile(__dirname + "/../client/pages/page/index.ht ...

Empty the localStorage when terminating the IE process using the Task Manager

Utilizing HTML5 localStorage to keep track of my application session has been a useful feature. Here is a snippet of the code I am currently using: if(typeof(Storage)!=="undefined") { if(sessionStorage.lastname=="Smith") { alert("Your ses ...

Tips on avoiding quotation marks in a Less variable containing a color identifier

I'm currently working on an HTML/CSS project where I aim to establish classes for labels and texts based on their color. For instance: .text-red{ color: red; } .label-white{ color: white; } In order to achieve this, my approach involves cr ...

Tips for incorporating an onClick event into a variable beyond the class extension

Currently utilizing React/Redux in this scenario. At the beginning of my code, outside of the class extends block, I have: const Question10 = () => (<div> <p>Insert question here</p> <input place ...

Aurelia's navigation feature adds "?id=5" to the URL instead of "/5"

I have set up my Aurelia Router in app.ts using the configureRouter function like this: configureRouter(config, router: Router) { config.map([ { route: ['users', 'users/:userId?'], na ...

How to Refine Database Queries in Laravel Without Using Conditional Statements

I am currently facing the challenge of filtering users in my database using numerous if / elseif statements, and I'm on the lookout for a more efficient method. At present, I find myself writing if statements for every possible query based on the foll ...

Retrieve a JSON array using an HTTP Get request in JavaScript (with jQuery)

I’ve been experimenting with various code snippets in an attempt to reach my objective, but so far I haven’t found a solution. Objective: My goal is to retrieve a JSON array of objects from a specific web URL using the GET method. This task needs to b ...