Google Script: Implementing multiple conditions based on unique identifiers

A custom script has been designed to keep track of the frequency of VIN numbers repetitions and the status of parts arrival for each unique VIN Number (Car).

For instance, if a VIN number appears 5 times, it indicates that five parts are expected to arrive. Following this, the script will then analyze the "arrived" column for that specific VIN to check for 5 instances of "Yes" values.

If the count is as follows: (VIN number repeated) 5/5 (Number of "Yes" values), it will trigger an update in the [Master] tab Parts Order column changing it to "Yes" for that particular VIN number.

Users are required to manually update the [Parts] tab by entering either "Yes" or leaving it blank to indicate whether the part has arrived or not.

Access the Google Sheets template through the following link: https://docs.google.com/spreadsheets/d/1wlGV_QCWpRwmI5FWiOli6lXuzRATy_Goygp3lhtm-Ek/edit?usp=sharing

My attempt:

Innovative function to retrieve the last value from a column:

function getLastRowSpecial(range){
  var rowNum = 0;
  var blank = false;
  for(var row = 0; row < range.length; row++){
    if(range[row][0] === "" && !blank){
      rowNum = row;
      blank = true;

    }else if(range[row][0] !== ""){
      blank = false;
    };
  };
  return rowNum;
};

While able to determine the occurrences of each VIN Number, the challenge lies in counting the number of "Yes" values for each unique VIN. This dynamic aspect needs further development. The approach taken at the end faces limitations in terms of dynamism, especially concerning the variable 'number'.

Main Script:

      /** ---------------------- SPREAD SHEETS ---------------------- **/
      var masterS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
      var partS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parts");
      /** ----------------- Selecting Range of Cells ----------------- **/
      /** ----- Parts Spread Sheet ----- **/
      /** VIN to Match */
      var vinPartOrderRangeP = partS.getRange("C5:C");
      var vinPartValuesP = vinPartOrderRangeP.getValues();
      var columnCheckPartVINP = getLastRowSpecial(vinPartValuesP);
      var partVINDataRangeP = partS.getRange(5, 3, columnCheckPartVINP, 1);
      var partsVinSetP = partVINDataRangeP.getValues();
    
      /** Part Arrived */
      var partOrderedRangeP = partS.getRange("N5:N");
      var partOrderedValuesP = partOrderedRangeP.getValues();
      var partOrderedValuesCorrectLengthP = partOrderedValuesP.splice(0,partsVinSetP.length);
    
      /** Combining VINs with Parts Arrived */
      var vinPartsArrivedP = [];
      vinPartsArrivedP.push(partsVinSetP,partOrderedValuesCorrectLengthP);
    
      /** ----- Master Spread Sheet ----- **/
      /** VIN to Match */
      var vinPartOrderRangeM = masterS.getRange("B5:B");
      var vinPartValuesM = vinPartOrderRangeM.getValues();
      var columnCheckPartVINM = getLastRowSpecial(vinPartValuesM);
      var partVINDataRangeM = masterS.getRange(5, 2, columnCheckPartVINM, 1);
      var partsVinSetM = partVINDataRangeM.getValues();
    
      /** Part Arrived */
      var partPastRangeM = masterS.getRange("I5:I");
      var partPastValuesM = partPastRangeM.getValues();
    
     /* For-Loop getting Number of Parts that need to Arrive */
      var vinNumber = [], arrivalPartsRequired = [], prev;
    
      for (var i = 0; i < vinPartsArrivedP[0].length; i++) {
        if (vinPartsArrivedP[0][i][0] !== prev) {
          vinNumber.push(vinPartsArrivedP[0][i][0]);
          arrivalPartsRequired.push(1);
        } else {
          arrivalPartsRequired[arrivalPartsRequired.length - 1]++;
        }
        prev = vinPartsArrivedP[0][i][0];
      }
      console.log('[' + vinNumber[0] + ']','[' + arrivalPartsRequired[0] + ']')
    
      /*Now we have the count of Yes's needed per each VIN number.*/
    
      console.log(vinPartsArrivedP[0][3][0])
      var number = 0;
      var number2 = 0;
      var number3 = 0;
      var number4 = 0;
      var number5 = 0;
    
      for(var j = 0; j < partsVinSetM.length; j++) {
        
      };
      
      for(var k = 0; k < vinPartsArrivedP[0].length; k++){
        if(vinNumber[0] == vinPartsArrivedP[0][k][0]){
          number++
          for(var i = 0; i < partOrderedValuesP[0].length; i++){
            for(var j = 0; j < partOrderedValuesP[0].length; j++) {     
              if(partOrderedValuesP[i][j] == 'Yes') {
                console.log(i);
                return i+1;
              }
            }
            return -1;
          }
        }
        if(vinNumber[1] == vinPartsArrivedP[0][k][0]){
          number2++
        }
        if(vinNumber[2] == vinPartsArrivedP[0][k][0]){
          number3++
        }
        if(vinNumber[3] == vinPartsArrivedP[0][k][0]){
          number4++
        }
        if(vinNumber[4] == vinPartsArrivedP[0][k][0]){
          number5++
        }
      };
    
      console.log(number);
      console.log(number2);
      console.log(number3);
      console.log(number4);
      console.log(number5);

Answer №1

It is important to establish the following objective.

  • The main aim is to extract data from the "C" and "N" columns in the "Parts" sheet, comparing the number of matching VIN # entries in column "C" with the number of "yes" entries in column "N".
  • If both numbers are equal, the plan is to insert "yes" into column "I" on the "Master" sheet using Google Apps Script.
  • To achieve this goal, consider the following steps:

Here's a suggested sequence to accomplish your objective:

  1. Retrieve information from the "Parts" sheet.
  2. Create an object to track the count of VIN # and yes values.
  3. Formulate an array for updating the "Master" sheet.
  4. Update the values in the "Master" sheet accordingly.

The provided sample script illustrates how to execute these steps effectively.

Sample script:

function sample() {
  // 1. Retrieve values from the "Master" sheet.
  var masterS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
  var valuesOfParts = partS.getRange("C5:N" + partS.getLastRow()).getValues();
  
  // 2. Create an object for tracking the count of `VIN #` and `yes`.
  var obj = valuesOfParts.reduce((o, [c,,,,,,,,,,,n]) => {
    if (o[c]) {
      o[c].c += 1;
      if (n == "yes") o[c].yes += 1;
    } else {
      o[c] = {c: 1, yes: n == "yes" ? 1 : 0};
    }
    return o;
  }, {});

  // 3. Formulate an array for updating the "Master" sheet.
  var partS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parts");
  var rangeOfMaster = masterS.getRange("B5:B" + masterS.getLastRow());
  var valuesOfMaster = rangeOfMaster.getValues().map(([b]) => [obj[b] && obj[b].c == obj[b].yes ? "yes" : ""]);

  // 4. Update the values in the "Master" sheet.
  rangeOfMaster.offset(0, 7).setValues(valuesOfMaster);
}

References:

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

I'm looking to transfer my stringified object into the HTML body. How can I achieve

When sending an HTML file to a client using the res.write() method, I also need to include an object within the HTML. However, when I stringify the object and add it along with the HTML, the JSON object ends up outside of the HTML structure. I require the ...

What is the best way to trigger the ajax request with the same post parameter upon pressing the browser's back button?

Is there a way to remember the post parameters and resend an AJAX request when the browser back button is pressed? I have searched online and found a couple of methods: Using localsotrage or document.location.hash when the page unloads. Using cookie ...

Vanilla JavaScript MVC - Send notification to controller from model upon successful AJAX completion

I am facing some challenges with my first vanilla JS MVC app. When my model sends an AJAX request to the server, the controller updates the view before waiting for the promise to resolve, resulting in an empty update on the view. How can I inform the contr ...

Exploring the capabilities of CasperJS through double clicking

I'm currently working on creating a bot using CasperJS. The main goal is for the bot to send trade offers by offering an item, but I'm facing difficulties in figuring out how to click on the item. I attempted to use Resurrectio, however, it' ...

Interactive hover text appears when you mouse over the SVG path

Does anyone know the simplest way to display sample text when hovering over an svg path? Below is my CSS code: <style> path:hover{ fill:yellow;stroke:blue; } .available { fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;strok ...

Utilizing Google Sheets as a secure, read-only database for Angular applications without the need to make the sheet accessible to the

Seeking a way to utilize Google Sheets document as a read-only database for my Angular application, I have attempted various methods. However, the challenge with all these approaches is that they necessitate public sharing of the Sheet (accessible to anyon ...

Error: An unidentified SyntaxError occurred with an unexpected token < within an anonymous function displayed on the console

In the process of developing an upload file application. The implementation involves AJAX and PHP. Everything functions smoothly on the localhost, but upon transferring it to the web server, a specific error is encountered: Uncaught SyntaxError: Unexpe ...

Sending a POST request to a Flask server using Stripe and AJAX

I am attempting to implement a function that triggers an ajax request when a stripe form is submitted. However, using the .submit() method doesn't seem to be working as expected. Here is my current code: HTML <form action="/download_data" method= ...

Combine columns containing consistent values into one row within an R data frame

Within my data.frame d, there are columns that contain consistent numbers for each row of the first column, such as study.name (shown below). For instance, columns like ESL, ESL.1, prof, and prof.1 have constant values across all rows of Shin.Ellis and Tr ...

directive in Angular ordering

After exploring this link, my understanding deepened: http://plnkr.co/edit/k5fHMU?p=preview Upon analyzing the code snippet provided in the link above, I noticed that the Angular app consists of both a controller and a directive. However, there seems to ...

What is the proper way to reference a computed symbol that has been inherited as a function in an extended class

As a newcomer to Typescript, my understanding of the code might be lacking. I am currently working with the Klasa framework, which is built on top of Discord bot framework using Discord.js. The framework recently introduced plugin functionality and there a ...

The v-on handler is encountering an error: "ReferenceError: i18n is not defined"

I'm currently working on a Vue.js project to create a multi-language website, but I'm struggling with how to access and utilize the i18n constant. I've attempted using the eventBus approach, but it doesn't seem to be the right solution ...

Manipulating images separately using the canvas

Currently, I am utilizing an HTML5 canvas to generate a collection of trees alongside their corresponding shadows. My objective is to ensure that each shadow corresponds with the position of a designated light source. While I have successfully drawn each t ...

Importing a JavaScript file into another JavaScript file as text in React Native can be a convenient way

In my project, I have a file named MyFirstPage.js that contains the following code snippet: renderCards() { let icon = this.state.icon; .... .... .... } This code is responsible for rendering cards within the main render function. However, as the ...

Angularjs directives failing to compute accurately~

I'm working with an AngularJS directive where the HTML template is compiled within the linker function. var htmlTemplate = '<img ng-src="~/img/logos/{{account.Logo}}" width="45" height="35" />' var linker = function (scope, element) ...

How can I utilize a service for monitoring user data and ensuring that $watch() functions properly?

I'm a beginner when it comes to AngularJS and currently working on building a website that has a navigation bar dependent on the user's login status. My approach involves using a state model design with the Nav controller as the parent state for ...

Tips for sending a changing mouse scroll value as a property in VueJS

I am currently utilizing the Laravel - VueJS framework. My goal is to detect the Y position of the mouse scroll and pass it dynamically as a prop to a Navbar component. To achieve this, I set up an eventListener and stored the window.scrollY value in a va ...

Comparing partial strings using Mongodb aggregation techniques

After populating my MongoDB database with around 5000 questions, I am now looking to group questions together that are partially similar, ranging from 70% to 80% similarity, and then send them to the frontend. I attempted to achieve this using the pipelin ...

Krajee Bootstrap File Input, receiving AJAX success notification

I am currently utilizing the Krajee Bootstrap File Input plugin to facilitate an upload through an AJAX call. For more information on the AJAX section of the Krajee plugin, please visit: Krajee plugin AJAX The JavaScript and PHP (CodeIgniter) code snippe ...

Tips for transferring information from an express rendering to a Vue component?

When working with an express route, page.js router.post('/results', (req, res, next) => { output.terms = "hello" output.results = [{"text": "hello world"}, {"text": "hello sunshine"}] res.render("/myview",output) }) The cod ...