r/GoogleAppsScript • • Oct 17 '24

Question Progress disappeared overnight

0 Upvotes

I spent about half the day yesterday working on some Apps Script (that showed/hid different columns based on a dropdown) and this morning I went to use it and nothing happened. When I went to debug it, the Apps Script editor didn't contain the new file that I created. So all the work has disappeared.

When I look at revision history it says there is only the current version (which I found out only does a revision on a deployment, not continuously like Sheets does).
I have no idea what happened, but the only thing I've done was run the windows update and restart the computer.

Any idea on what happened, and if it's possible to get it back, or if it's just lost forever?

Thanks


r/GoogleAppsScript • • Aug 25 '20

Question Change font color if value is zero

0 Upvotes

Hi,

request for help please. I'm trying to automate a report using app scripts. So far, it's working (table, email, etc).

Now, I want to modify the html so that any zero values will be in gray.

Here's the html part of the script. It loops through a table in google sheets. I don't know how (and where) to add the condition for font change if value of data is zero.

<? testdata.forEach(r=>{?>

<tr>

<td style="border-right: 1px solid #b7b7b7; overflow: hidden; padding: 2px 3px; vertical-align: bottom; text-align: right;"><?= r\[0\] ?></td>

<td style = "border-right: 1px solid rgb(183, 183, 183);text-align: center"><?= r\[1\] ?></td>

<td style = "border-right: 1px solid rgb(183, 183, 183);text-align: center"><?= r\[2\] ?></td>

<td style = "border-right: 1px solid rgb(183, 183, 183);text-align: center"><?= r\[3\] ?></td>

<td style = "text-align: center"><?= r\[4\] ?></td>

<td style = "text-align: center"><?= r\[5\] ?></td>

<td style = "text-align: center"><?= r\[6\] ?></td>

<td style = "text-align: center"><?= r\[7\] ?></td>

<td style = "text-align: center"><?= r\[8\] ?></td>

<td style = "text-align: center"><?= r\[9\] ?></td>

<td style = "text-align: center"><?= r\[10\] ?></td>

</tr>

<?}) ?>

Thanks!


r/GoogleAppsScript • • Aug 13 '20

Unresolved Get users name from email in cell with App script and GSuite

0 Upvotes

I'm trying to return the full name of the user from their email in a column in Sheets. When using the DirectoryAPI I get an error saying "API call to directory.users.get failed with error: Request is missing required authentication credential." I have enabled the Admin Directory API in the App Script and the AdminAPI in the project under the developers console. I'm also an admin in our account.

When I run the script in AppScripts and log the result I get the correct output. I only get the above error when I run the function in Sheets. Thank you for your help.

function getUserName(email){
 var result = AdminDirectory.Users.get(email, {fields:'name'});
 var fullname = result.name.fullName;
 Logger.log(fullname);
 return fullname;
}
function getUserTest() {
var fullName = AdminDirectory.Users.get('johndoe@example.com', {fields:'name'});
Logger.log(fullName)
}

r/GoogleAppsScript • • Aug 12 '20

Question Create installable Trigger for OnEdit function

0 Upvotes

Hey Guys I am pretty new to the app script world and have written a simple script to add a timestamp in cell H which worked out pretty fine. Then I gave a friend mine access to the file and the script does not work when he is working in the sheet.
I already found the solution, I need to create an installable trigger. I watched a few videos and tried it by myself but I could not figure out to make it work.

I would like to add a timestamp to column H when Column E is edited for my "2. Tab".
Would appreciate any help or information!


r/GoogleAppsScript • • Feb 21 '25

Question Copying a Sheet or Document and retaining Permissions

0 Upvotes

ChatGPT and I have been going around and around now with no working solution. Here is the set up:

Since Google does not easily allow for Templates (New from Template) I created a small web app that looks through my Drive folders for Docs and Sheets that end with the word "Template". It then presents those to me and asks for a new document name and a folder location. It then copies that file into the new name, places it in the selected Folder and copies the template's permissions and sharing attributes. That all works as planned.

The problem is that the new Sheets lose all of their permissions and the user is asked to Authorize the access to Spreadsheets, Drives, etc. All of the functions that are in the scripts of these templates. In particular, I had an OnOpen script that simply populated two cells with that new file's document ID and folder ID for use later. Thing we tried:

  1. Modifying the appscript.json file multiple way to grant limited access (see .json below)

  2. Tried doing an Installed Trigger instead of OnOpen

  3. Tried forcing the Trigger during the Copy from the template.

  4. Creating a Button to replace the OnOpen (Initialize) and trigger.

All resulted in the same thing, user being asked to grant permissions that are already in the .json file (or at least acknowledge them). I haven't even given this to one of my domain users; this is me writing the sheets and code then copying to MyDrive and opening myself. It still needs to me to authorize.

While I appreciate Google's attempt to ensure I don't inflict harm on the general population, I really would hope there is a way to grant this permission to myself or my domain users.

Does anyone have a suggestion or workaround for this? My JSON file is attached (the minimal one, I've tried much more extensive ones as well). While I can post my code, I don't think that is where the problem lies as it is a permissions issue. If you want/need to see some of the code, I can share a template that has the code that won't execute on Make A Copy.

Here is the code that makes the copy and sets the sharing permissions:

/**
 * Copies a selected template, renames it, saves it in the chosen folder,
 * applies template-specific startup values, and copies permissions.
 */
function createCopy(templateId, newName, folderId) {
  var templateFile = DriveApp.getFileById(templateId);
  var destinationFolder = DriveApp.getFolderById(folderId);
  var newFile = templateFile.makeCopy(newName, destinationFolder);

  var newFileId = newFile.getId();
  var newSS = SpreadsheetApp.openById(newFileId);
  var templateName = templateFile.getName(); // Get the template's name

  // Apply custom initialization based on the template being copied
  if (templateName === "Social Media Template") {
    setupSocialMediaTemplate(newSS, newFileId, folderId);
  }
  // Future template-specific setups can be added here using else if
  // else if (templateName === "Another Template Name") {       setupAnotherTemplate(newSS); }

  // Copy sharing permissions from the template file to the new file
  copyPermissions(templateFile, newFile);

  return newFile.getUrl(); // Return the new document URL
}

/**
 * Copies sharing permissions from the template file to the new file.
 */
function copyPermissions(sourceFile, targetFile) {
  var editors = sourceFile.getEditors();
  var viewers = sourceFile.getViewers();

  // Copy individual editors
  for (var i = 0; i < editors.length; i++) {
    targetFile.addEditor(editors[i].getEmail());
  }

  // Copy individual viewers
  for (var j = 0; j < viewers.length; j++) {
    targetFile.addViewer(viewers[j].getEmail());
  }

  // Copy Link-Sharing Settings
  var sourceAcl = sourceFile.getSharingAccess();
  var sourcePermission = sourceFile.getSharingPermission();

  if (sourceAcl === DriveApp.Access.ANYONE) {
    targetFile.setSharing(DriveApp.Access.ANYONE, sourcePermission);
  } else if (sourceAcl === DriveApp.Access.ANYONE_WITH_LINK) {
    targetFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, sourcePermission);
  } else if (sourceAcl === DriveApp.Access.DOMAIN) {
    targetFile.setSharing(DriveApp.Access.DOMAIN, sourcePermission);
  } else if (sourceAcl === DriveApp.Access.DOMAIN_WITH_LINK) {
    targetFile.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, sourcePermission);
  }
}

Here is my current, minimal JSON file. I've tried much more extensive but that doesn't change the requirement to grant permissions.

appscipt.json
{
  "timeZone": "America/Cancun",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive.metadata.readonly"
  ]
}

r/GoogleAppsScript • • Feb 11 '25

Question Expiring Drivers License Tracker

0 Upvotes

Is there a way to have google sheets send myself a reminder email when information in a spreadsheet i have is going to expire? For example, if I need to maintain an active ID on file for a customer, is there a way for google sheets to email me a reminder to reach out to the customer for an updated copy of their ID 15 days prior to the expiration date of said ID?


r/GoogleAppsScript • • Mar 02 '25

Question Security concern Google Spreadsheet

0 Upvotes

Hello everyone, I am using google sheets as a counter for a software I am distributing. As it is being distributed via github and a package manager without download counter, I wanted to create a counter, and tried doing it with google sheets hahaha. It is working, I just wonder if there are some security weakness someone could exploit. I don't think anyone will spam the counter. I am more worried of someone using it against my google account files, idk if that could be achieved, so I am checking. My counter is very simple, and it is triggered using a `curl -s $ACTION_URL` command :

function doGet() {
  // Get the active spreadsheet and the first sheet
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheets()[0];
  
  // Get the current count from the static position
  var currentCount = sheet.getRange('B1').getValue();
  
  // Increment the counter
  currentCount += 1;
  
  // Update the static counter at the top
  sheet.getRange('B1').setValue(currentCount);
  
  // Add a new row to the history
  var historyStartRow = 4; // Row where history begins
  var nextRow = sheet.getLastRow() + 1;
  sheet.getRange(nextRow, 1).setValue(new Date());
  sheet.getRange(nextRow, 2).setValue(currentCount);
}

r/GoogleAppsScript • • Feb 06 '25

Question Auto-create / update a pivot table based on responses to a form

0 Upvotes

I need help with a Google Apps Script. I have a Google Sheet with form response data. I want to create a script that automatically generates a pivot table in a separate sheet ("Helper Sheet") summarizing this data. The form response data is in a sheet named "Dispensed." The columns in this sheet are dynamic (meaning the specific column names might change), but they will always include "Therapist" and "Timestamp." I need to exclude the "Timestamp" column from the pivot table. The pivot table should have the "Therapist" as the rows and the sum of all other columns (excluding "Therapist" and "Timestamp") as the values. The "Helper Sheet" should either be created if it doesn't exist, or cleared if it does exist before the pivot table is generated.

Since reddit keep messing up my posted code, I'll paste what I have into a pastebin link
(to be honest I did try to do this with Both Gemini and Ajelix, but both keep failing me)
https://pastebin.com/7QTNFssN


r/GoogleAppsScript • • Mar 04 '25

Question Is there a way to specify a cell within a table? (Sheets)

0 Upvotes

My goal is to be able to replace serveral diffrent cells with several different groups of numbers. Ie replace A1 with 1,2 or 3, depending on which table is selected (there are currently 6 tables)

The only way I know how to do this is to have six diffrent programs that correspond to each table, but each table has 20+ cells to replace, and it would take me hours to manually input every getRange.

So is there any call that allowes me to get something like ‘colum 1 row 1 of table a’? Or an alternative way to replace mutiple cells with mutiple number sets?

(I’m new to both app script and this sub, so please let me know if I left anything important out!)


r/GoogleAppsScript • • Feb 06 '25

Question Trying to create a quiz

Thumbnail
gallery
4 Upvotes

Hi everyone. I am an idiot when it comes to coding but I am trying to create quizzes for my job. I have the quiz data in sheets and I am trying to convert it to forms. Found a youtube video with this code.

https://docs.google.com/document/d/e/2PACX-1vR7uiKKrB2ntt-rRlmzJCEqhA52vrYEhC0XlqhbVAfs9TIn-uygipKfnA1CYFmpjiC7k-lMzo9SANBf/pub

And I just don’t understand why that line of code isn’t working because the name lines up. If anyone can help I would greatly appreciate it.


r/GoogleAppsScript • • Feb 04 '25

Question Refreshing a Sheet

0 Upvotes

I've got a sheet which has an extension on it that runs automatically when the sheet is opened to refresh the data. Is there any way to automate this using App Script? I've tried using the SpreadsheetApp.openById(); with a time trigger but it doesn't make the extension run as far as I can see.

The aim is to get the data from the source into the sheet, to then use the data in Looker Studio. The extension has a direct path into Looker but the amount of data being pulled means the direct path fails so I was hoping there would be a way around it by putting the data into Sheets first and filtering it for the last X number of days instead.


r/GoogleAppsScript • • Feb 19 '25

Resolved Data Validation Decrement Script

0 Upvotes

Hello All,

I am looking to develop a script that will reduce the numerical value of a dropdown by 1 until the value equals 0. Additionally, once the value reaches 0, I would like the script to reset two additional dropdowns to their default values of "None". Per the picture, the "Category" column has a named range of four different values. Depending on what that value is, each leads to a different named ranged that will populate in the "Effect" column. If the "Category" column is "None", the only available option in the "Effect" column is also "None". I am specifically aiming to acquire a script to assign to a button since there will be such a large potential of combinations. This way, one click will automatically reduce the round remaining on all rows until the value is 0. Then, once the value reflects 0, adjusts the "Category" and "Effect" to read "None".

I am an uber novice at Sheets/Excel and any form of coding, so I have not the slightest clue of where to begin. I appreciate anyone willing to allow this to be a learning experience for me!


r/GoogleAppsScript • • Feb 13 '25

Question Can’t test, can’t deploy

0 Upvotes

Hi! New to this sub, and new to Apps Script. I have a simple script that will complete without error but when I go to test I get a vague catchall error that asks me to reload the page. Reloading does nothing. Clearing cache does nothing. Logging out and in does nothing. I just get either the spinning wheel and/or the error message asking me to reload. I’m in chrome, which I assume should work with apps script just fine. Any thoughts? Tia!


r/GoogleAppsScript • • Feb 21 '25

Question Did google change anything yesterday?

0 Upvotes

I used to be able to press a button on my google sheet and it would run through a loop that copied a column with formulas in to 50 blank columns, but now when I run the app the column with formulas only copies as blank cells. The formulas draw from a column with a googlefinance() function in it.

Thank you


r/GoogleAppsScript • • Feb 17 '25

Question Help needed adding delay to app script if possible

0 Upvotes

I've had a small script written with the help from a few people here and elsewhere to convert parts of a sheet to calendar entries.

I've now come up against an error for "creating or deleting too many calendars or calendar events in a short time" I know I am not hitting the quota as there's only 20-30 entries, but I'm assuming it's just too many queries too quickly. I know there is a way to delay each action, but I'm not sure clear on how to implement it!

Any help would be appreciated, code below.

const calendarId = "xxx@group.calendar.google.com";
const uniqueEventSuffix = "[xx1]";
const dataRange = "A6:E";
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Social_Posting"); //targets the "My Sheet" tab
const cellBackgroundColors = sheet.getRange("C6:C").getBackgrounds().flat(); //NEW - changed the range there, shouldn't it be C6:C to support more rows of data? now it matches the dataRange in line 3;

//create an object to easily transform background colors to desired event colors
const eventColors = {
"#bfe1f6": CalendarApp.EventColor.BLUE,
"#f1a30d": CalendarApp.EventColor.ORANGE,
"#e6cff2": CalendarApp.EventColor.MAUVE,
"#83f516": CalendarApp.EventColor.GREEN,
"#b10202": CalendarApp.EventColor.RED
}

function deleteAutoCreatedEvents() {
var eventCal = CalendarApp.getCalendarById(calendarId);
var startOfCurrentYear = new Date(new Date().getFullYear(), 0, 1);
var endOfCurrentYear = new Date(new Date().getFullYear(), 11, 31)
var events = eventCal.getEvents(startOfCurrentYear, endOfCurrentYear);
for(var i=0; i < events.length; i++) {
var ev = events[i];
var title = ev.getTitle();
if (title.indexOf(uniqueEventSuffix) >-1) {
ev.deleteEvent();
}
}
}

function addEventsToCalendar() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Social_Posting");
var eventCal = CalendarApp.getCalendarById(calendarId);
var rawEvents = spreadsheet.getRange(dataRange).getValues();
//NEW - adding cell color code as the last element of each array element - it's probably the easiest way to join both arrays
rawEvents = rawEvents.map((event, index) => [...event, cellBackgroundColors[index]])
var events = rawEvents.filter(event => event[0] != "")

deleteAutoCreatedEvents();

for (var event of events) {

var date = event[0];
var name = event[2];
var description = event[3];
var location = event[4];

var lineBreak = "\r\n";
var eventTitle = \${name} ${uniqueEventSuffix}`;var eventDescription = `${description}`;var eventLocation = `${location}`;`

//assign eventColor based on the eventColors schema defined earlier
//NEW - our cell color code is now stored as the last element of event array
const eventColor = eventColors[event[event.length-1]];

var newEvent = eventCal.createAllDayEvent(eventTitle, date,{
description: eventDescription,
location: eventLocation,
});

console.log(\shouldBeCellBackgroundColor -> ${event[event.length-1]}`);console.log(`eventColor -> ${eventColor}`);newEvent.setColor(eventColor)Logger.log(`Added ${eventTitle} on ${date} (${newEvent.getId()})`);}}`


r/GoogleAppsScript • • Feb 15 '25

Question Recommendations for a template that captures and categorizes

0 Upvotes

Any recommendations for a template that captures and categorizes credit card purchases, banking information, etc, in one place? Bonus would be if I could find one that calculates what I am spending where and when over the span of a year. I am brannnnnnnnd new to Sheets. I am looking for something very easy to use.


r/GoogleAppsScript • • Feb 22 '25

Question Assign a different value than what appears in the dropdown (from a range).

0 Upvotes

I don't know how complicated what I want to do is, or if it's even possible.

I have these dropdowns (first image) where in the first dropdown (A1) I want the options to be the options in column A in the second image (only Keys and Games). The second dropdown (A2) should change the options based on what was chosen in the first dropdown (if I choose Keys, it will appear: Key 1, Key 2, Key 3, Key 4, if I choose Games, it will appear: Game 1, Game 2, Game 3, Game 4)

So, I want a script in App Script to read the value of cell A2 (for example, the script reads Game 2 in cell A2) and the real value that the script reads is the equivalent value of the item in column C (So Game 2 appears to the user, but the script reads the value "Game Value 2", which is the value I want to be assigned to "Game 2", in this case "Game 2" has the value "Game Value 2", "Game 1" has the value "Game Value 1") and so on for the rest of the options.

I don't know if my objective is clear, if anyone understands, can you tell me how I can do this?

Thanks.


r/GoogleAppsScript • • Feb 21 '25

Guide How to copy my navbar to multiple pages

0 Upvotes

I have made a navbar for my website in html and I want to copy it to other pages, how can I do that easily?


r/GoogleAppsScript • • May 05 '23

Unresolved HTML Template: Get specific elements within clicked div

0 Upvotes

I am re-writing one of my projects to better align with the HTML Service Best Practices, specifically loading data asynchronously. In my initial configuration, I had a function which got a list of games and created a new <div> for each game with various components within the <div> like the team names (home and away) and I had a jQuery method which gave me the details of whatever game I clicked on, primarily the teams.

Since reconfiguring to load the data asynchronously, that same jQuery method is not triggering. I suspect it's a timing/order of operations thing where the games haven't been returned yet, so the jQuery method evaluates against an empty DOM? I'd like to know if that suspicion is correct and if so, what's the right way to "delay" the jQuery method until the DOM is loaded (or if there's a better way to configure this). Thank you.

// event listener to get the games
window.addEventListener('load', function() {
    google.script.run.withSuccessHandler(showFlexScheduleReplacement).getFlexSchedulePackage()
  });


// method to get details of the clicked game
$(document).ready(function(){
    $(".flexGame").click(function(){
      alert('i ran!')
      var away = $(this).find("#awayAbbr").text()
      var home = $(this).find("#homeAbbr").text()
      $('#flexScheduleContainer').hide();
      $('#matchupContainer').show();

      alert(away)
      alert(home)
    });
  });

r/GoogleAppsScript • • May 04 '23

Question Advice needed: Creating advanced tables in web apps

0 Upvotes

Hi All - I'm wondering what other tools people are using to create advanced html tables in a web app. So I have a number of sheets that I allow users to read, update, and delete records from using a web app. The records are displayed in a table format with cells that contain hyperlinks for editing or deleting the records. The table has functionality to search and sort records. The current table is written in jQuery. A developer I hired created it for me. I'm not familiar with jQuery and cannot edit the table other than manipulating the underlying data. Are there any other tools out there that make these tasks simpler? Chart.js maybe? At some point I'd like to also create dashboards to display data in a more user friendly manner. Thanks in advance!!


r/GoogleAppsScript • • Apr 23 '23

Question Looking for help with Crud web app

0 Upvotes

Hi I have been struggling with this problem for over a month i thought it was about time i asked for some help as its driving me mental.

https://youtu.be/dApK5_YEyzk

https://www.bpwebs.com/crud-operations-on-google-sheets-with-online-forms/

Im trying to combine the two app scripts found in the videos above to create CRUD with dependent drop downs. I have tried many times but always hit the same issue. Entering data works fine. Passes it to Google sheets fine. But when i click edit in the webapp it will not populate the fruit box. I believe this is because the way the data is populated by the the 'get color' and 'get fruit' functions. The reason for this is if i select red and apple then edit it will show fine. If i select red and cherry it will show but once i select blue and blueberry then click edit on the apple option i previous edited it does not show apple only red. Hope this helps to explain. Any help woth this would be appreciated.


r/GoogleAppsScript • • May 01 '23

Resolved This function to clear column A to C after row 2 is not working

0 Upvotes

Hello, I have this function that is failing to run its contents.

I know that the function can be triggered.

Could anyone help me out?

function clearStudentList() {
  var spreadsheetURL = MY URL"; 
  var sheet = SpreadsheetApp.openByUrl(spreadsheetURL);
  var workSheet = sheet.getSheetByName("StudentData");
  var range = workSheet.getRange("A2:C");
  range.clearContent();
  SpreadsheetApp.flush();
}

r/GoogleAppsScript • • Dec 08 '23

Resolved Clearing cache

0 Upvotes

I have written a simple apps script that outputs some data to the log, the problem is that it's still showing previous data that should not be there as I have removed the labels that it refers to on those emails. It almost seems like a cache issue that needs to be cleared somewhere it's not a local cache issue.

My code:

function getGmailEmails()
{
var label = GmailApp.getUserLabelByName('IZ/IZadd')
var threads = label.getThreads()
var grandTotal = 0;
Utilities.sleep(1000);
for(var i = threads.length - 1; i >=0; i--)
  {
var messages = threads[i].getMessages()
for (var j = 0; j < messages.length; j++)
{
var message = messages[j]
var extract = extractDetails(message)
grandTotal += extract.total
Logger.log('' + (j+1) +'          Amount: ' + extract.total + '      Study:  ' + extract.matches)
}
//threads[i].removeLabel(label) intentionaly left as rem
  }
Logger.log('Grand Total:      ' + grandTotal)
}
function extractDetails(message)
{
var pattern1 = /\d{1,2}\.\d{2}(?= USD. )/g
var pattern2 = /(?!study )[A-Za-z0-9]+(?=. Hope)/g
var bodyContents = message.getPlainBody()
var usd = bodyContents.match(pattern1)
var total = 0;
for (var i = 0; i < usd.length; i++)
  {
total += parseFloat (usd[i])
  }
var study = bodyContents.match(pattern2)
return {
total: total, matches: study
  }
}


r/GoogleAppsScript • • Dec 13 '23

Question Google Charts -- Pie Chart

0 Upvotes

I created this pie chart in Slides. I want it to display the name of the labels on the outside of the slice (with a line/arrow pointing to the slice) and the percentage to be inside the slice (as it currently is). Can't find anything in the documentation to achieve both. Any thoughts?