Utilizing Google Apps Script to streamline the process of converting unnormalized data into normalized data within Google Sheets

I am working with a Google Spreadsheet that contains 3 separate raw data worksheets named 'Category1', 'Category2', and 'Category3'. These worksheets are regularly updated by different individuals in my company, but the data is not organized in a normalized manner, which makes it difficult to perform efficient queries.

My goal is to develop a script that can automatically generate normalized Output sheets ('Category1 Output', 'Category2 Output', 'Category3 Output') based on the raw data. These output sheets should update themselves whenever changes are made to the raw tabs.

In the Google Sheet shared below, I have exemplified what one of the Categories should look like. The 'Category1' worksheet serves as the original data source that undergoes constant updates. The 'Category1 Output' sheet is the final output that dynamically adjusts itself following any modifications in the 'Category1' worksheet.

Link to Google Sheet

Answer №1

The individual inquiring has a setup with three sheets arranged in columns, featuring multiple rows per data set and various columns for each time period. Instead of replacing the sheets, they wanted a condensed version where filtering could be utilized to focus on relevant data effectively. The objective was to translate each sheet from a columnar format to a row-wise format.

The process itself is relatively straightforward. The original dataset consisted of 64 products with 8 data rows allocated per product. This resulted in an output of approximately 1,350 records.

The main issue faced by the questioner's code arose during the conversion of data to the desired output format. Ensuring that there were exactly 8 rows of data per product was essential, which prompted a validation check within the code to confirm this requirement. Additionally, specific sheets were identified using names (via getSheetByName) to facilitate easy application of the code to any designated Input Sheet and Output sheet. However, it was imperative that both sheets existed prior to running the code.

An initial fix was made to address the coding hiccup encountered by the questioner. By implementing the methodology of getDataRange and getValues before the looping process, performance greatly improved. Two loops were employed - one vertical for moving through the data rows, and the other horizontal for navigating the time-related columns. While the original implementation suffered from inefficiency leading to timeouts, a modification involving building a single 2D array and only saving it to the Output sheet once at the end significantly boosted performance. Completion time dropped drastically from several minutes to under 5 seconds.


function so5243560403() {
    // The function for creating a clean Output Sheet
}

function isInt1(value) {
    return !isNaN(value) && parseInt(Number(value)) == value && !isNaN(parseInt(value, 10));
}

UPDATE

A critical component in the questioner's code pertained to updating data on an "Output Sheet" when modifications were made to "Category” sheets. Although the base structure of the update code was sound, a pivotal element missing was translating the source range on the Category Sheet to establish the corresponding target range on the Output sheet.

The solution revolved around employing a mathematical numeric sequence approach. Specifically, the numerical sequence represented the row numbers for products on the source sheet, with each product spanning 8 rows starting from the first row (#10). Hence, given the row number of a change event, determining the relevant product group required computations based on the sequential pattern. As changes often occurred across different rows within a product, calculating the precise product grouping and subsequently identifying the altered fields were crucial steps efficiently implemented via algorithmic formulas.

The functionality incorporated within the updated section systematically decoded the relationships between changed cells, product sequences, week numbers, and associated field alterations on the Output sheet. By leveraging nuances like row differences, cycle positions, and column shifts, the updated code successfully pinpointed the exact locations for introducing new values obtained post-edit events.


function OnEdit(e) {
    // Functionality for updating relevant Outputsheets based on edits in Category sheets
}

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

What is the best way to insert text into a span element within a for loop using JavaScript?

I am currently working on form validation using an array and a loop. In each required field, I have created empty span elements. Here is the JavaScript code that I have set up: var name = document.querySelector('#Name').value, firstLastName = ...

What is the use of the typeof operator for arrays of objects in TypeScript?

How can I update the any with the shape of the options's object below? interface selectComponentProps { options: { label: string; value: string; }[]; } const SelectComponent: React.FC<selectComponentProps> = ({ options, }) => ...

How can I remove the div container every time the submit button is clicked?

I am currently working on a form that is capturing values as shown below. <form role="form" id="calculate"> <div class="form-group"> <select class="form-control" id="paper"> < ...

Is it necessary to establish a connection to my mongodb database directly within my jest test file, or is it permissible to invoke functions from separate classes that handle the database connection?

Currently in the process of testing my database functions using jest. My javascript file contains a variety of functions that connect to the database, retrieve data, and return an array. The issue I'm facing is when calling these functions from my jes ...

Encountering an issue with the v-carousel component from Vuetify: receiving a 'Cannot read property 't' of undefined' error message

Currently, I am trying to create an image carousel using Laravel along with Vue/Vuetify. The issue lies in the fact that the Vuetify v-carousel and v-carousel-item components are not rendering properly due to the error mentioned in the title. I have alrea ...

Is there a way to verify that all of my HTML elements have been loaded in AngularJS?

I am currently utilizing angularJS version 1.2.1 along with angular-ui-bootstrap. Within my code, I have a collection of <ng-includes> tags from angularjs and <accordion> components from angular-ui. When loading the content, I need to initiat ...

Adding content to the parent element immediately after it is generated using jQuery

Is there a way to trigger $(e).append() as soon as the element e is created without using setTimeout()? I find that method inefficient. Are there any DOM events that can detect changes in a subtree of a DOM element? Usually, I would just add the code to t ...

There is currently no feature to integrate postal code objects within React's Stripe elements

I'm currently working on designing a custom form for Stripe. Instead of using the entire card element, I am opting to bring in individual components from Stripe elements for better styling options. My goal is to layout these individual inputs in a gri ...

Having difficulty positioning the dropdown above the other elements in the body

Below, you'll notice that the dropdown menu isn't positioned correctly over other body elements like the timer. I'm utilizing bootstrap for the dropdown and redcountdown js for the timer. https://i.sstatic.net/OO8Jm.png Here is the HTML: & ...

Waiting for a promise in node.js that is not yet resolved

I have an async function in my "app.js" that is waiting for a connection to be ready from the imported connection.js file. I am struggling with getting app.js to work correctly with the "await". I am unable to add an export in the 'on' function ...

How can I arrange selected options at the top in MUI autocomplete?

I am currently working with mui's useAutocomplete hook https://mui.com/material-ui/react-autocomplete/#useautocomplete Is there a way to programmatically sort options and place the selected option at the top using JavaScript sorting, without resorti ...

Is there a way to apply -webkit-text-fill-color using pure vanilla JavaScript?

My website features two a links, and I am utilizing JavaScript to set their href attributes. When there is no link provided, the color changes to black. However, in Safari on iPhone, achieving the correct color requires the use of -webkit-text-fill-color ...

Issue encountered when executing the migration fresh seed: SyntaxError, which indicates the absence of a closing parenthesis after the

Having trouble with a nextJS project that utilizes mikro-orm? Struggling to overcome this persistent error for days: C:\Users\BossTrails\Documents\core.nest-main_2\node_modules\.bin\mikro-orm:2 basedir=$(dirname "$(e ...

An issue has occurred: Cannot access the properties of an undefined object (specifically 'controls')

I encountered an error message stating "TypeError: Cannot read property 'controls' of undefined" in the code that I am not familiar with. My goal is to identify the source of this error. Below is the HTML code snippet from my webpage: <div ...

Javascript : What is the method to access the array index of a string?

Hey there, I'm struggling with changing a string to invoke an array in JavaScript. Can someone please help me out? So, I have this array: var fruit=['Apple','Banana','Orange']; And I also have a data string from MySQL: ...

JQuery does not have the ability to compare the current date and

I've encountered an issue while comparing two date scripts that resulted in incorrect output. Here is the code that I used: var current = new Date(); var date = new Date($(this).val()); alert(current) == "Sat Aug 23 2014 14:42:00 GMT+0700 (ICT)" aler ...

Slick Slider isn't compatible with Bootstrap Tab functionality

I'm having an issue with using slick slider within a Bootstrap tab menu. The first tab displays the slick slider correctly, but when I switch to the second tab, only one image is shown. How can I resolve this problem? <!DOCTYPE html> <html ...

Using Node.js to seamlessly read and upload files with Dropbox API

I am utilizing the Dropbox API to retrieve a file from the node.js file system and then transfer it into a designated Dropbox folder. The transfer process is successful, but the file ends up being empty, with a size of 0 bytes. var path = require("path") ...

What could be causing the abortTransaction() method in mongoose to not function as

System OS: MacOS 10.15.5 NodeJS Version: 10.16.3 Mongoose Versions: 5.8, 5.9 MongoDB Version: 4.0.3 The following code snippet is in question: import User from 'models/user' const session = await User.startSession() session.startTransaction() ...

What is the best way to extract data from a JSON object using JavaScript, Node.js, or React?

The data received from the server includes information on two different products: [{ "model": "G7", "brand": "LG", "price": 999.99, "image": "https://www.bell.ca/Mobility/Products/LG-G7-ThinQ?INT=MOB_mobdevpg_BTN_poplink_Mass_051016_mb_details#", ...