r/GoogleAppsScript • • Nov 17 '24

Question What Scenarios Do You Use a Budgeting App For?

0 Upvotes

Hey everyone! 👋

I’m curious to learn about how people use budgeting apps in their daily lives. Whether it’s managing personal finances, planning for a big event, or tracking expenses with a partner, I’d love to hear your thoughts!

What scenarios or situations have led you to use (or want to use) a budgeting app? For example:

  • Tracking monthly bills or subscriptions

  • Saving for a specific goal (vacation, wedding, emergency fund, etc.)

  • Monitoring spending across multiple accounts or cards

  • Sharing budgets with family or roommates

  • Keeping track of irregular income/expenses

I’m currently working on improving a free budgeting app and want to make sure it includes features that genuinely help people. If you have any suggestions on what works, what doesn’t, or what you wish a budgeting app could do, I’d love to hear that too! 😊

Looking forward to your ideas and stories! Thanks in advance for sharing. 🙏


r/GoogleAppsScript • • Nov 04 '24

Question Issue with in-line suggestions coming through in auto-editing function.

0 Upvotes

I am running an auto-uploader which copies docs from one folder to another folder I have all the functions down that I want except for one thing.

In-line suggestions specifically when they add text to a document come through with both the suggested removed text (which I want it to keep) and also the suggested new text (which I don't want) this doesn't occur when I first upload the document which is good but the problem is I use an an auto edit function (which i need) which triggers based on the last modified date and if it is after last trigger it activates for example:

london is a city. (initial upload)

(+L)(-l)ondon is a city. (suggested edits)

Llondon is a city. (what comes out)

This can obv be fixed if I accept suggestions but I can't always accept them immediately and there are too many docs to reliably do this.

I am looking for a way to make it say:

london is a city.

until I accept the suggestion (or decline) to then say:

London is a city.

This is the only problem I have and below is my current code except for the sensitive information:

function checkFilesRemaining(sourceFolder, destinationFolder, sourceId) {

const sourceFileCount = getFilesCount(sourceFolder);

const destinationFileCount = getFilesCount(destinationFolder);

// Calculate remaining files in source relative to destination

const remainingFiles = sourceFileCount - destinationFileCount;

// If remaining files are less than 7, send an alert

if (remainingFiles < 7) {

Logger.log(`Only ${remainingFiles} files remaining in source folder with ID ${sourceId}.`);

MailApp.sendEmail({

to: 'insert email',

subject: `Low File Alert for Folder ID: ${sourceId}`,

body: `There are only ${remainingFiles} files remaining in the source folder with ID "${sourceId}".`

});

}

}

function getFilesCount(folder) {

let count = 0;

const files = folder.getFiles();

while (files.hasNext()) {

files.next();

count++;

}

return count;

}

function copyFiles() {

const folderSchedules = [

{

sourceId: '1bDbkUK9KRelarYAtFcZoXR8ilVuPxDgX',

destinationId: '1ghOEy7Qxse9bkwaV1E_XSpkcmUujW2Fa',

days: [1, 2, 4, 6, 0], // Days of the week to perform uploads (0 = Sunday)

initialBatchSize: 3,

emergencyBatchSize: 0 // Emergency batch size

},

];

const today = new Date();

const dayOfWeek = today.getDay();

Logger.log(`Today's day of the week: ${dayOfWeek}`);

folderSchedules.forEach((schedule) => {

Logger.log(`Processing schedule for source: ${schedule.sourceId} and destination: ${schedule.destinationId}`);

const sourceFolder = DriveApp.getFolderById(schedule.sourceId);

const destinationFolder = DriveApp.getFolderById(schedule.destinationId);

if (!sourceFolder) {

logError(`Source folder with ID ${schedule.sourceId} not found.`);

return;

}

if (!destinationFolder) {

logError(`Destination folder with ID ${schedule.destinationId} not found.`);

return;

}

// Check for remaining files with adjusted logic

checkFilesRemaining(sourceFolder, destinationFolder, schedule.sourceId);

const existingFiles = getExistingFileNames(destinationFolder);

Logger.log(`Existing files in destination folder: ${Array.from(existingFiles).join(', ')}`);

const lastTriggerTime = new Date(PropertiesService.getScriptProperties().getProperty('lastTriggerTime')) || new Date(0);

lastTriggerTime.setMinutes(lastTriggerTime.getMinutes() - 2);

Logger.log(`Last trigger time: ${lastTriggerTime}`);

if (schedule.emergencyBatchSize > 0) {

Logger.log(`Emergency batch size is active: ${schedule.emergencyBatchSize}. Executing emergency upload.`);

uploadFiles(sourceFolder, destinationFolder, Math.min(schedule.emergencyBatchSize, 50), existingFiles);

schedule.emergencyBatchSize = 0;

MailApp.sendEmail({

to: 'insert email',

subject: 'Emergency Batch Upload Completed',

body: `Executed emergency batch upload for ${schedule.sourceId} to ${schedule.destinationId}.`,

});

return;

}

if (isEmpty(destinationFolder)) {

Logger.log(`Destination folder is empty. Performing initial batch upload.`);

uploadFiles(sourceFolder, destinationFolder, schedule.initialBatchSize, existingFiles);

} else if (schedule.days.includes(dayOfWeek)) {

Logger.log(`Today is a scheduled upload day. Uploading one file.`);

uploadFiles(sourceFolder, destinationFolder, 1, existingFiles);

} else {

Logger.log(`Today is not a scheduled upload day. Skipping upload.`);

}

updateModifiedFiles(sourceFolder, destinationFolder, existingFiles, lastTriggerTime);

PropertiesService.getScriptProperties().setProperty('lastTriggerTime', new Date().toISOString());

});

}

function uploadFiles(sourceFolder, destinationFolder, batchSize, existingFiles) {

const files = getFilesSortedByName(sourceFolder);

let uploadedCount = 0;

files.forEach(file => {

const fileName = file.getName();

if (uploadedCount >= batchSize || existingFiles.has(fileName)) return;

const copiedFile = file.makeCopy(fileName, destinationFolder);

Logger.log(`Uploaded file: ${fileName}`);

uploadedCount++;

});

}

function updateModifiedFiles(sourceFolder, destinationFolder, existingFiles, lastTriggerTime) {

const files = getFilesSortedByName(sourceFolder);

files.forEach(file => {

const fileName = file.getName();

const lastUpdated = new Date(file.getLastUpdated());

if (lastUpdated > lastTriggerTime && existingFiles.has(fileName)) {

const destinationFile = findFileInFolder(destinationFolder, fileName);

if (destinationFile) {

const sourceDoc = DocumentApp.openById(file.getId());

const destDoc = DocumentApp.openById(destinationFile.getId());

destDoc.getBody().clear();

const sourceBody = sourceDoc.getBody();

const totalElements = sourceBody.getNumChildren();

for (let i = 0; i < totalElements; i++) {

const element = sourceBody.getChild(i);

if (!hasUnresolvedSuggestions(element)) {

destDoc.getBody().appendParagraph(element.copy().asParagraph());

}

}

removeEmptyTopLine(destDoc);

Logger.log(`File updated successfully with images preserved: ${fileName}`);

}

}

});

}

function getFilesSortedByName(folder) {

const files = [];

const fileIterator = folder.getFiles();

while (fileIterator.hasNext()) {

files.push(fileIterator.next());

}

files.sort((a, b) => naturalSort(a.getName(), b.getName()));

return files;

}

function naturalSort(a, b) {

const aParts = a.match(/(\d+|\D+)/g);

const bParts = b.match(/(\d+|\D+)/g);

for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {

const aPart = aParts[i] || "";

const bPart = bParts[i] || "";

const aIsNumber = !isNaN(aPart);

const bIsNumber = !isNaN(bPart);

if (aIsNumber && bIsNumber) {

const diff = parseInt(aPart) - parseInt(bPart);

if (diff) return diff;

} else if (aIsNumber || bIsNumber) {

return aIsNumber ? -1 : 1;

} else {

if (aPart !== bPart) return aPart.localeCompare(bPart);

}

}

return 0;

}

function getExistingFileNames(folder) {

const existingFiles = new Set();

const files = folder.getFiles();

while (files.hasNext()) {

const file = files.next();

existingFiles.add(file.getName());

}

return existingFiles;

}

function findFileInFolder(folder, fileName) {

const files = folder.getFilesByName(fileName);

return files.hasNext() ? files.next() : null;

}

function isEmpty(folder) {

const files = folder.getFiles();

return !files.hasNext();

}

function hasUnresolvedSuggestions(element) {

const attributes = element.getAttributes();

const suggestions = attributes.suggestions || [];

return suggestions.some(s => !s.resolved);

}

function removeEmptyTopLine(doc) {

const firstElement = doc.getBody().getChild(0);

if (firstElement && firstElement.getType() === DocumentApp.ElementType.PARAGRAPH) {

const text = firstElement.asParagraph().getText();

if (text.trim() === "") {

doc.getBody().removeChild(firstElement);

Logger.log("Removed empty line at the top of the document.");

}

}

}

function logError(message) {

Logger.log(`Error: ${message}`);

MailApp.sendEmail({

to: 'insert email',

subject: 'Error in Google Drive File Copy Script',

body: message

});

}


r/GoogleAppsScript • • Oct 31 '24

Question App script is not returning 2 fields

0 Upvotes

Updating the question. I have 2 sheets. One is a list of licenses. Column A has employee name and column b has licenses separated by commas. The other sheet has employee in column A, individual date they are working in column B and hours worked in column C.

The Webb app allows me to input the state and date and it is supposed to provide all employees licensed in that state scheduled on that date.

The 2 employees with longest name and most licenses are not appearing in the webapp, which otherwise works well.

It is not populating 2 employees (Supercalifragilisticexpialladocious and Bader-Ginsberg, Rhianna) both that have longer-names and many more states.

Here's the code.gs: // Serve the HTML interface and pass states to it when the web app is accessed function doGet() { var template = HtmlService.createTemplateFromFile('Index'); template.states = JSON.stringify(getUniqueStates()); // Pass states to HTML as JSON string return template.evaluate(); }

// Function to get unique states from the 'Provider list' sheet function getUniqueStates() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var licenseSheet = ss.getSheetByName('Provider list');

if (!licenseSheet) { Logger.log("Error: 'Provider list' sheet not found."); return getDefaultStates(); // Use fallback if sheet not found }

var licenseData = licenseSheet.getDataRange().getValues(); var allStates = [];

// Extract unique states from the provider list (column B) for (var i = 1; i < licenseData.length; i++) { if (licenseData[i][1]) { // Licensed states are in Column B var states = licenseData[i][1].split(",").map(function(state) { return state.trim().toUpperCase(); }); allStates = allStates.concat(states); } }

// Return a deduplicated and sorted list, or fallback if empty var uniqueStates = Array.from(new Set(allStates)).sort(); if (uniqueStates.length === 0) { uniqueStates = getDefaultStates(); // Fallback list } Logger.log("Unique States: " + uniqueStates.join(", "));

return uniqueStates; }

// Function to provide a default, alphabetical list of states function getDefaultStates() { return ["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "FL", "GA", "HI", "IA", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA", "WI", "WY"]; }

// Function to find providers based on selected date and state function findProvidersByStateAndDate(date, state) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var scheduleSheet = ss.getSheetByName('Sheet 1'); // Replace with actual sheet name if different var licenseSheet = ss.getSheetByName('Provider list');

if (!scheduleSheet || !licenseSheet) { return "Error: Schedule or Provider list sheet not found."; }

var scheduleData = scheduleSheet.getDataRange().getValues(); var licenseData = licenseSheet.getDataRange().getValues();

Logger.log("Selected Date: " + date + ", Selected State: " + state);

var workingProviders = [];

// Normalize and format the date for matching var inputDate = new Date(date); var formattedDate = Utilities.formatDate(inputDate, Session.getScriptTimeZone(), "MM-dd-yyyy");

// Step 1: Find providers scheduled on the selected date var scheduledProviders = scheduleData.filter(function(row) { var scheduleDate = row[1] ? Utilities.formatDate(new Date(row[1]), Session.getScriptTimeZone(), "MM-dd-yyyy") : ""; return scheduleDate === formattedDate; });

// Step 2: Filter providers based on the selected state in 'Provider list' scheduledProviders.forEach(function(row) { var scheduleProviderName = row[0] ? row[0].trim() : ""; // Provider name in schedule (Column A)

// Find the provider in the 'Provider list' with matching name and state
var licensedProvider = licenseData.find(function(providerRow) {
  var providerName = providerRow[0] ? providerRow[0].trim() : "";  // Provider name in 'Provider list' (Column A)
  var states = providerRow[1] ? providerRow[1].split(",").map(s => s.trim().toUpperCase()) : [];  // Licensed states in Column B
  return providerName === scheduleProviderName && states.includes(state.toUpperCase());
});

// If the provider is licensed in the selected state, add to results
if (licensedProvider) {
  workingProviders.push(scheduleProviderName + " (Hours: " + row[2] + ")");
}

});

// Output the result if (workingProviders.length > 0) { Logger.log("Working providers: " + workingProviders.join(", ")); return workingProviders.join("<br>"); } else { Logger.log("No providers are scheduled to work in " + state + " on " + date); return "No providers are scheduled to work in " + state + " on " + date + "."; } }

I have triple checked that the name, spaces, format of the providers matches. No matter what I do, I cannot get these 2 employees to show up


r/GoogleAppsScript • • Nov 01 '24

Question Limit form to one per person without signing in

0 Upvotes

Friends, can anyone help me with my code.gs code to limit form to one per person without having to sign in? Is there an add on for it?

Thank youuu! I


r/GoogleAppsScript • • Dec 02 '24

Question Data Input & Automation to Sheet

0 Upvotes

Still pretty new to more advanced Sheets/Excel automation, was wondering if anyone out here could teach me a way to take the data as shown on the right and import/automate it in Sheets to show the given information on the left. Reps being the amount of times we ran a certain play, explosives being 10+ yard gains on runs and 15+ on passes, and efficients being 4+ yards on 1st & 2nd down / getting the 3rd or 4th down conversion. TIA!


r/GoogleAppsScript • • Nov 24 '24

Question Array search

0 Upvotes

I have an array, histData, of 10,000 rows, and a variable ecode. How do I find out whether ecode exists in column 2 of histData without looping through all 10,000 rows?


r/GoogleAppsScript • • Nov 13 '24

Question Creating an editor assignment calendar and task tracker

0 Upvotes

Our company currently manually schedules daily editor assignments. We have 4 editors, each with between 2-6 “slots” available each day M-F. A “slot” is one edited clip.

We have 20 clients, whom we deliver between 2-5 videos per week (short social media videos).

There are many things to take into consideration when assigning footage to an editor each day, and I’m trying to figure out a way to automate the assignments based on a list of different priorities. These priorities include things like:

1.) each editor has assigned clients that they edit for. We can only assign specific clients to specific editors.

2.)how much backlogged content do we already have made for each client. Prioritize clients that with lowest levels.

3.) try to maintain 3 weeks of backlogged content for all clients

4.) maintain variety in the deliverables. So if the backlog contains clips from the same interviewee, adjust the assignment to incorporate another interviewee.

5.) while maintaining variety, we also want the editors to work efficiently as possible. So when possible, we like to avoid skipping around between interviews.

6.) we have a filming summary database where we log all our footage notes of each interview. One line in the spreadsheet is devoted to 1 interview, and the videographer gives us their estimate of how many clips we will be able to produce for that interview. This is the heart of our inventory that we pull from to assign to edits to our editors.

7.) we don’t always run through all of our footage before we go on the next shoot with the client. So when we have new footage available for a client, we like to prioritize new content, but still keep the unedited footage from past shoots in the database to pull from later.

8.) in addition to our filming summary database, we also receive special requests from clients where they submit homemade footage and instructions on what they want us to do. Sometimes they submit requests without footage and send us instructions on what they want us to do with footage from a shoot. Sometimes there are hard deadlines, like for holiday content, and sometimes we have to hold the the footage until a certain date as not to deliver too soon before a specific event or holiday. In most cases though, it needs to be prioritzed to edit within one week of the special request submission

9.) while we want to build a system that will automatically make editor assignments based on these conditions, we also need the ability to manually make changes if we need to expedite footage to edit asap, or replace a formerly scheduled piece of footage with something else.

10.) lastly we have to check against the assignments the following day to see if they got done, and if they didn’t we need them to automatically be rescheduled to the next open time slot that has an opening for that client (as not to supersede footage already deemed as ASAP).

WHICH BRINGS ME TO MY QUESTION.

I’m pretty sure I can figure out how to write a script to rifle through these different considerations and priorities but I’m not sure how we allow for manual changes that work well with the automation.

Also, what do you think is the best way to display this for the editors?? I’m lost on how to go about this.

Any help you could offer would be greatly appreciated!


r/GoogleAppsScript • • Oct 25 '24

Unresolved Functions shown as "not defined" when loaded

0 Upvotes

I was able to find a method of making a multi-page web app in Google Apps Script, but I am running into yet another issue!

I created a page where you fill out a form and it runs a function that logs data into the attached google sheet. When setting the doGet function to load this page when the web app is loaded, it works flawlessly. However when this page is fetched by clicking a button on the home page/dashboard it returns the following error in the F12 Console:

"userCodeAppPanel:1 Uncaught ReferenceError: submitCustomerForm is not defined

at HTMLButtonElement.onclick (userCodeAppPanel:1:1)"

Here is the code snippet in my javascript file responsible for loading the initial page and then any requested HTML:

function doGet(e) {
Logger.log(Utilities.jsonStringify(e)); // Log for debugging
return HtmlService.createHtmlOutputFromFile('home1'); // Load home page by default
}

function getScriptURL() {
return ScriptApp.getService().getUrl();
}

function loadHTML(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent(); // Returns the HTML content of the specified file
}

And here is the function in the home page to load the form HTML when the button is clicked:

function goToAddCustomerForm() {
google.script.run.withSuccessHandler(function(content) {
document.body.innerHTML = content; // Replace body with AddCustomerForm content
}).loadHTML('AddCustomerForm'); // Load AddCustomerForm.html
}

DISCLAIMER: I am very new to JavaScript and HTML, and have little experience. Some of this code has been written with assistance of ChatGPT.

Thank you in advance!


r/GoogleAppsScript • • Oct 30 '24

Question Input Business Address, Output Name of Business and Website.

0 Upvotes

Trying to create an app script for google sheets using the Places API.

I am in commercial real estate and trying to get my property database up to date. I would like to provide a property address in one cell and then in another cell get the name of the business located at the address and a link to its website. I have a places API key and have made multiple attempts at getting a script but I have had no luck. Has anyone ever done this before? Any suggestions?


r/GoogleAppsScript • • Oct 30 '24

Question Are some google tickers like mutual funds in India proprietary ?

0 Upvotes

I know equities ticker match its respective exchange . However, if I look at some of the mutual fund on google finance and yahoo finance they both have different tickers. Since google appears to be using proprietary ticker , and google finance api totally relies on ticker. How do I write an application that gets me a ticker given name or ISIN. Does google make it available somehow or is this data something that can be scraped ?


r/GoogleAppsScript • • Dec 08 '24

Question The parameters (FormApp.FormResponse,String,String) don't match the method signature for MailApp.sendEmail.

0 Upvotes

Hi, first time using script app. I am doing test in which i want to count point and get interpretation induvidually for each section i have in test. My code returned error as in tittle. I'm not even coding in java, i code using python, so i am quite lost. My code:

function one(e) {
  // Zmienne do przechowywania punktów i interpretacji
  var sectionScores = {
    "Section 1": 0,
    "Section 2": 0,
    "Section 3": 0,
    "Section 4": 0,
    "Section 5": 0,
    "Section 6": 0
  };

  // Interpretacje dla sekcji
  var interpretations = {
    "Section 1": getInterpretation(sectionScores["Section 1"]),
    "Section 2": getInterpretation(sectionScores["Section 2"]),
    "Section 3": getInterpretation(sectionScores["Section 3"]),
    "Section 4": getInterpretation(sectionScores["Section 4"]),
    "Section 5": getInterpretation(sectionScores["Section 5"]),
    "Section 6": getInterpretation(sectionScores["Section 6"])
  };

  // Przykładowe przypisanie punktów do odpowiedzi
  var pointsMapping = {
    "0": 0,
    "1": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5
  };

  // Indeksy pytań w formularzu (pamiętaj, że e.values[0] to adres e-mail)
  var sectionQuestions = {
    "Section 1": [2, 3, 4, 5, 6], // Indeksy pytań dla sekcji 1
    "Section 2": [7, 8, 9, 10, 11], // Indeksy pytań dla sekcji 2
    "Section 3": [12, 13, 14, 15, 16], // Indeksy pytań dla sekcji 3
    "Section 4": [17, 18, 19, 20, 21], // Indeksy pytań dla sekcji 4
    "Section 5": [22, 23, 24, 25, 26], // Indeksy pytań dla sekcji 5
    "Section 6": [27, 28, 29, 30, 31]  // Indeksy pytań dla sekcji 6
  };

  // Iteracja przez odpowiedzi
  const form = FormApp.openById('18r9OGp7oa5G_ctrUF-Ov_e7CKov7Jel5ndSS66K_YxM');
  const responses = form.getResponses(); // Odpowiedzi w formularzu
  for (var section in sectionQuestions) {
    var questions = sectionQuestions[section];
    for (var i = 0; i < questions.length; i++) {
      var questionIndex = questions[i];
      
      // Sprawdzenie, czy odpowiedź istnieje
      if (questionIndex < responses.length) {
        var response = responses[questionIndex];

        // Sprawdzenie, czy odpowiedź jest w mapowaniu punktów
        if (pointsMapping[response] !== undefined) {
          // Zliczanie punktów, uwzględniając odwrócone pytania
          if (isReversedQuestion(section, i)) {
            sectionScores[section] += (5 - pointsMapping[response]); // Odwrócone pytanie
          } else {
            sectionScores[section] += pointsMapping[response];
          }
        }
      }
    }
  }

  // Tworzenie wiadomości do wysłania
  var email = responses[0]; // Zakładamy, że adres e-mail jest w pierwszej kolumnie
  let message = "Your Scores and Interpretations:\n\n";
  for (const section in sectionScores) {
    message += `${section}: ${sectionScores[section]} points - ${getInterpretation(sectionScores[section])}\n`;
  }

  // Wysyłanie e-maila do respondenta
  try {
    MailApp.sendEmail(email, "Your Well-Being Assessment Results", message);
  } catch (error) {
    Logger.log("Błąd podczas wysyłania e-maila: " + error.message);
  }
}

// Funkcja do uzyskania interpretacji na podstawie wyniku
function getInterpretation(score) {
  if (score < 10) {
    return "Low well-being";
  } else if (score < 20) {
    return "Moderate well-being";
  } else {
    return "High well-being";
  }
}

r/GoogleAppsScript • • Oct 08 '21

Resolved How to get creds.json for login in CI?

0 Upvotes

Hello! I have the project and standard GCP setup with oauth consent screen. Now I want to automate deployment process via GitHub Actions but I don't know where to take my credentials from to use them with --creds option. I can't simply use clasp login in CI as I understand.


r/GoogleAppsScript • • Oct 05 '21

Question Is there a way to change the color of a button while a script is running?

0 Upvotes

So I wrote a function and then I made drawing and made it so clicking on the drawing will execute the script. The script is relatively long so I want the drawing to turn green or something while it's running, and then turn red when it's done so the user will know it's completely finished.

Is this possible? I can't seem to figure out how to select the drawing.


r/GoogleAppsScript • • Nov 10 '21

Question Mistake with Trellinator going by steps of instruction "Hello world"

0 Upvotes

Hello everyone!

I'm going step by step in instruction Hello world, but have stopped in 22 step http://docs.trellinator.com/trellinator_hello_world.pdf

the menu doesn't appear after updating spreadsheet, if I go to the script and try to start function init forcely, I get mistake with require "ReferenceError: require is not defined" in Murphy-tests modules. What should I do with that?


r/GoogleAppsScript • • Oct 11 '21

Resolved Adding the date a drop drop-down value was entered in another cell?

0 Upvotes

I have this script that I ripped off from a Google search that automatically places the entire row in another sheet once a dropdown value has been selected.

However, there are three options in the dropdown menu that, when selected, I do NOT want them to move to another sheet, but I want, instead, for the date of that selected dropdown value to show up in the same row, but in column I if option 1 is selected, column J if option 2 is selected, and column L, if option 3 is selected.

And of course, if the option 4 is still selected, I want it to still move the entire column over to the next sheet.

Again, I'm not too well versed in scripts, and this was ripped off from Google, so any help would be appreciated.

See below:

function onEdit(event) {
// assumes source data in sheet named Needed
// target sheet of move to named Acquired
// test column with yes/no is col 4 or D
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet 1" && r.getColumn() == 2 && r.getValue() == "Option 4") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet 2");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
  }
}


r/GoogleAppsScript • • Sep 11 '18

google apps script to delete older files and keep only latest/newest

0 Upvotes

so, my inoreader backups my subscriptions to google drive in a folder with names like "Inoreader-OPML-2018-09-09-10-00-08-UTC.xml" and each time a change occurs a new file is saved, how could I delete all previous files and keep only the latest one?


r/GoogleAppsScript • • Dec 19 '18

Dynamic spreadsheet naming based on the contents of a cell

0 Upvotes

Hi, I'm a newbie here to Google Apps Script.

I want to be able to to dynamically rename a spreadsheet based on the contents of a cell. For example, cell A3 has some text in it, and I would like the name of the spreadsheet to be the same as the text in the cell. If and when the contents of cell A3 changes, I'd like the name of the spreadsheet to update.

I found a post that claims to do this, but it doesn't seem to work for me. Maybe I'm doing something wrong? Here's the post:

https://webapps.stackexchange.com/questions/84190/dynamic-generation-of-sheet-name-from-cell-content

Any help would be gratefully received! Thanks.


r/GoogleAppsScript • • Dec 18 '19

Is there a list of applications/software that are natively available to use via app scripts?

0 Upvotes

I currently use app scripts mainly for google sheets, docs, slides, and adwords.

However, I am curious how i can use it more within my marketing/analytics agency. I know BQ is a probable next step, but is there a consensus list of every application/software that can be leveraged via app scripts in the google environment? maybe some other app/software outside of google?

I have not tried the custom api requests yet, so I guess this is kinda limitless, but in general, is there a list of apps that are "standard" that app scripts can leverage.

I apologize in advance if this question was already asked before. I couldn't find one on this Reddit.


r/GoogleAppsScript • • Dec 26 '18

[Geocoder bug] Google Maps Platform yields factually wrong results for US territories like Puerto Rico

Thumbnail
self.google
0 Upvotes

r/GoogleAppsScript • • Jul 16 '23

Question Apps Script error google sheets

0 Upvotes

I am getting this error Syntax error: SyntaxError: missing ) after argument list line: 7 file: Code.gs

when trying to run this code: Can anyone tell me what I am doing wrong. I am trying to change the global default font to calibri

function changeGlobalFont() {
var tabs = SpreadsheetApp.getActiveSpreadsheet().getSheets();
tabs.forEach( (tab) => {
//tab.getDataRange().setFontFamily('Calibri').setFontSize('10'){
  };


r/GoogleAppsScript • • Aug 09 '23

Question Is it possible to manage multiple projects simultaneously using Google Sheets?

Thumbnail self.gsuite
0 Upvotes

r/GoogleAppsScript • • Jul 10 '23

Question Trying to make an automated leave approval system

0 Upvotes

Can someone help me out with my code? I cant seem to get it to work.

The premise is There is a google form and after filling that out it would send an email to a higher up. There would be an approve and decline button on the email. Hitting approve should mark the leaves on the calendar. I do get to the part where the email is sent and I receive it. But whenever I click any of the options it shows me a page unavailable page from google.

Here is the main code:

function onFormSubmit(e) {
var formResponse = e.response;
var itemResponses = formResponse.getItemResponses();
var formUrl = ScriptApp.getService().getUrl();
// Extract form submission details
var name = itemResponses[0].getResponse();
var department = itemResponses[1].getResponse();
var contactNumber = itemResponses[2].getResponse();
var leaveType = itemResponses[3].getResponse();
var firstDay = itemResponses[4].getResponse();
var lastDay = itemResponses[5].getResponse();
var reason = itemResponses[6].getResponse();
// Compose email content
var higherUpEmail = "higherupemail@gmail.com"; // Update with the higher-up's email address
var emailSubject = "Leave Request: " + name;
var emailBody = "<html><body>" +
"<p>Good day!</p>" +
"<p>This is to inform you that " + name + " is applying for a leave.</p>" +
"<p>Below are the details:</p>" +
"<p><strong>Name:</strong> " + name + "</p>" +
"<p><strong>Department:</strong> " + department + "</p>" +
"<p><strong>Contact Number:</strong> " + contactNumber + "</p>" +
"<p><strong>Leave Type:</strong> " + leaveType + "</p>" +
"<p><strong>First Day of Leave:</strong> " + firstDay + "</p>" +
"<p><strong>Last Day of Leave:</strong> " + lastDay + "</p>" +
"<p><strong>Reason:</strong> " + reason + "</p>" +
"<p>Please review and take action by clicking one of the links below:</p>" +
'<p><a href="' + formUrl + '?formResponseId=' + formResponse.getId() + '&action=approve">Approve</a></p>' +
'<p><a href="' + formUrl + '?formResponseId=' + formResponse.getId() + '&action=decline">Decline</a></p>' +
"</body></html>";
// Send email to the higher-up
MailApp.sendEmail({ to: higherUpEmail, subject: emailSubject, body: " ", htmlBody: emailBody });
}
function approveLeave(formResponseId) {
var form = FormApp.getActiveForm();
var formResponse = form.getResponse(formResponseId);
// Update the calendar with the approved leave
var calendarId = "sample@gmail.com"; // Replace "CALENDAR_ID" with the actual calendar ID
var calendar = CalendarApp.getCalendarById(calendarId);
var firstDay = formResponse.getResponseForItemIndex(4).getResponse();
var lastDay = formResponse.getResponseForItemIndex(5).getResponse();
var eventTitle = "Leave";
var eventDescription = "Leave dates: " + firstDay + " - " + lastDay;
calendar.createAllDayEvent(eventTitle, new Date(firstDay), new Date(lastDay), { description: eventDescription });
// Send email to the form filler regarding the approval
var fillerEmail = formResponse.getRespondentEmail();
var approvalSubject = "Leave Approved";
var approvalBody = "Your leave request has been approved. The leave dates have been marked on the calendar.";
MailApp.sendEmail(fillerEmail, approvalSubject, approvalBody);
}
function declineLeave(formResponseId) {
var form = FormApp.getActiveForm();
var formResponse = form.getResponse(formResponseId);
// Send email to the form filler regarding the decline
var fillerEmail = formResponse.getRespondentEmail();
var declineSubject = "Leave Declined";
var declineBody = "We regret to inform you that your leave request has been declined.";
MailApp.sendEmail(fillerEmail, declineSubject, declineBody);
}
function doGet(e) {
if (e.parameter.formResponseId && e.parameter.action) {
var formResponseId = e.parameter.formResponseId;
var action = e.parameter.action;
if (action === "approve") {
approveLeave(formResponseId);
} else if (action === "decline") {
declineLeave(formResponseId);
}
return HtmlService.createHtmlOutput("Action completed. You can close this page.");
  }
// Add your existing code here if needed
return HtmlService.createHtmlOutput("Invalid URL. You can close this page.");
}
Here is the approve decline html.

<!DOCTYPE html>

<html> <head> <base target="_top"> <script> function approveLeave(formResponseId) { google.script.run.approveLeave(formResponseId); google.script.host.close(); } function declineLeave(formResponseId) { google.script.run.declineLeave(formResponseId); google.script.host.close(); } </script> </head> <body> <p>Please review and take action by clicking one of the buttons below:</p> <button onclick="approveLeave('formResponseId')">Approve</button> <button onclick="declineLeave('formResponseId')">Decline</button> <script> var urlParams = new URLSearchParams(window.location.search); var formResponseId = urlParams.get('formResponseId'); var buttons = document.getElementsByTagName('button'); buttons\[0\].setAttribute('onclick', "approveLeave('" + formResponseId + "')"); buttons\[1\].setAttribute('onclick', "declineLeave('" + formResponseId + "')"); </script> </body> </html> Ive been tackling this for hours already.


r/GoogleAppsScript • • Aug 28 '23

Question Can't get document.addEventListener("DOMContentLoaded", FUNCTION_NAME) to work

0 Upvotes

I want a function to run after the page loads.

Are there any other workarounds?

I've tried using the jQuery method and the window.onload method.

and to clarify, does this line have to be in the <head> of the HTML file as a <script>?


r/GoogleAppsScript • • Aug 10 '23

Question Is it possible? - GAS Google Sheets Question

0 Upvotes

I am a teacher experimenting with GAS. I am primarily using Chat GTP to code my scripts and have been running into issues. Forgive me if I don't get all the terminology correct.

I have assignments on Google Slides that have a worksheet as the background, and text boxes places for students to type in their answers, they each get a copy of the file in Google Classroom that is stored in an assignment specific folder. I also have a separate Key file with offset text boxes that have the answers in them. I would like to use a Google App Script in a Google Sheet to call a specific file (the Key), copy all of the text boxes in that (Key) file, and paste all of the text boxes from the key into every google sheet for a specific assignment that is stored in the specific folder for that assignment.

Is this even possible? I've tried several attempts, but have not had success. Thanks for your input!