Files
rsmsn_blog/public/posts/google_scripts_sheets_to_slides.html
2024-07-03 18:21:05 -04:00

1140 lines
123 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" dir="auto">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="index, follow">
<title>Google Sheets to Slides with Scripts: an Automation | Norm-working Packets 💾</title>
<meta name="keywords" content="google, scripts, sheets">
<meta name="description" content="Learn about running a quick automation that turns rows in your Google Sheets and plugs it into a Google Slide template to easily share more attractive content.">
<meta name="author" content="Me">
<link rel="canonical" href="../posts/google_scripts_sheets_to_slides.html">
<script defer data-domain="selfhosted.rsmsn.co" src="https://analytics.rsmsn.co/js/script.js"></script>
<link crossorigin="anonymous" href="../assets/css/stylesheet.b609c58d5c11bb90b1a54e04005d74ad1ddf22165eb79f5533967e57df9c3b50.css" integrity="sha256-tgnFjVwRu5CxpU4EAF10rR3fIhZet59VM5Z&#43;V9&#43;cO1A=" rel="preload stylesheet" as="style">
<link rel="icon" href="../favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="../rsmsncircles.ico">
<link rel="apple-touch-icon" href="../apple-touch-icon.png">
<link rel="mask-icon" href="../safari-pinned-tab.svg">
<meta name="theme-color" content="#2e2e33">
<meta name="msapplication-TileColor" content="#2e2e33">
<link rel="alternate" hreflang="en" href="../posts/google_scripts_sheets_to_slides.html">
<noscript>
<style>
#theme-toggle,
.top-link {
display: none;
}
</style>
</noscript>
<meta property="og:title" content="Google Sheets to Slides with Scripts: an Automation" />
<meta property="og:description" content="Learn about running a quick automation that turns rows in your Google Sheets and plugs it into a Google Slide template to easily share more attractive content." />
<meta property="og:type" content="article" />
<meta property="og:url" content="/posts/google_scripts_sheets_to_slides.html" />
<meta property="og:image" content="/%3Cimage%20path/url%3E" /><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2024-02-25T10:14:30-05:00" />
<meta property="article:modified_time" content="2024-02-25T10:14:30-05:00" /><meta property="og:site_name" content="Self-hosted Norm" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="/%3Cimage%20path/url%3E" />
<meta name="twitter:title" content="Google Sheets to Slides with Scripts: an Automation"/>
<meta name="twitter:description" content="Learn about running a quick automation that turns rows in your Google Sheets and plugs it into a Google Slide template to easily share more attractive content."/>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1 ,
"name": "Posts",
"item": "/posts.html"
}
{
"@type": "ListItem",
"position": 1 ,
"name": "Google Sheets to Slides with Scripts: an Automation",
"item": "/posts/google_scripts_sheets_to_slides.html"
}
]
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Google Sheets to Slides with Scripts: an Automation",
"name": "Google Sheets to Slides with Scripts: an Automation",
"description": "Learn about running a quick automation that turns rows in your Google Sheets and plugs it into a Google Slide template to easily share more attractive content.",
"keywords": [
"google", "scripts", "sheets"
],
"articleBody": "Overview Recently, my wife needed help in sharing weekly content with a group of people. The original way this group was sharing content was a PDF export of a Google Doc. From a User Experience perspective, it wasnt great. Someone would received this long PDF, they would have to scroll to find the date or topic of the next additional_notes, and overall didnt look great.\nWhile she had developed the Google Sheets and Google Slide system to make everything a bit more legible and navigable, there was still an element of copy and paste from the Sheet to the Slide. She had asked if I knew of any ways to make this process easier. This was a perfect mini-project for Google Apps Scripts!\nIn case you havent heard of Google Apps Scripts, it is a built in Google IDE that uses Javascript to make various Google products available via automation and scripting. While Google saves the files as .gs files, its just javascript, dont worry! You can learn more about it here and here.\nBelow, Ill share the pieces of the script to explain what is going on. If you know what youre doing and just want the script, feel free to head to the bottom of the page to see the full script.\nGoal The goal here was pretty straight forward. I wanted to add a button on the Google Sheet that allows the user to create a Slides presentation from a subset of data within the sheet. The data will be date based, as this is what most end users need, and the user will be able to pick from the currently available dates \u0026 populated data.\nSetup Getting setup, you need both a Sheet with a few headings and an empty Slide presentation with a few empty text boxes. The empty text boxes will be key to helping us connect the data in the sheet to the correct placement in the slide. Here are two screenshots of what this looks like for my example:\nSheets Setup Ignoring any design from my screenshots - all credit goes to my much more creative wife - the setup for the sheet is fairly simple. You need various headings in Row A of the sheet which we will be using to reference data. In this tutorial, our headings are Date, Topic 1, Topic 2, Topic 3, Additional Notes. Whether you start on Row 1 or after that doesnt matter too much.\nFor the date column, well be formatting our date like this: “February 26, 2024”. Youll see why in a little bit.\nOn top of the actual data in the Sheet, the Apps Script is going to live in this document and just push data to the Slide. To access your App Scripts, click Extensions \u003e Apps Scripts. A new tab will open with a blank IDE style interface and an empty myFunction.\nSlides Setup Dont worry too much about the design for Slides, you can change that later. But the important step is creating the empty text boxes. After you create your text boxes (4 will be used in this tutorial), right click one of them and select “Format Options”. A panel on the left hand-side should slide out. Click the “Alt Text” drop down, and then “Advanced Options”. That little text box is the title for your text box; it is not used in the visual representation of the box, we will just be using it as a reference point.\nFor ease of this tutorial, make the Title of the text box the same as the Header row from when we set up the Sheet, above. Once youve added title to each of the text boxes, lets head into the code.\nonOpen Function The first function you need for creating a UI change in the Google Sheet is an onOpen function that will setup the UI when the Sheet is open.\n1 2 3 4 5 6 function onOpen(e) { SpreadsheetApp.getUi() .createMenu('Create Presentation') .addItem('Create Presentation', 'askDate' ) .addToUi(); } In this function (which well later trigger in the script settings), when someone opens up the Sheet, it will create the UI button in the top level menu. Heres whats happening:\nSpreadsheetApp.getUi() \u003e Instantiate class and get available methods for getUi(). createMenu() \u003e Creates a menu item called “Create Presentation”. addItem() \u003e Adds an item to that menu that when pressed, calls the askDate function. addtoUi() \u003e Add it! Now people can see and click on it. askDate Function This is the main function and a bit long, so Ill split it up into a few sections.\nSection 1 1 2 3 4 5 6 7 var ui = SpreadsheetApp.getUi(); var sheet = SpreadsheetApp.getActiveSheet(); var lastRow = sheet.getLastRow(); var dates = sheet.getRange(2,2,lastRow,1).getDisplayValues(); // get today's epoch time for easier calculations const epochDate = new Date().getTime() This first section were just getting the sheet ready for analysis. With the dates variable, were just looking at the second column. The reason were using the getDisplayValues() method is because Google will automatically convert the dates to include time zone, time, etc. We want to keep the date in the same format for a better user experience.\nFor that last line, were getting the current date \u0026 time in epoch time so we can run a comparison further down the script. For this use case, we dont need to include any dates in the past.\nSection 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 menuOptions = [] const re = new RegExp(\"^[A-Za-z]{3,15}\\\\s\\\\d{1,2},\\\\s\\\\d{2,4}\") for (let i = 0; i \u003c dates.length; i++ ) { var date = dates[i][0]; var epochSheetDate = new Date(date).getTime(); if (date != \"\") { var dateMatch = re.test(date) if (dateMatch == true) { if (epochDate \u003c epochSheetDate) { menuOptions.push(date) } } } } In this section were creating an empty array and instantiating a RegExp to ensure we have an actual date in the cell. See Regex101 to learn more about Regex and test different regex syntax.\nSomething that threw me off when first writing this regex function was the way the Google IDE manages escape character and slashes. If you take the second line above and input it into Regex101 youll see the \\s or \\d become dark gray, basically skipping over that token. However, for Google, youll need an additional backslash to escape and make the token become used by the function.\nHeres the “correct” RegExp string for Regex101.com: ^[A-Za-z]{3,15}\\s\\d{1,2},\\s\\d{2,4}\nNext, we dive into a for loop, looping through the dates column of values (which we just called earlier). After attributing each value to the var date variable, we also convert that same value into epoch time (by creating a new Date().getTime()) so that we can compare it with todays date.\nAfter the variables are setup we need to check that the date isnt empty; we dont need any rows where a date hasnt been assigned to it yet. If we have a non-empty date value, lets compare it using the regex string. All were doing here is asking “Is this date in the format Im expecting it?” If true, lets keep the value and continue using it. If not, just ignore it.\nSo weve now found a value thats in the date format we expect, lets now take that same value in epoch time (referenced by the epochSheetDate variable) and compare it to todays epoch time date. If todays date is less than the value in the sheet, that means the date in the sheet is in the future.\nSo now we have a date in the correct format and that is at some future date from today. Fantastic! Once weve gone through those checks, were ready to add the date to the array we created at the top of this section. Push on!\nSection 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 if (menuOptions.length \u003e 0) { let stringList = menuOptions.toString(); var formattedDates = stringList.replaceAll(\"2024,\", \"2024 \\n \"); var response = ui.prompt('Which date would you like to create a presentation for? Please copy and paste the date exactly as you see it in the options below. Options: \\n \\n'+formattedDates); if (response.getSelectedButton() == ui.Button.OK) { var dateChosen = response.getResponseText(); if (dateChosen != \"\") { ui.alert(\"Woohoo! Let's make a presentation!\") for(var y = 0; y\u003cdates.length;y++){ if (dates[y][0] == dateChosen) { // Logger.log(\"Row:\"+(y+2)); var presRow = y+2 var presData = sheet.getRange(presRow,3,1,4).getValues(); for (presCopy of presData) { var topic1 = presCopy[0]; var topic2 = presCopy[1]; var topic3 = presCopy[2]; var additional_notes = presCopy[3]; } createPresentation(dateChosen, topic1, topic2, topic3, additional_notes) } } } else { ui.alert(\"Ouch. Looks like you entered something incorrectly (i.e. you entered nothing). Try again.\") } } } else { ui.alert(\"No Dates Available. Check Spreadsheet\") } This next section might feel long, but its really easy to follow, dont worry. Its a lot of data organization to ensure were giving the users a smooth experience \u0026 to make sure when the data hits the Slide, its in the right spot.\nFirst things first - lets only run this if we actually have items in the menuOptions array! No need to give the user an affirmative message when theres no data to process. If there are no dates available, we call the else of this if, which is the 3rd to last line in this section.\nA ui.alert is just a modal that offers no interaction to the user.\nThe next few lines are for processing that array of dates we grabbed from the sheet to making them presentable to the user. Without the stringList and formattedDates variables, Googles modal just shows a wall of text of dates which makes it difficult to parse for the user. By using replaceAll() we remove the comma and insert a new line after every portion of the string that contains 2024 and a comma.\nSo now, instead of the modal showing:\nFebruary 2, 2024,February 3, 2024,February 4,2024... etc We now see the much easier to read:\nFebruary 2, 2024 February 3, 2024 February 4, 2024 After thats formatted nicely, we can now have the prompt show for the user which asks them what date they would like to process into a Slide presentation. Since we havent visited any ui options since the top of this tutorial, this is the modal that will show up after a user clicks “Create Presentation” in the top level menu in Google Sheets.\nOk, so now moving onto line 5, we need to get the text for what the user enters into the modal box. If they dont enter anything, we should let them know that nothing will be done. That message comes from the second to last else statement in this section. Instead, if they enter some data lets parse it!\nIf you want to test yourself by adding in some new code try this exercise:\nHow can we ensure that the user entered a date in the format we expect? Tip: It is something reusable from another portion of the script.\nFor lines 9 and 10, were now looping back through the same set of rows that we did in section 2. The reason were re-entering this for loop is because weve already exited the loop. So we have to get the values again. Once we have them, lets match the date that the user entered to the correct row. Were able to do that by grabbing the index and adding 2 to it.\nI havent fully looked into why we need to add 2 to get the correct row number. As we loop through the dates, the array length (dates.length) is all the available rows in the sheet. So you would think that y is the row that the value is on; but its not.\nMy only guess so far has to do with the frozen row at the top that I have in my Sheet. So the frozen row is not used, and row 2 is now index 0. Which means index 41 is technically row 43, and why we have to add 2 to the value to get the visually correct row number. We need this number to be correct so that we can get the rest of the values int he sheet.\nNow that we have the correct row number, were going to shift from getting values from each row and getting them from each column. By calling var presData = sheet.getRange(presRow,3,1,4).getValues(); we are grabbing an array. getRange is looking for the following values, in the following order:\nRow number (which we got from the y+2) Column Number (which is Column C in this case) Number of Rows (we only need this row) Number of Columns (we know how many more columns we need). Next up, were jumping into another for loop, now for all the data we just pulled from the column. This part is just parsing each columns data into its own variable for easier management when we create the presentation. Weve also grabbed the additional notes column, but were not using it right now. This columns data may be valuable by adding it to the speaker notes of the Slide Presentation. Check out these two resources:\nWorking with Speaker Notes Notes Properties API Once thats done, call the next function: createPresentation()! Were almost done.\ncreatePresentation Function 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function createPresentation(dateChosen, topic1, topic2, topic3, additionalNotes) { const slides = SlidesApp.openById('ENTER_ID_OF_SLIDE_PRESENTATION'); let slide = slides.getSlides()[0]; let elements = slide.getPageElements(); for (let i = 0; i \u003c elements.length; i++) { var titles = elements[i].getTitle() if (titles == \"Date\") { var dateText = elements[i].asShape().getText(); dateText.clear(); dateText.setText(dateChosen); } if (titles == \"Topic 1\") { const topic1Text = elements[i].asShape().getText(); topic1Text.clear(); topic1Text.setText(topic1); } if (titles == \"Topic 2\") { const topic2Text = elements[i].asShape().getText(); topic2Text.clear(); topic2Text.setText(topic2); } if (titles == \"Topic 3\") { const topic3Text = elements[i].asShape().getText(); topic3Text.clear(); topic3Text.setText(topic3); } } } This function may be the shortest to explain. All we are doing is taking those variables from the previous function (the variables that contain each topics text value) and doing the following:\nOpening the Presentation (line 2) Getting the first slide (line 3) Grabbing all the page elements (line 4) Looping through the page elements \u0026 grabbing all the titles that we set during setup (line 5 \u0026 6) Then we compare the title of the Slide text box to the expected string (Topic 1-3), and if we get a match, retrieve the text of the box as a variable, clear the text, and input our new text with the variables we created in the previous function. And just like that, you should have all your boxes filled in with the data you input to the Google Sheet!\nBonus exercises:\nInstead of overwriting this presentation each time, how can you add a new slide with the same text boxes? How would you find that slide since were right now grabbing the first slide? How can you change the name of this Slide Presentation to the date from the Sheet? Could you automatically export this Slide as a PDF and save it to a users Drive? Full Script: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 function onOpen(e) { SpreadsheetApp.getUi() .createMenu('Create Presentation') .addItem('Create Presentation', 'askDate' ) .addToUi(); } function askDate() { var ui = SpreadsheetApp.getUi(); var sheet = SpreadsheetApp.getActiveSheet(); var lastRow = sheet.getLastRow(); var dates = sheet.getRange(2,2,lastRow,1).getDisplayValues(); // get today's epoch time for easier calculations const epochDate = new Date().getTime() menuOptions = [] const re = new RegExp(\"^[A-Za-z]{3,15}\\\\s\\\\d{1,2},\\\\s\\\\d{2,4}\") for (let i = 0; i \u003c dates.length; i++ ) { var date = dates[i][0]; var epochSheetDate = new Date(date).getTime(); if (date != \"\") { var dateMatch = re.test(date) if (dateMatch == true) { if (epochDate \u003c epochSheetDate) { menuOptions.push(date) } } } } if (menuOptions.length \u003e 0) { let stringList = menuOptions.toString(); var stringlist = stringList.replaceAll(\"2024,\", \"2024 \\n \"); var response = ui.prompt('Which date would you like to create a presentation for? Please copy and paste the date exactly as you see it in the options below. Options: \\n \\n'+stringlist); if (response.getSelectedButton() == ui.Button.OK) { var dateChosen = response.getResponseText(); if (dateChosen != \"\") { ui.alert(\"Woohoo! Let's make a presentation!\") for(var y = 0; y\u003cdates.length;y++){ if (dates[y][0] == dateChosen) { // Logger.log(\"Row:\"+(y+2)); var presRow = y+2 var presData = sheet.getRange(presRow,3,1,4).getValues(); for (presCopy of presData) { var topic1 = presCopy[0]; var topic2 = presCopy[1]; var topic3 = presCopy[2]; var additional_notes = presCopy[3]; } createPresentation(dateChosen, topic1, topic2, topic3, additionalNotes) } } } else { ui.alert(\"Ouch. Looks like you entered something incorrectly (i.e. you entered nothing). Try again.\") } } } else { ui.alert(\"No Dates Available. Check Spreadsheet\") } } function createPresentation(dateChosen, topic1, topic2, topic3, additionalNotes) { const slides = SlidesApp.openById('ENTER_ID_OF_SLIDE_PRESENTATION'); let slide = slides.getSlides()[0]; let elements = slide.getPageElements(); for (let i = 0; i \u003c elements.length; i++) { var titles = elements[i].getTitle() if (titles == \"Date\") { var dateText = elements[i].asShape().getText(); dateText.clear(); dateText.setText(dateChosen); } if (titles == \"topic1\") { const topic1Text = elements[i].asShape().getText(); topic1Text.clear(); topic1Text.setText(topic1); } if (titles == \"topic2\") { const topic2Text = elements[i].asShape().getText(); topic2Text.clear(); topic2Text.setText(topic2); } if (titles == \"topic3\") { const topic3Text = elements[i].asShape().getText(); topic3Text.clear(); topic3Text.setText(topic3); } } } ",
"wordCount" : "2963",
"inLanguage": "en",
"image":"/%3Cimage%20path/url%3E","datePublished": "2024-02-25T10:14:30-05:00",
"dateModified": "2024-02-25T10:14:30-05:00",
"author":{
"@type": "Person",
"name": "Me"
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "/posts/google_scripts_sheets_to_slides.html"
},
"publisher": {
"@type": "Organization",
"name": "Norm-working Packets 💾",
"logo": {
"@type": "ImageObject",
"url": "/favicon.ico"
}
}
}
</script>
</head>
<body class=" dark" id="top">
<script>
if (localStorage.getItem("pref-theme") === "light") {
document.body.classList.remove('dark')
}
</script>
<header class="header">
<nav class="nav">
<div class="logo">
<a href="../" accesskey="h" title="Norm-working Packets 💾 (Alt + H)">Norm-working Packets 💾</a>
<div class="logo-switches">
<button id="theme-toggle" accesskey="t" title="(Alt + T)">
<svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</button>
<ul class="lang-switch"><li>|</li>
</ul>
</div>
</div>
<ul id="menu">
<li>
<a href="../posts.html" title="Posts">
<span>Posts</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="main">
<article class="post-single">
<header class="post-header">
<div class="breadcrumbs"><a href="../">Home</a>&nbsp;»&nbsp;<a href="../posts.html">Posts</a></div>
<h1 class="post-title entry-hint-parent">
Google Sheets to Slides with Scripts: an Automation
</h1>
<div class="post-description">
Learn about running a quick automation that turns rows in your Google Sheets and plugs it into a Google Slide template to easily share more attractive content.
</div>
<div class="post-meta"><span title='2024-02-25 10:14:30 -0500 EST'>February 25, 2024</span>&nbsp;·&nbsp;14 min&nbsp;·&nbsp;2963 words&nbsp;·&nbsp;Me
</div>
</header> <div class="toc">
<details >
<summary accesskey="c" title="(Alt + C)">
<span class="details">Table of Contents</span>
</summary>
<div class="inner"><nav id="TableOfContents">
<ul>
<li><a href="#sheets-setup">Sheets Setup</a></li>
<li><a href="#slides-setup">Slides Setup</a></li>
<li><a href="#onopen-function">onOpen Function</a></li>
<li><a href="#askdate-function">askDate Function</a>
<ul>
<li><a href="#section-1">Section 1</a></li>
<li><a href="#section-2">Section 2</a></li>
<li><a href="#section-3">Section 3</a></li>
</ul>
</li>
<li><a href="#createpresentation-function">createPresentation Function</a></li>
</ul>
</nav>
</div>
</details>
</div>
<div class="post-content"><h1 id="overview">Overview<a hidden class="anchor" aria-hidden="true" href="#overview">#</a></h1>
<p>Recently, my wife needed help in sharing weekly content with a group of people. The original way this group was sharing
content was a PDF export of a Google Doc. From a User Experience perspective, it wasn&rsquo;t great. Someone would received this
long PDF, they would have to scroll to find the date or topic of the next additional_notes, and overall didn&rsquo;t look great.</p>
<p>While she had developed the Google Sheets and Google Slide system to make everything a bit more legible and navigable, there
was still an element of copy and paste from the Sheet to the Slide. She had asked if I knew of any ways to make this process
easier. This was a perfect mini-project for Google Apps Scripts!</p>
<style type="text/css">
.box-shortcode {
padding: 1.6em;
padding-top: 1.4em;
line-height: 1.4em;
margin-top: 1em;
margin-bottom: 2em;
border-radius: 4px;
color: #444;
background: #f3ebe850;
}
.box-title {
margin: -18px -18px 12px;
padding: 4px 18px;
border-radius: 4px 4px 0 0;
font-weight: 700;
color: #fff;
background: #6ab0de;
}
.box-shortcode.warning .box-title {
background: #ff6b6b;
}
.box-shortcode.warning {
background: #ff6b6b4f;
}
.box-shortcode.info .box-title {
background: #0089e488;
}
.box-shortcode.info {
background: #0089e41c;
box-shadow: 3px 3px 5px #0089e410;
}
.box-shortcode.important .box-title {
background: #f7ec2c;
}
.box-shortcode.important {
background: #f7ec2c7d;
}
.box-shortcode.tip .box-title {
background: #a3ffa34d;
}
.box-shortcode.tip {
background: #a3ffa34d;
box-shadow: 3px 3px 5px #0089e410;
}
.icon-box {
display: inline-flex;
align-self: center;
margin-right: 8px;
}
.icon-box img,
.icon-box svg {
height: 1em;
width: 1em;
fill: currentColor;
}
.icon-box img,
.icon-box.baseline svg {
top: 0.125em;
position: relative;
}
.box-shortcode p {
margin-bottom: 0.6em;
}
.box-shortcode p:first-of-type {
display: inline;
}
.box-shortcode p:nth-of-type(2) {
margin-top: 0.6em;
}
.box-shortcode p:last-child {
margin-bottom: 0;
}
</style>
<svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg">
<symbol id="tip-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/>
</symbol>
<symbol id="important-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>
</symbol>
<symbol id="warning-box" viewBox="0 0 576 512" preserveAspectRatio="xMidYMid meet">
<path
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>
</symbol>
<symbol id="info-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/>
</symbol>
</svg><div class="box box-shortcode info" >
<span class="icon-box baseline">
<svg><use href="#info-box"></use></svg>
</span>
<p>In case you haven&rsquo;t heard of Google Apps Scripts, it is a built in Google IDE that uses Javascript to make various
Google products available via automation and scripting. While Google saves the files as <code>.gs</code> files, it&rsquo;s just javascript,
don&rsquo;t worry! You can learn more about it <a href="https://www.google.com/script/start/">here</a> and <a href="https://developers.google.com/apps-script/overview">here</a>.</p>
</div>
<p>Below, I&rsquo;ll share the pieces of the script to explain what is going on. If you know what you&rsquo;re doing and just want the
script, feel free to head to the bottom of the page to see the <a href="#full-script">full script</a>.</p>
<h1 id="goal">Goal<a hidden class="anchor" aria-hidden="true" href="#goal">#</a></h1>
<p>The goal here was pretty straight forward. I wanted to add a button on the Google Sheet that allows the user to create a
Slides presentation from a subset of data within the sheet. The data will be date based, as this is what most end users need,
and the user will be able to pick from the currently available dates &amp; populated data.</p>
<h1 id="setup">Setup<a hidden class="anchor" aria-hidden="true" href="#setup">#</a></h1>
<p>Getting setup, you need both a Sheet with a few headings and an empty Slide presentation with a few empty text boxes. The
empty text boxes will be key to helping us connect the data in the sheet to the correct placement in the slide. Here are two
screenshots of what this looks like for my example:</p>
<p><img loading="lazy" src="../posts/img/google_sheets_for_scripts_example.png" alt="Google Sheets Example" />
</p>
<p><img loading="lazy" src="../posts/img/google_slides_for_scripts_example.png" alt="Google Slides Example" />
<img src="./img/google_slides_for_scripts_example.png" alt="Example image"></p>
<h2 id="sheets-setup">Sheets Setup<a hidden class="anchor" aria-hidden="true" href="#sheets-setup">#</a></h2>
<p>Ignoring any design from my screenshots - all credit goes to my much more creative wife - the setup for the sheet is fairly
simple. You need various headings in Row A of the sheet which we will be using to reference data. In this tutorial, our
headings are <code>Date, Topic 1, Topic 2, Topic 3, Additional Notes</code>. Whether you start on Row 1 or after that doesn&rsquo;t matter too
much.</p>
<p>For the date column, we&rsquo;ll be formatting our date like this: &ldquo;February 26, 2024&rdquo;. You&rsquo;ll see why in a little bit.</p>
<p>On top of the actual data in the Sheet, the Apps Script is going to live in this document and just push data to the Slide. To
access your App Scripts, click Extensions &gt; Apps Scripts. A new tab will open with a blank IDE style interface and an empty
<code>myFunction</code>.</p>
<h2 id="slides-setup">Slides Setup<a hidden class="anchor" aria-hidden="true" href="#slides-setup">#</a></h2>
<p>Don&rsquo;t worry too much about the design for Slides, you can change that later. But the important step is creating the empty
text boxes. After you create your text boxes (4 will be used in this tutorial), right click one of them and select &ldquo;Format
Options&rdquo;. A panel on the left hand-side should slide out. Click the &ldquo;Alt Text&rdquo; drop down, and then &ldquo;Advanced Options&rdquo;. That
little text box is the title for your text box; it is not used in the visual representation of the box, we will just be using
it as a reference point.</p>
<p>For ease of this tutorial, make the Title of the text box the same as the Header row from when we set up the Sheet, above.
Once you&rsquo;ve added title to each of the text boxes, let&rsquo;s head into the code.</p>
<h2 id="onopen-function">onOpen Function<a hidden class="anchor" aria-hidden="true" href="#onopen-function">#</a></h2>
<p>The first function you need for creating a UI change in the Google Sheet is an <code>onOpen</code> function that will setup the UI when
the Sheet is open.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">onOpen</span>(<span style="color:#a6e22e">e</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getUi</span>()
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">createMenu</span>(<span style="color:#e6db74">&#39;Create Presentation&#39;</span>)
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">addItem</span>(<span style="color:#e6db74">&#39;Create Presentation&#39;</span>, <span style="color:#e6db74">&#39;askDate&#39;</span> )
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">addToUi</span>();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>In this function (which we&rsquo;ll later trigger in the script settings), when someone opens up the Sheet, it will create the UI
button in the top level menu. Here&rsquo;s what&rsquo;s happening:</p>
<ul>
<li><code>SpreadsheetApp.getUi()</code> &ndash;&gt; Instantiate class and get available methods for <code>getUi()</code>.</li>
<li><code>createMenu()</code> &ndash;&gt; Creates a menu item called &ldquo;Create Presentation&rdquo;.</li>
<li><code>addItem()</code> &ndash;&gt; Adds an item to that menu that when pressed, calls the <code>askDate</code> function.</li>
<li><code>addtoUi()</code> &ndash;&gt; Add it! Now people can see and click on it.</li>
</ul>
<p><img loading="lazy" src="../posts/img/google_sheets_menu_example_2.png" alt="Google Sheets Menu Example" />
</p>
<h2 id="askdate-function">askDate Function<a hidden class="anchor" aria-hidden="true" href="#askdate-function">#</a></h2>
<p>This is the main function and a bit long, so I&rsquo;ll split it up into a few sections.</p>
<h3 id="section-1">Section 1<a hidden class="anchor" aria-hidden="true" href="#section-1">#</a></h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">ui</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getUi</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">sheet</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getActiveSheet</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">lastRow</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getLastRow</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dates</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getRange</span>(<span style="color:#ae81ff">2</span>,<span style="color:#ae81ff">2</span>,<span style="color:#a6e22e">lastRow</span>,<span style="color:#ae81ff">1</span>).<span style="color:#a6e22e">getDisplayValues</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// get today&#39;s epoch time for easier calculations
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">epochDate</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Date().<span style="color:#a6e22e">getTime</span>()
</span></span></code></pre></td></tr></table>
</div>
</div><p>This first section we&rsquo;re just getting the sheet ready for analysis. With the <code>dates</code> variable, we&rsquo;re just looking at the
second column. The reason we&rsquo;re using the <code>getDisplayValues()</code> method is because Google will automatically convert the dates
to include time zone, time, etc. We want to keep the date in the same format for a better user experience.</p>
<p>For that last line, we&rsquo;re getting the current date &amp; time in epoch time so we can run a comparison further down the script.
For this use case, we don&rsquo;t need to include any dates in the past.</p>
<h3 id="section-2">Section 2<a hidden class="anchor" aria-hidden="true" href="#section-2">#</a></h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span> <span style="color:#a6e22e">menuOptions</span> <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">re</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> RegExp(<span style="color:#e6db74">&#34;^[A-Za-z]{3,15}\\s\\d{1,2},\\s\\d{2,4}&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">dates</span>.<span style="color:#a6e22e">length</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> ) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">date</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">dates</span>[<span style="color:#a6e22e">i</span>][<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">epochSheetDate</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Date(<span style="color:#a6e22e">date</span>).<span style="color:#a6e22e">getTime</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">date</span> <span style="color:#f92672">!=</span> <span style="color:#e6db74">&#34;&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateMatch</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">re</span>.<span style="color:#a6e22e">test</span>(<span style="color:#a6e22e">date</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dateMatch</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">true</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">epochDate</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">epochSheetDate</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">push</span>(<span style="color:#a6e22e">date</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span></code></pre></td></tr></table>
</div>
</div><p>In this section we&rsquo;re creating an empty array and instantiating a RegExp to ensure we have an actual date in the cell. See
<a href="https://regex101.com">Regex101</a> to learn more about Regex and test different regex syntax.</p>
<div class="box box-shortcode tip" >
<span class="icon-box baseline">
<svg><use href="#tip-box"></use></svg>
</span>
<p>Something that threw me off when first writing this regex function was the way the Google IDE manages escape character and
slashes. If you take the second line above and input it into <a href="https://regex101.com">Regex101</a> you&rsquo;ll see the <code>\s</code> or <code>\d</code>
become dark gray, basically skipping over that token. However, for Google, you&rsquo;ll need an additional backslash to escape and
make the token become used by the function.</p>
<p>Here&rsquo;s the &ldquo;correct&rdquo; RegExp string for Regex101.com: <code>^[A-Za-z]{3,15}\s\d{1,2},\s\d{2,4}</code></p>
</div>
<p>Next, we dive into a for loop, looping through the <code>dates</code> column of values (which we just called earlier). After attributing
each value to the <code>var date</code> variable, we also convert that same value into epoch time (by creating a new <code>Date().getTime()</code>)
so that we can compare it with today&rsquo;s date.</p>
<p>After the variables are setup we need to check that the date isn&rsquo;t empty; we don&rsquo;t need any rows where a date hasn&rsquo;t been assigned to it
yet. If we have a non-empty date value, let&rsquo;s compare it using the regex string. All we&rsquo;re doing here is asking &ldquo;Is this date
in the format I&rsquo;m expecting it?&rdquo; If true, let&rsquo;s keep the value and continue using it. If not, just ignore it.</p>
<p>So we&rsquo;ve now found a value that&rsquo;s in the date format we expect, let&rsquo;s now take that same value in epoch time (referenced by
the <code>epochSheetDate</code> variable) and compare it to today&rsquo;s epoch time date. If today&rsquo;s date is less than the value in the
sheet, that means the date in the sheet is in the future.</p>
<p>So now we have a date in the correct format and that is at some future date from today. Fantastic! Once we&rsquo;ve gone through
those checks, we&rsquo;re ready to add the date to the array we created at the top of this section. Push on!</p>
<h3 id="section-3">Section 3<a hidden class="anchor" aria-hidden="true" href="#section-3">#</a></h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">stringList</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">toString</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">formattedDates</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">stringList</span>.<span style="color:#a6e22e">replaceAll</span>(<span style="color:#e6db74">&#34;2024,&#34;</span>, <span style="color:#e6db74">&#34;2024 \n &#34;</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">response</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">prompt</span>(<span style="color:#e6db74">&#39;Which date would you like to create a presentation for? Please copy and paste the date exactly as you see it in the options below. Options: \n \n&#39;</span><span style="color:#f92672">+</span><span style="color:#a6e22e">formattedDates</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">getSelectedButton</span>() <span style="color:#f92672">==</span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">Button</span>.<span style="color:#a6e22e">OK</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateChosen</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">getResponseText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dateChosen</span> <span style="color:#f92672">!=</span> <span style="color:#e6db74">&#34;&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;Woohoo! Let&#39;s make a presentation!&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span>(<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">y</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">y</span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">dates</span>.<span style="color:#a6e22e">length</span>;<span style="color:#a6e22e">y</span><span style="color:#f92672">++</span>){
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dates</span>[<span style="color:#a6e22e">y</span>][<span style="color:#ae81ff">0</span>] <span style="color:#f92672">==</span> <span style="color:#a6e22e">dateChosen</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Logger.log(&#34;Row:&#34;+(y+2));
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">presRow</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">y</span><span style="color:#f92672">+</span><span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">presData</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getRange</span>(<span style="color:#a6e22e">presRow</span>,<span style="color:#ae81ff">3</span>,<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">4</span>).<span style="color:#a6e22e">getValues</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#a6e22e">presCopy</span> <span style="color:#66d9ef">of</span> <span style="color:#a6e22e">presData</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic2</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">1</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic3</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">2</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">additional_notes</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">3</span>];
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">createPresentation</span>(<span style="color:#a6e22e">dateChosen</span>, <span style="color:#a6e22e">topic1</span>, <span style="color:#a6e22e">topic2</span>, <span style="color:#a6e22e">topic3</span>, <span style="color:#a6e22e">additional_notes</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;Ouch. Looks like you entered something incorrectly (i.e. you entered nothing). Try again.&#34;</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;No Dates Available. Check Spreadsheet&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>This next section might feel long, but it&rsquo;s really easy to follow, don&rsquo;t worry. It&rsquo;s a lot of data organization to ensure
we&rsquo;re giving the users a smooth experience &amp; to make sure when the data hits the Slide, it&rsquo;s in the right spot.</p>
<p>First things first - let&rsquo;s only run this if we actually have items in the <code>menuOptions</code> array! No need to give the user an
affirmative message when there&rsquo;s no data to process. If there are no dates available, we call the else of this if, which is
the 3rd to last line in this section.</p>
<div class="box box-shortcode tip" >
<span class="icon-box baseline">
<svg><use href="#tip-box"></use></svg>
</span>
<p>A <code>ui.alert</code> is just a modal that offers no interaction to the user.</p>
</div>
<p>The next few lines are for processing that array of dates we grabbed from the sheet to making them presentable to the user.
Without the <code>stringList</code> and <code>formattedDates</code> variables, Google&rsquo;s modal just shows a wall of text of dates which makes it
difficult to parse for the user. By using <code>replaceAll()</code> we remove the comma and insert a new line after every portion of the
string that contains 2024 and a comma.</p>
<p>So now, instead of the modal showing:</p>
<pre tabindex="0"><code>February 2, 2024,February 3, 2024,February 4,2024... etc
</code></pre><p>We now see the much easier to read:</p>
<pre tabindex="0"><code>February 2, 2024
February 3, 2024
February 4, 2024
</code></pre><p>After that&rsquo;s formatted nicely, we can now have the prompt show for the user which asks them what date they would like to
process into a Slide presentation. Since we haven&rsquo;t visited any ui options since the top of this tutorial, this is the modal
that will show up after a user clicks &ldquo;Create Presentation&rdquo; in the top level menu in Google Sheets.</p>
<p>Ok, so now moving onto line 5, we need to get the text for what the user enters into the modal box. If they don&rsquo;t enter
anything, we should let them know that nothing will be done. That message comes from the second to last <code>else</code> statement in
this section. Instead, if they enter some data let&rsquo;s parse it!</p>
<div class="box box-shortcode warning" >
<span class="icon-box baseline">
<svg><use href="#warning-box"></use></svg>
</span>
<p>If you want to test yourself by adding in some new code try this exercise:</p>
<p><em>How can we ensure that the user entered a date in the format we expect? Tip: It is something reusable from another portion
of the script.</em></p>
</div>
<p>For lines 9 and 10, we&rsquo;re now looping back through the same set of rows that we did in section 2. The reason we&rsquo;re
re-entering this for loop is because we&rsquo;ve already exited the loop. So we have to get the values again. Once we have them,
let&rsquo;s match the date that the user entered to the correct row. We&rsquo;re able to do that by grabbing the index and adding 2 to
it.</p>
<div class="box box-shortcode info" >
<span class="icon-box baseline">
<svg><use href="#info-box"></use></svg>
</span>
<p>I haven&rsquo;t fully looked into <em>why</em> we need to add 2 to get the correct row number. As we loop through the dates, the array
length (<code>dates.length</code>) is all the available rows in the sheet. So you would think that <code>y</code> is the row that the value is on;
but it&rsquo;s not.</p>
<p>My only guess so far has to do with the frozen row at the top that I have in my Sheet. So the frozen row is not used, and row
2 is now index 0. Which means index 41 is technically row 43, and why we have to add 2 to the value to get the <em>visually
correct</em> row number. We need this number to be correct so that we can get the rest of the values int he sheet.</p>
</div>
<p>Now that we have the correct row number, we&rsquo;re going to shift from getting values from each row and getting them from each
column. By calling <code>var presData = sheet.getRange(presRow,3,1,4).getValues();</code> we are grabbing an array. <code>getRange</code> is
looking for the following values, in the following order:</p>
<ul>
<li>Row number (which we got from the <code>y+2</code>)</li>
<li>Column Number (which is Column C in this case)</li>
<li>Number of Rows (we only need this row)</li>
<li>Number of Columns (we know how many more columns we need).</li>
</ul>
<p>Next up, we&rsquo;re jumping into another for loop, now for all the data we just pulled from the column. This part is just parsing
each column&rsquo;s data into it&rsquo;s own variable for easier management when we create the presentation. We&rsquo;ve also grabbed the
additional notes column, but we&rsquo;re not using it right now. This column&rsquo;s data may be valuable by adding it to the speaker
notes of the Slide Presentation. Check out these two resources:</p>
<ul>
<li><a href="https://developers.google.com/slides/api/guides/notes">Working with Speaker Notes</a></li>
<li><a href="https://developers.google.com/slides/api/reference/rest/v1/presentations.pages#Page.NotesProperties">Notes Properties API</a></li>
</ul>
<p>Once that&rsquo;s done, call the next function: <code>createPresentation()</code>! We&rsquo;re almost done.</p>
<h2 id="createpresentation-function">createPresentation Function<a hidden class="anchor" aria-hidden="true" href="#createpresentation-function">#</a></h2>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">createPresentation</span>(<span style="color:#a6e22e">dateChosen</span>, <span style="color:#a6e22e">topic1</span>, <span style="color:#a6e22e">topic2</span>, <span style="color:#a6e22e">topic3</span>, <span style="color:#a6e22e">additionalNotes</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">slides</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SlidesApp</span>.<span style="color:#a6e22e">openById</span>(<span style="color:#e6db74">&#39;ENTER_ID_OF_SLIDE_PRESENTATION&#39;</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">slide</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">slides</span>.<span style="color:#a6e22e">getSlides</span>()[<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">elements</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">slide</span>.<span style="color:#a6e22e">getPageElements</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">elements</span>.<span style="color:#a6e22e">length</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">titles</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">getTitle</span>()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Date&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateText</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">dateText</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">dateText</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">dateChosen</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Topic 1&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic1Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic1Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic1Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic1</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Topic 2&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic2Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic2Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic2Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic2</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Topic 3&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic3Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic3Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic3Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic3</span>);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>This function may be the shortest to explain. All we are doing is taking those variables from the previous function (the
variables that contain each topic&rsquo;s text value) and doing the following:</p>
<ol>
<li>Opening the Presentation (line 2)</li>
<li>Getting the first slide (line 3)</li>
<li>Grabbing all the <a href="https://developers.google.com/apps-script/reference/slides/slides/page-element">page elements</a> (line 4)</li>
<li>Looping through the page elements &amp; grabbing all the titles that we set during <a href="#slides-setup">setup</a> (line
5 &amp; 6)</li>
<li>Then we compare the title of the Slide text box to the expected string (Topic 1-3), and if we get a match, retrieve the text
of the box as a variable, clear the text, and input our new text with the variables we created in the previous function.</li>
</ol>
<p>And just like that, you should have all your boxes filled in with the data you input to the Google Sheet!</p>
<div class="box box-shortcode tip" >
<span class="icon-box baseline">
<svg><use href="#tip-box"></use></svg>
</span>
<p><strong>Bonus exercises:</strong></p>
<ul>
<li>Instead of overwriting this presentation each time, how can you add a new slide with the same text boxes? How would you
find that slide since we&rsquo;re right now grabbing the first slide?</li>
<li>How can you change the name of this Slide Presentation to the date from the Sheet?</li>
<li>Could you automatically export this Slide as a PDF and save it to a user&rsquo;s Drive?</li>
</ul>
</div>
<style>
details summary {
min-width: 200px;
font-weight: 600;
cursor: pointer;
}
details summary > * {
display: inline;
}
details {
margin: 1em;
border-radius: 5px;
padding: 1em;
overflow: hidden;
box-shadow: 0 .1rem 1rem -.5rem rgba(0,0,0,.4);
}
summary {
padding: 0 1rem .3em 1.2rem;
display: block;
position: relative;
cursor: pointer;
}
summary:before {
content: '>';
position: absolute;
top: .1rem;
left: 0.1rem;
transform: rotate(0);
transition: .3s transform ease;
}
details[open] > summary:before {
transform: rotate(180deg);
content: '-';
}
details summary::-webkit-details-marker {
display:none;
}
</style><details><summary><h2 id="full-script">Full Script:<a hidden class="anchor" aria-hidden="true" href="#full-script">#</a></h2>
</summary>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">60
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">61
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">62
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">63
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">64
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">65
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">66
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">67
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">68
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">69
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">70
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">71
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">72
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">73
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">74
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">75
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">76
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">77
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">78
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">79
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">80
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">81
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">82
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">83
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">84
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">85
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">86
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">87
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">onOpen</span>(<span style="color:#a6e22e">e</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getUi</span>()
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">createMenu</span>(<span style="color:#e6db74">&#39;Create Presentation&#39;</span>)
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">addItem</span>(<span style="color:#e6db74">&#39;Create Presentation&#39;</span>, <span style="color:#e6db74">&#39;askDate&#39;</span> )
</span></span><span style="display:flex;"><span> .<span style="color:#a6e22e">addToUi</span>();
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">askDate</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">ui</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getUi</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">sheet</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SpreadsheetApp</span>.<span style="color:#a6e22e">getActiveSheet</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">lastRow</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getLastRow</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dates</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getRange</span>(<span style="color:#ae81ff">2</span>,<span style="color:#ae81ff">2</span>,<span style="color:#a6e22e">lastRow</span>,<span style="color:#ae81ff">1</span>).<span style="color:#a6e22e">getDisplayValues</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// get today&#39;s epoch time for easier calculations
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">epochDate</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Date().<span style="color:#a6e22e">getTime</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">menuOptions</span> <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">re</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> RegExp(<span style="color:#e6db74">&#34;^[A-Za-z]{3,15}\\s\\d{1,2},\\s\\d{2,4}&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">dates</span>.<span style="color:#a6e22e">length</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> ) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">date</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">dates</span>[<span style="color:#a6e22e">i</span>][<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">epochSheetDate</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Date(<span style="color:#a6e22e">date</span>).<span style="color:#a6e22e">getTime</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">date</span> <span style="color:#f92672">!=</span> <span style="color:#e6db74">&#34;&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateMatch</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">re</span>.<span style="color:#a6e22e">test</span>(<span style="color:#a6e22e">date</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dateMatch</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">true</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">epochDate</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">epochSheetDate</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">push</span>(<span style="color:#a6e22e">date</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">stringList</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">menuOptions</span>.<span style="color:#a6e22e">toString</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">stringlist</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">stringList</span>.<span style="color:#a6e22e">replaceAll</span>(<span style="color:#e6db74">&#34;2024,&#34;</span>, <span style="color:#e6db74">&#34;2024 \n &#34;</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">response</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">prompt</span>(<span style="color:#e6db74">&#39;Which date would you like to create a presentation for? Please copy and paste the date exactly as you see it in the options below. Options: \n \n&#39;</span><span style="color:#f92672">+</span><span style="color:#a6e22e">stringlist</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">getSelectedButton</span>() <span style="color:#f92672">==</span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">Button</span>.<span style="color:#a6e22e">OK</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateChosen</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">getResponseText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dateChosen</span> <span style="color:#f92672">!=</span> <span style="color:#e6db74">&#34;&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;Woohoo! Let&#39;s make a presentation!&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span>(<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">y</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">y</span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">dates</span>.<span style="color:#a6e22e">length</span>;<span style="color:#a6e22e">y</span><span style="color:#f92672">++</span>){
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">dates</span>[<span style="color:#a6e22e">y</span>][<span style="color:#ae81ff">0</span>] <span style="color:#f92672">==</span> <span style="color:#a6e22e">dateChosen</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// Logger.log(&#34;Row:&#34;+(y+2));
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">presRow</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">y</span><span style="color:#f92672">+</span><span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">presData</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">sheet</span>.<span style="color:#a6e22e">getRange</span>(<span style="color:#a6e22e">presRow</span>,<span style="color:#ae81ff">3</span>,<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">4</span>).<span style="color:#a6e22e">getValues</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#a6e22e">presCopy</span> <span style="color:#66d9ef">of</span> <span style="color:#a6e22e">presData</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic2</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">1</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">topic3</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">2</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">additional_notes</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">presCopy</span>[<span style="color:#ae81ff">3</span>];
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">createPresentation</span>(<span style="color:#a6e22e">dateChosen</span>, <span style="color:#a6e22e">topic1</span>, <span style="color:#a6e22e">topic2</span>, <span style="color:#a6e22e">topic3</span>, <span style="color:#a6e22e">additionalNotes</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;Ouch. Looks like you entered something incorrectly (i.e. you entered nothing). Try again.&#34;</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ui</span>.<span style="color:#a6e22e">alert</span>(<span style="color:#e6db74">&#34;No Dates Available. Check Spreadsheet&#34;</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">createPresentation</span>(<span style="color:#a6e22e">dateChosen</span>, <span style="color:#a6e22e">topic1</span>, <span style="color:#a6e22e">topic2</span>, <span style="color:#a6e22e">topic3</span>, <span style="color:#a6e22e">additionalNotes</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">slides</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">SlidesApp</span>.<span style="color:#a6e22e">openById</span>(<span style="color:#e6db74">&#39;ENTER_ID_OF_SLIDE_PRESENTATION&#39;</span>);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">slide</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">slides</span>.<span style="color:#a6e22e">getSlides</span>()[<span style="color:#ae81ff">0</span>];
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">elements</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">slide</span>.<span style="color:#a6e22e">getPageElements</span>();
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">elements</span>.<span style="color:#a6e22e">length</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">titles</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">getTitle</span>()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Date&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">dateText</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">dateText</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">dateText</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">dateChosen</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;topic1&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic1Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic1Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic1Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic1</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;topic2&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic2Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic2Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic2Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic2</span>);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">titles</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;topic3&#34;</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">topic3Text</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elements</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">asShape</span>().<span style="color:#a6e22e">getText</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic3Text</span>.<span style="color:#a6e22e">clear</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">topic3Text</span>.<span style="color:#a6e22e">setText</span>(<span style="color:#a6e22e">topic3</span>);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div>
</details>
<style>
.box-shortcode {
color: #e8e8e8;
border: none;
}
.post-content img {
margin: auto
}
details {
margin: 0;
padding: 0;
border: none;
background: transparent;
box-shadow: none;
}
</style>
</div>
<footer class="post-footer">
<ul class="post-tags">
<li><a href="../tags/google.html">Google</a></li>
<li><a href="../tags/scripts.html">Scripts</a></li>
<li><a href="../tags/sheets.html">Sheets</a></li>
</ul>
<nav class="paginav">
<a class="prev" href="../posts/save_terminal_to_file.html">
<span class="title">« Prev</span>
<br>
<span>How to Revisit your Terminal Session&#39;s History</span>
</a>
<a class="next" href="../posts/openresty_and_package_update_issues.html">
<span class="title">Next »</span>
<br>
<span>QuickHits: OpenResty and Package Updates</span>
</a>
</nav>
<ul class="share-buttons">
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on x"
href="https://x.com/intent/tweet/?text=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation&amp;url=%2fposts%2fgoogle_scripts_sheets_to_slides.html&amp;hashtags=google%2cscripts%2csheets">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M512 62.554 L 512 449.446 C 512 483.97 483.97 512 449.446 512 L 62.554 512 C 28.03 512 0 483.97 0 449.446 L 0 62.554 C 0 28.03 28.029 0 62.554 0 L 449.446 0 C 483.971 0 512 28.03 512 62.554 Z M 269.951 190.75 L 182.567 75.216 L 56 75.216 L 207.216 272.95 L 63.9 436.783 L 125.266 436.783 L 235.9 310.383 L 332.567 436.783 L 456 436.783 L 298.367 228.367 L 432.367 75.216 L 371.033 75.216 Z M 127.633 110 L 164.101 110 L 383.481 400.065 L 349.5 400.065 Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on linkedin"
href="https://www.linkedin.com/shareArticle?mini=true&amp;url=%2fposts%2fgoogle_scripts_sheets_to_slides.html&amp;title=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation&amp;summary=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation&amp;source=%2fposts%2fgoogle_scripts_sheets_to_slides.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-288.985,423.278l0,-225.717l-75.04,0l0,225.717l75.04,0Zm270.539,0l0,-129.439c0,-69.333 -37.018,-101.586 -86.381,-101.586c-39.804,0 -57.634,21.891 -67.617,37.266l0,-31.958l-75.021,0c0.995,21.181 0,225.717 0,225.717l75.02,0l0,-126.056c0,-6.748 0.486,-13.492 2.474,-18.315c5.414,-13.475 17.767,-27.434 38.494,-27.434c27.135,0 38.007,20.707 38.007,51.037l0,120.768l75.024,0Zm-307.552,-334.556c-25.674,0 -42.448,16.879 -42.448,39.002c0,21.658 16.264,39.002 41.455,39.002l0.484,0c26.165,0 42.452,-17.344 42.452,-39.002c-0.485,-22.092 -16.241,-38.954 -41.943,-39.002Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on reddit"
href="https://reddit.com/submit?url=%2fposts%2fgoogle_scripts_sheets_to_slides.html&title=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-3.446,265.638c0,-22.964 -18.616,-41.58 -41.58,-41.58c-11.211,0 -21.361,4.457 -28.841,11.666c-28.424,-20.508 -67.586,-33.757 -111.204,-35.278l18.941,-89.121l61.884,13.157c0.756,15.734 13.642,28.29 29.56,28.29c16.407,0 29.706,-13.299 29.706,-29.701c0,-16.403 -13.299,-29.702 -29.706,-29.702c-11.666,0 -21.657,6.792 -26.515,16.578l-69.105,-14.69c-1.922,-0.418 -3.939,-0.042 -5.585,1.036c-1.658,1.073 -2.811,2.761 -3.224,4.686l-21.152,99.438c-44.258,1.228 -84.046,14.494 -112.837,35.232c-7.468,-7.164 -17.589,-11.591 -28.757,-11.591c-22.965,0 -41.585,18.616 -41.585,41.58c0,16.896 10.095,31.41 24.568,37.918c-0.639,4.135 -0.99,8.328 -0.99,12.576c0,63.977 74.469,115.836 166.33,115.836c91.861,0 166.334,-51.859 166.334,-115.836c0,-4.218 -0.347,-8.387 -0.977,-12.493c14.564,-6.47 24.735,-21.034 24.735,-38.001Zm-119.474,108.193c-20.27,20.241 -59.115,21.816 -70.534,21.816c-11.428,0 -50.277,-1.575 -70.522,-21.82c-3.007,-3.008 -3.007,-7.882 0,-10.889c3.003,-2.999 7.882,-3.003 10.885,0c12.777,12.781 40.11,17.317 59.637,17.317c19.522,0 46.86,-4.536 59.657,-17.321c3.016,-2.999 7.886,-2.995 10.885,0.008c3.008,3.011 3.003,7.882 -0.008,10.889Zm-5.23,-48.781c-16.373,0 -29.701,-13.324 -29.701,-29.698c0,-16.381 13.328,-29.714 29.701,-29.714c16.378,0 29.706,13.333 29.706,29.714c0,16.374 -13.328,29.698 -29.706,29.698Zm-160.386,-29.702c0,-16.381 13.328,-29.71 29.714,-29.71c16.369,0 29.689,13.329 29.689,29.71c0,16.373 -13.32,29.693 -29.689,29.693c-16.386,0 -29.714,-13.32 -29.714,-29.693Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on facebook"
href="https://facebook.com/sharer/sharer.php?u=%2fposts%2fgoogle_scripts_sheets_to_slides.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-106.468,0l0,-192.915l66.6,0l12.672,-82.621l-79.272,0l0,-53.617c0,-22.603 11.073,-44.636 46.58,-44.636l36.042,0l0,-70.34c0,0 -32.71,-5.582 -63.982,-5.582c-65.288,0 -107.96,39.569 -107.96,111.204l0,62.971l-72.573,0l0,82.621l72.573,0l0,192.915l-191.104,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on whatsapp"
href="https://api.whatsapp.com/send?text=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation%20-%20%2fposts%2fgoogle_scripts_sheets_to_slides.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-58.673,127.703c-33.842,-33.881 -78.847,-52.548 -126.798,-52.568c-98.799,0 -179.21,80.405 -179.249,179.234c-0.013,31.593 8.241,62.428 23.927,89.612l-25.429,92.884l95.021,-24.925c26.181,14.28 55.659,21.807 85.658,21.816l0.074,0c98.789,0 179.206,-80.413 179.247,-179.243c0.018,-47.895 -18.61,-92.93 -52.451,-126.81Zm-126.797,275.782l-0.06,0c-26.734,-0.01 -52.954,-7.193 -75.828,-20.767l-5.441,-3.229l-56.386,14.792l15.05,-54.977l-3.542,-5.637c-14.913,-23.72 -22.791,-51.136 -22.779,-79.287c0.033,-82.142 66.867,-148.971 149.046,-148.971c39.793,0.014 77.199,15.531 105.329,43.692c28.128,28.16 43.609,65.592 43.594,105.4c-0.034,82.149 -66.866,148.983 -148.983,148.984Zm81.721,-111.581c-4.479,-2.242 -26.499,-13.075 -30.604,-14.571c-4.105,-1.495 -7.091,-2.241 -10.077,2.241c-2.986,4.483 -11.569,14.572 -14.182,17.562c-2.612,2.988 -5.225,3.364 -9.703,1.12c-4.479,-2.241 -18.91,-6.97 -36.017,-22.23c-13.314,-11.876 -22.304,-26.542 -24.916,-31.026c-2.612,-4.484 -0.279,-6.908 1.963,-9.14c2.016,-2.007 4.48,-5.232 6.719,-7.847c2.24,-2.615 2.986,-4.484 4.479,-7.472c1.493,-2.99 0.747,-5.604 -0.374,-7.846c-1.119,-2.241 -10.077,-24.288 -13.809,-33.256c-3.635,-8.733 -7.327,-7.55 -10.077,-7.688c-2.609,-0.13 -5.598,-0.158 -8.583,-0.158c-2.986,0 -7.839,1.121 -11.944,5.604c-4.105,4.484 -15.675,15.32 -15.675,37.364c0,22.046 16.048,43.342 18.287,46.332c2.24,2.99 31.582,48.227 76.511,67.627c10.685,4.615 19.028,7.371 25.533,9.434c10.728,3.41 20.492,2.929 28.209,1.775c8.605,-1.285 26.499,-10.833 30.231,-21.295c3.732,-10.464 3.732,-19.431 2.612,-21.298c-1.119,-1.869 -4.105,-2.99 -8.583,-5.232Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on telegram"
href="https://telegram.me/share/url?text=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation&amp;url=%2fposts%2fgoogle_scripts_sheets_to_slides.html">
<svg version="1.1" xml:space="preserve" viewBox="2 2 28 28" height="30px" width="30px" fill="currentColor">
<path
d="M26.49,29.86H5.5a3.37,3.37,0,0,1-2.47-1,3.35,3.35,0,0,1-1-2.47V5.48A3.36,3.36,0,0,1,3,3,3.37,3.37,0,0,1,5.5,2h21A3.38,3.38,0,0,1,29,3a3.36,3.36,0,0,1,1,2.46V26.37a3.35,3.35,0,0,1-1,2.47A3.38,3.38,0,0,1,26.49,29.86Zm-5.38-6.71a.79.79,0,0,0,.85-.66L24.73,9.24a.55.55,0,0,0-.18-.46.62.62,0,0,0-.41-.17q-.08,0-16.53,6.11a.59.59,0,0,0-.41.59.57.57,0,0,0,.43.52l4,1.24,1.61,4.83a.62.62,0,0,0,.63.43.56.56,0,0,0,.4-.17L16.54,20l4.09,3A.9.9,0,0,0,21.11,23.15ZM13.8,20.71l-1.21-4q8.72-5.55,8.78-5.55c.15,0,.23,0,.23.16a.18.18,0,0,1,0,.06s-2.51,2.3-7.52,6.8Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share Google Sheets to Slides with Scripts: an Automation on ycombinator"
href="https://news.ycombinator.com/submitlink?t=Google%20Sheets%20to%20Slides%20with%20Scripts%3a%20an%20Automation&u=%2fposts%2fgoogle_scripts_sheets_to_slides.html">
<svg version="1.1" xml:space="preserve" width="30px" height="30px" viewBox="0 0 512 512" fill="currentColor"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<path
d="M449.446 0C483.971 0 512 28.03 512 62.554L512 449.446C512 483.97 483.97 512 449.446 512L62.554 512C28.03 512 0 483.97 0 449.446L0 62.554C0 28.03 28.029 0 62.554 0L449.446 0ZM183.8767 87.9921H121.8427L230.6673 292.4508V424.0079H281.3328V292.4508L390.1575 87.9921H328.1233L256 238.2489z" />
</svg>
</a>
</li>
</ul>
</footer>
</article>
</main>
<footer class="footer">
<span>&copy; 2024 <a href="../">Norm-working Packets 💾</a></span>
<span>
Powered by
<a href="https://gohugo.io/" rel="noopener noreferrer" target="_blank">Hugo</a> &
<a href="https://github.com/adityatelange/hugo-PaperMod/" rel="noopener" target="_blank">PaperMod</a>
</span>
</footer>
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
<path d="M12 6H0l6-6z" />
</svg>
</a>
<script>
let menu = document.getElementById('menu')
if (menu) {
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
menu.onscroll = function () {
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
}
}
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
var id = this.getAttribute("href").substr(1);
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
behavior: "smooth"
});
} else {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
}
if (id === "top") {
history.replaceState(null, null, " ");
} else {
history.pushState(null, null, `#${id}`);
}
});
});
</script>
<script>
var mybutton = document.getElementById("top-link");
window.onscroll = function () {
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
mybutton.style.visibility = "visible";
mybutton.style.opacity = "1";
} else {
mybutton.style.visibility = "hidden";
mybutton.style.opacity = "0";
}
};
</script>
<script>
document.getElementById("theme-toggle").addEventListener("click", () => {
if (document.body.className.includes("dark")) {
document.body.classList.remove('dark');
localStorage.setItem("pref-theme", 'light');
} else {
document.body.classList.add('dark');
localStorage.setItem("pref-theme", 'dark');
}
})
</script>
<script>
document.querySelectorAll('pre > code').forEach((codeblock) => {
const container = codeblock.parentNode.parentNode;
const copybutton = document.createElement('button');
copybutton.classList.add('copy-code');
copybutton.innerHTML = 'copy';
function copyingDone() {
copybutton.innerHTML = 'copied!';
setTimeout(() => {
copybutton.innerHTML = 'copy';
}, 2000);
}
copybutton.addEventListener('click', (cb) => {
if ('clipboard' in navigator) {
navigator.clipboard.writeText(codeblock.textContent);
copyingDone();
return;
}
const range = document.createRange();
range.selectNodeContents(codeblock);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand('copy');
copyingDone();
} catch (e) { };
selection.removeRange(range);
});
if (container.classList.contains("highlight")) {
container.appendChild(copybutton);
} else if (container.parentNode.firstChild == container) {
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
} else {
codeblock.parentNode.appendChild(copybutton);
}
});
</script>
</body>
</html>