<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Eamonn Cottrell - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Eamonn Cottrell - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:51 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/sieis/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Microsoft Excel: 14 Time-Saving Keyboard Shortcuts ]]>
                </title>
                <description>
                    <![CDATA[ Microsoft Excel is the quintessential spreadsheet software used everywhere from universities to small businesses to enterprises. It’s a lifesaver for countless financial professionals, data analysts, and teachers. But it’s also one of those programs ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/microsoft-excel-keyboard-shortcuts/</link>
                <guid isPermaLink="false">670ead175b03d2b334e6560f</guid>
                
                    <category>
                        <![CDATA[ excel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analysis ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Tue, 15 Oct 2024 17:57:43 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728930420116/82fe0d9f-89fe-4332-82dc-43b44d4ee2dc.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Microsoft Excel is the quintessential spreadsheet software used everywhere from universities to small businesses to enterprises.</p>
<p>It’s a lifesaver for countless financial professionals, data analysts, and teachers. But it’s also one of those programs that virtually everyone in any role can benefit from learning.</p>
<p>A handful of shortcuts can go a long way in increasing your productivity (and enjoyment) while using Excel.</p>
<p>In this article, I’ll detail some of the many shortcuts that I have found helpful throughout my studies and career.</p>
<h3 id="heading-excel-shortcuts-well-cover">Excel Shortcuts We’ll Cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-execute-shortcuts-in-excel">How to Execute Shortcuts in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-create-a-table">Shortcut to Create a Table</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-create-a-pivot-table">Shortcut to Create a Pivot Table</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-autofit-column-sizes">Shortcut to AutoFit Column Sizes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-open-format-cells">Shortcut to Open Format Cells</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-center-contents-of-cell">Shortcut to Center Contents of Cell</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-fill-color">Shortcut to Fill Color</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-fill-contents-down-or-right">Shortcut to Fill Contents Down (or Right)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-show-or-hide-gridlines">Shortcut to Show or Hide Gridlines</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-show-all-formulas">Shortcut to Show all Formulas</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcuts-for-navigation-in-excel">Shortcuts for Navigation in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-open-the-autofilter-menu-in-excel">Shortcut to Open the AutoFilter Menu in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-create-a-slicer-in-excel">Shortcut to Create a Slicer in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-create-checkboxes-in-excel">Shortcut to Create Checkboxes in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcut-to-create-charts-in-excel">Shortcut to Create Charts in Excel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-other-notes">Other Notes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-more-shortcuts">More Shortcuts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-got-sheet">Got Sheet</a></p>
</li>
</ul>
<p>Here’s a video walkthrough of everything we’ll cover in this article:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/RfFhh0n4bMM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-execute-shortcuts-in-excel">How to Execute Shortcuts in Excel</h2>
<p>In Excel, the more you can learn to do without touching your mouse, the better. Often, by keeping your hands on your keyboard, you can save a lot of time in each project.</p>
<p>As such, virtually every command imaginable is available as a keyboard shortcut.</p>
<p>The basic ones like <code>CTRL + S</code> for save and <code>CTRL + C</code> for copy are present. But Excel goes a step further…</p>
<p>The real power comes from the <code>alt</code> shortcuts. By pressing sequences of keys that typically start with <code>alt</code>, almost all of the actions in the Ribbon become available.</p>
<p>By simply pressing the <code>alt</code> key, all of the shortcut sequences available from the current view become highlighted in yellow on the ribbon:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728924144231/6b083a86-6db6-41e3-b960-4a06a5d3284f.png" alt="alt shortcuts in Excel" class="image--center mx-auto" width="1059" height="280" loading="lazy"></p>
<p>Incidentally, some of the shortcuts’ sequences are separated by commas, while at other times two letters appear next to each other. Their execution is the same. Simply press them in sequence.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728925276816/8867e861-ecd7-43d9-989d-dab2fef62d8a.png" alt="one vs two letter shortcut sequences" class="image--center mx-auto" width="169" height="89" loading="lazy"></p>
<p>Below, you’ll find some of my favorites, but keep in mind that you can easily view all the available shortcuts at any time by pressing <code>alt</code> and then continuing to press the appropriate keys for the corresponding tabs and actions.</p>
<h2 id="heading-shortcut-to-create-a-table">Shortcut to Create a Table</h2>
<h3 id="heading-keyboard-shortcut-ctrl-t">Keyboard Shortcut: <code>ctrl + t</code></h3>
<p>Tables in Excel are often the preferred format to begin manipulating and visualizing data. As long as the active cell is inside your data range, pressing <code>ctrl + t</code> will pop up a dialog and automatically select the data range to be used for the table.</p>
<p>It is adjustable if Excel gets a column or row wrong, and you can also toggle table headers on or off from this initial box.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728924526482/aa5ffdee-2327-4232-8a6d-c74e271f4bce.png" alt="create table in Excel" class="image--center mx-auto" width="342" height="204" loading="lazy"></p>
<h2 id="heading-shortcut-to-create-a-pivot-table">Shortcut to Create a Pivot Table</h2>
<h3 id="heading-keyboard-shortcut-alt-n-v-t">Keyboard shortcut: <code>alt + n, v, t</code></h3>
<p>Want to appear a lot smarter than you are? Learn the basics of pivot tables in ten minutes. Your coworkers will remain impressed for weeks.</p>
<p>To create a pivot table, simply click somewhere in your data range and press <code>ALT + n, v, t</code>.</p>
<p>Excel is smart enough to recognize the data range you likely want included even if it isn’t already formatted as a table.</p>
<p>A dialog box will pop up for you to confirm the data range and location for the pivot table.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728924350920/21f22ae2-238c-4e73-9690-cbc538c46458.png" alt="21f22ae2-238c-4e73-9690-cbc538c46458" class="image--center mx-auto" width="635" height="357" loading="lazy"></p>
<h2 id="heading-shortcut-to-autofit-column-sizes">Shortcut to AutoFit Column Sizes</h2>
<h3 id="heading-keyboard-shortcut-alt-h-o-i">Keyboard Shortcut: <code>alt + h, o, i</code></h3>
<p>Ever get tired of resizing your columns so that the text in the cells doesn’t clip or spill? You can always double click the column boundary headings. This resizes the column to fit the widest cell’s contents.</p>
<p>The keyboard shortcut is much more efficient and allows you to autofit multiple columns in one fell swoop. Simply click and drag the column boundaries to select any number of columns. Execute the <code>alt + h, o, i</code> shortcut and all the columns in your active range will autofit their width.</p>
<p>You can also autofit cells individually by selecting one or more active cells and performing the same shortcut.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728924664667/9611fe54-9d2f-442c-9246-a3ab85b1e81d.png" alt="autofit column width in Excel" class="image--center mx-auto" width="411" height="427" loading="lazy"></p>
<h2 id="heading-shortcut-to-open-format-cells">Shortcut to Open Format Cells</h2>
<h3 id="heading-keyboard-shortcut-ctrl-1-or-alt-h-fm">Keyboard Shortcut: <code>CTRL + 1</code> or <code>alt + h, fm</code></h3>
<p>Unless you are content with mediocrity, you’ll be formatting the cells in your spreadsheet at some point to create more readable, user-friendly content.</p>
<p>The simplest shortcut to open up the Format Cells window is <code>CTRL + 1</code>, although if you want to flex your dexterity, <code>alt + h, fm</code> will get you there as well.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728925061866/0d773119-097f-479e-bcc5-5bb8ba311a5d.png" alt="Cell formatting options" class="image--center mx-auto" width="783" height="774" loading="lazy"></p>
<h2 id="heading-shortcut-to-center-contents-of-cell">Shortcut to Center Contents of Cell</h2>
<h3 id="heading-keyboard-shortcut-horizontal-alt-h-a-c">Keyboard Shortcut: (horizontal) <code>alt + h, a, c</code>,</h3>
<p>(vertical) <code>alt + h, a, m</code></p>
<p>We have it easy compared to web developers. There seems a never-ending supply of articles and videos reminding developers how to center <code>divs</code>.</p>
<p>In Excel, we need only remember two quick shortcuts.</p>
<ul>
<li><p>For horizontal centering: <code>alt + h, a, c</code></p>
</li>
<li><p>For vertical centering: <code>alt + h, a, m</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728925842812/56676126-976e-4f1d-bb8a-2bf7072f9342.png" alt="centering text in a cell in Excel" class="image--center mx-auto" width="453" height="372" loading="lazy"></p>
<p>There are other shortcuts for left, right, top and bottom alignment, but most of the time when we change the original alignment, it’s to center it.</p>
<h2 id="heading-shortcut-to-fill-color">Shortcut to Fill Color</h2>
<h3 id="heading-keyboard-shortcut-alt-h-h">Keyboard Shortcut: <code>alt + h, h</code></h3>
<p>For a quick highlight, it takes precious seconds to mouse up to the fill color icon. Pressing <code>alt + h, h</code> quickly toggles the color selection open.</p>
<p>Once it’s open, you can leave your mouse to the side and arrow down to your favorite color</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728926023010/6cebdbc6-e27e-4784-8cc8-d46dbf8c4985.png" alt="fill color menu in Excel" class="image--center mx-auto" width="385" height="603" loading="lazy"></p>
<h2 id="heading-shortcut-to-fill-contents-down-or-right">Shortcut to Fill Contents Down (or Right)</h2>
<h3 id="heading-keyboard-shortcut-down-ctrl-d-right-ctrl-r">Keyboard Shortcut: (down) <code>CTRL + D</code>, (right) <code>CTRL + R</code></h3>
<p>One of the most powerful features of Excel is the ability to drag formulas and functions down or across many cells, effectively reproducing a single calculation many times on different pieces of data.</p>
<p>By typing a formula in cell A8 in the image below, we can then highlight A8 and drag down to our heart’s content. Then, by pressing <code>CTRL + D</code>, the formula will be copied down into every highlighted cell.</p>
<p>By default, it will also preserve the relative reference of the cell. In other words, the next cell will contain the formula <code>A7 + A8</code> and then <code>A8 + A9</code>, and so on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728927617121/35dd07d3-90ac-4c31-9318-1e588bff007c.png" alt="Dragging down" class="image--center mx-auto" width="1116" height="1349" loading="lazy"></p>
<h2 id="heading-shortcut-to-show-or-hide-gridlines">Shortcut to Show or Hide Gridlines</h2>
<h3 id="heading-keyboard-shortcut-alt-w-vg">Keyboard Shortcut: <code>alt + w, vg</code></h3>
<p>The mark of a real data analyst is not the quality of their reports, but the precision of their workbook. Gridlines have got to go. If you need lines, you can add borders.</p>
<p>Toggle off the gridlines with <code>alt + w, vg</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728926496034/ab39e08c-1ac2-4d4d-986e-1c79597a322e.png" alt="Shortcut to toggle off gridlines" class="image--center mx-auto" width="332" height="158" loading="lazy"></p>
<p>And if you need those borders immediately, highlight your data range and press <code>alt + h, b</code> to open up the border menu. If you simply need all borders, <code>alt + h, b, a</code> will do the trick</p>
<h2 id="heading-shortcut-to-show-all-formulas">Shortcut to Show all Formulas</h2>
<h3 id="heading-keyboard-shortcut-ctrl">Keyboard Shortcut: <code>CTRL + ~</code></h3>
<p>You’ll likely never lose control of a workbook.</p>
<p>But in the event you access one of your less rigorous colleague’s workbooks and need to see what functions they’ve Frankensteined together, press <code>CTRL + ~</code> to display all the functions instead in the spreadsheet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728927250678/868f9daa-04d7-447c-b494-15fea77a4e1c.png" alt="display functions in Excel workbook" class="image--center mx-auto" width="807" height="709" loading="lazy"></p>
<h2 id="heading-shortcuts-for-navigation-in-excel">Shortcuts for Navigation in Excel</h2>
<h3 id="heading-keyboard-shortcuts-ctrl-arrow-keys-and-others">Keyboard Shortcuts: <code>CTRL + arrow keys</code> (and others)</h3>
<p>Navigating the grid can be very fast with the keyboard. Pressing <code>CTRL +</code> the <code>arrows</code>, the <code>home</code> and the <code>end</code> buttons will warp you all over the active sheet.</p>
<p>Using the <code>arrows</code> and <code>CTRL</code>, you go to the last nonblank cell in the row or column.</p>
<p>Using <code>CTRL + home or end</code>, you go to the beginning and the end of the workbook, respectively. (When inside a table, <code>home</code> and <code>end</code> take you to the beginning and end of the table only.)</p>
<h2 id="heading-shortcut-to-open-the-autofilter-menu-in-excel">Shortcut to Open the AutoFilter Menu in Excel</h2>
<h3 id="heading-keyboard-shortcut-alt-down-arrow">Keyboard Shortcut: <code>alt + down arrow</code></h3>
<p>Another superpower in Excel is the ease with which we can filter and sort large pieces of data. To access the AutoFilter Menu quickly, press <code>alt + down arrow</code> while in the header for the column you’d like to filter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728928353490/dcca3af8-2858-4ca0-abd6-d7e197826008.png" alt="auto-filter menu" class="image--center mx-auto" width="444" height="918" loading="lazy"></p>
<h2 id="heading-shortcut-to-create-a-slicer-in-excel">Shortcut to Create a Slicer in Excel</h2>
<h3 id="heading-keyboard-shortcut-alt-n-sf">Keyboard Shortcut: <code>alt + n, sf</code></h3>
<p>For an even more user-friendly method of sorting, you can insert a slicer directly onto the spreadsheet by pressing <code>alt + n, sf</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728928617015/599d1bb7-4873-4f3d-aee2-6d478dcc034c.png" alt="Menu for inserting slicers" class="image--center mx-auto" width="536" height="556" loading="lazy"></p>
<h2 id="heading-shortcut-to-create-checkboxes-in-excel">Shortcut to Create Checkboxes in Excel</h2>
<h3 id="heading-keyboard-shortcut-alt-n-cb">Keyboard Shortcut: <code>alt + n, cb</code></h3>
<p>If you’re anything like me, you’ll find a way to use checkboxes in almost every spreadsheet you create. They’re extremely useful for toggling selections on and off in a workbook, and as of June 2024, Excel has made them available in production Excel.</p>
<p>Press <code>alt + n, cb</code> to insert a checkbox in a cell.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728931963136/cc54e602-2d2c-4536-b07f-408f8404977d.png" alt="cc54e602-2d2c-4536-b07f-408f8404977d" class="image--center mx-auto" width="506" height="467" loading="lazy"></p>
<h2 id="heading-shortcut-to-create-charts-in-excel">Shortcut to Create Charts in Excel</h2>
<h3 id="heading-keyboard-shortcut-alt-n-r">Keyboard Shortcut: <code>alt + n, r</code></h3>
<p>There are a ton of chart types in Excel. To quickly open up the recommended charts dialog box, we can press <code>alt + n, r</code>.</p>
<p>Or, if we know we want a specific type of chart, there are multiple options to shortcut straight to them, like <code>alt + n, C1</code>, <code>alt + n, N1</code>, <code>alt + n, SA</code> and so on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729001331573/b9e240ba-6f42-4817-9d8c-e27241f66b18.png" alt="Chart types" class="image--center mx-auto" width="911" height="439" loading="lazy"></p>
<h2 id="heading-more-shortcuts">More Shortcuts</h2>
<p>There are a zillion shortcuts available in Excel. If you want to check out the full list, you can find a current version maintained by <a target="_blank" href="https://support.microsoft.com/en-us/office/keyboard-shortcuts-in-excel-1798d9d5-842a-42b8-9c99-9b7213f0040f">Microsoft here</a>.</p>
<h2 id="heading-got-sheet">Got Sheet</h2>
<p>Come join my free newsletter, <a target="_blank" href="https://www.gotsheet.xyz/subscribe">Got Sheet</a>. I show people how to get good at spreadsheets every week.</p>
<p>You can find me over on <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube</a> as well.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Work with Tables in Excel vs Google Sheets ]]>
                </title>
                <description>
                    <![CDATA[ Google Sheets recently released an all new feature: tables. Well, new is a bit of an overstatement. Excel has had proper tables for many, many years, and it's been a point of contention in the spreadsheet community. In this article, I'll break down w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/excel-vs-google-sheets-tables/</link>
                <guid isPermaLink="false">66b8dde70a89d796f29a16dd</guid>
                
                    <category>
                        <![CDATA[ excel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Tue, 02 Jul 2024 17:27:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/4.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google Sheets recently released an all new feature: tables.</p>
<p>Well, <em>new</em> is a bit of an overstatement. Excel has had proper tables for many, many years, and it's been a point of contention in the spreadsheet community.</p>
<p>In this article, I'll break down what exactly tables are, why they're important, and then see how Google Sheet's new tables stack up against Microsoft Excel's.</p>
<p>Here is a video walkthrough of everything we'll cover:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vBp5mveYZZ4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-whats-a-table">What's a Table?</h2>
<p>A table is a way of structuring and formatting data in a spreadsheet. It groups together rows and columns of data so that they can be more easily filtered, grouped, and analyzed.</p>
<p>Many people would look at the following bit of data and wrongly assume that it's already in a table.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-103.png" alt="Image" width="600" height="400" loading="lazy">
<em>Data in Excel</em></p>
<p>This is merely well organized rows and columns of data in Excel. Each column is a separate category of information, that is ids, names, emails, job titles, and salaries.</p>
<p>Each row represents one entry of that data. So, you'd put your id, name, email, job title and salary going left to right in a row.</p>
<p>Simple, yes?</p>
<p>A table contains all the same data, but by formatting it as a table we can unlock a whole lot of additional functionality.</p>
<p>The first of which is the appearance itself. When we create a table, Excel immediately colors our data with a dark header row and bands of alternating colors.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-104.png" alt="Image" width="600" height="400" loading="lazy">
<em>Table in Excel</em></p>
<p>Sheets does the same thing, as we can see below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-105.png" alt="Image" width="600" height="400" loading="lazy">
<em>Table in Google Sheets</em></p>
<p>So, a table is simply a way of managing and grouping data more easily. But it goes much further than just formatting, as we'll see.</p>
<h2 id="heading-why-are-tables-important">Why are Tables Important?</h2>
<p>Tables help reduce errors. When dealing with data, we are always making sure the data is clean and that we don't have errors in our formulas. </p>
<p>Tables help keep things orderly simply by being structured and formatted well. But as we'll see in the formula section in a moment, they also allow us to reduce errors in formulas by dynamically calculating things for us</p>
<h2 id="heading-how-to-create-a-table-in-excel-and-sheets">How to Create a Table in Excel and Sheets</h2>
<p>In Microsoft Excel, creating a table is as easy as clicking anywhere in the data range and pressing <code>CTRL + T</code>. Immediately, Excel will predict the data range for the table and ask you to confirm this.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-106.png" alt="Image" width="600" height="400" loading="lazy">
<em>Excel table data range</em></p>
<p>Alternatively, you can find the same create table option from the Insert Menu in the Ribbon at the top.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/table.png" alt="Image" width="600" height="400" loading="lazy">
<em>Excel insert menu</em></p>
<p>Over in Sheets, you'll need to either right click in a cell in the data range, or select the option from the Format menu to Convert to Table.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/sheets.png" alt="Image" width="600" height="400" loading="lazy">
<em>Convert to table options in Google Sheets</em></p>
<p>One caveat in Sheets: if you right click in a cell, you have to select the whole data range for it to convert to a table. Whereas, if you select Format - Convert to table from the menu, it is (like Excel) smart enough to predict the whole data range.</p>
<p>A small thing. But Excel takes the prize for ease of creation.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/right-click.png" alt="Image" width="600" height="400" loading="lazy">
<em>Convert to table in Google Sheets</em></p>
<p><strong>⭐Winner: EXCEL</strong></p>
<h2 id="heading-how-to-format-tables-in-excel-and-sheets">How to Format Tables in Excel and Sheets</h2>
<p>As we saw initially, some formatting is done as soon as we create a table.</p>
<p>From here, though, both programs allow for further customization.</p>
<p>In Sheets, we can select the dropdown in the top left next to the table name to access a few options immediately. For the most part, we can simply change the alternating colors of the table.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/sheets-format.png" alt="Image" width="600" height="400" loading="lazy">
<em>Formatting options in Google Sheets</em></p>
<p>If we select Custom, it opens up the full alternating colors menu that is also accessible through the Format menu. This gives us more control over the colors, but it's all aesthetic.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-110.png" alt="Image" width="600" height="400" loading="lazy">
<em>Alternating colors menu in Google Sheets</em></p>
<p>Meanwhile in Excel, we have the same options with a few more toggle selections for styling. For instance, we can check the first column to bold the text in the id column or we toggle between banded columns and/or rows.</p>
<p>And on the far right of the Table Design tab in the Ribbon, there are a ton of prebuilt styles that we can toggle on and off.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/format-excel.png" alt="Image" width="600" height="400" loading="lazy">
<em>Table design in Excel</em></p>
<p>Both programs give plenty of options here, and this is mostly to make the tables look good. But Excel comes out on top with more options.</p>
<p><strong>⭐Winner: EXCEL</strong></p>
<h2 id="heading-how-to-sort-tables-in-excel-and-google-sheets">How to Sort Tables in Excel and Google Sheets</h2>
<p>In both programs, there is a dropdown toggle button in each of the header row's cells. Selecting this in Excel allows us to sort ascending or descending...or even by color.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/sort.png" alt="Image" width="600" height="400" loading="lazy">
<em>sort in excel</em></p>
<p>For instance, if we have some of our data using a blue font color, we can actually sort it by that color:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/sort-color.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sort by color in Excel</em></p>
<p>What about Google Sheets? Yep, same deal there. It will also detect when different colors are used and allow you to do the same type of sorting.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/sheets-sorting-options-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sort by color in Sheets</em></p>
<p>Excel does have a Custom Sorting dialog box that can drill down into more detail. For instance, you can add levels of sorting.</p>
<p>Using our color example, we can first sort by the blue font colors in the email color and then by the red font colors in the job title column.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/double-sort.png" alt="Image" width="600" height="400" loading="lazy">
<em>Multiple column sorting in Excel</em></p>
<p>Google Sheets can do the same thing, but not from the header drop downs. The header drop down sorting is restricted to one row at a time in Sheets.</p>
<p>But, if you select the entire table's data range and then <code>Data - Sort Range - Advanced range sorting options</code>, you are able to sort by multiple columns in Google Sheets.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/advanced-sort-google-sheets.png" alt="Image" width="600" height="400" loading="lazy">
<em>Advanced sorting in Google Sheets</em></p>
<p>Sheets' advanced sorting is not as powerful as Excel's, though. You are only able to sort ascending or descending by value. Excel takes the cake on this one by a hair.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/google-sheets-muiltiple-row-sorting.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>⭐Winner: EXCEL</strong></p>
<h2 id="heading-how-to-filter-tables-in-excel-and-google-sheets">How to Filter Tables in Excel and Google Sheets</h2>
<p>Filtering works exactly the same as sorting. In both programs, click the dropdown selector in the header row to see the options for filtering.</p>
<p>In both programs, we have the same options. We can filter by color just like in our sorting. We can filter by values by either selecting all, none, or individual values. And we can filter by condition.</p>
<p>Here's Google Sheet's menu:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-113.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filtering in Google Sheets</em></p>
<p>And here's Excel's menu. All the same options are available. Both programs allow for custom filter formulas to be entered as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-112.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filtering in Excel</em></p>
<p><strong>⭐Winner: TIE</strong></p>
<h2 id="heading-how-to-use-tables-in-formulas-in-excel-and-google-sheets">How to Use Tables in Formulas in Excel and Google Sheets</h2>
<p>One of the big reasons to use tables lies in formulas. Whether you use Excel or Sheets, you are likely taking advantage of built-in functions and the ability to create custom formulas for analyzing your data.</p>
<p>By holding your data in a table, your formulas can reference that data dynamically.</p>
<p>Meaning, if you add rows of data to your table, any formulas referencing those table values will update automatically.</p>
<p>The risk of breaking things by adding data decreases dramatically with the use of tables.</p>
<p>Here's a simple example. If we wanted to combine the first and last names into one cell, we could concatenate them with this formula <code>=Salary[first_name]&amp;" "&amp;Salary[last_name]</code>.</p>
<p>In Excel, we reference a table by its name, in this case, <code>Salary</code>. Then within brackets, we reference a column name, <code>[last_name]</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-115.png" alt="Image" width="600" height="400" loading="lazy">
<em>Spill formula in Excel</em></p>
<p>We can do the exact same in Sheets.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-116.png" alt="Image" width="600" height="400" loading="lazy">
<em>Formula referencing in Sheets</em></p>
<p>There's one powerful difference, though. In Excel, the formula will spill down. Meaning, we only have to write it once at the very top, but because it sees that we're referencing values in a table, it will spill down to every row in the table.</p>
<p>In Google Sheets, we still have to drag the formula down.</p>
<p>Now, sometimes, we may not want things to spill down. In this case we can use different syntax in Excel. Instead of the column name within brackets, we can add an @ sign and another set of brackets. This tells Excel to only make the calculation on one row: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-117.png" alt="Image" width="600" height="400" loading="lazy">
<em>Formula referencing in Excel</em></p>
<p>Excel flexes on this one. It's much more powerful to use tables in formulas in Excel than in Sheets.</p>
<p><strong>⭐Winner: EXCEL</strong></p>
<h2 id="heading-how-to-change-table-range-in-excel-and-google-sheets">How to Change Table Range in Excel and Google Sheets</h2>
<p>What if we want to extend our table or remove data from it? Both Google Sheets and Excel allow us to do this easily.</p>
<p>Say we want to add a column for the full name of a person. In both programs, if we simply type in <code>full_name</code> in G1 to the right of our last column, that column will become a part of the table's data range.</p>
<p>Anytime we type in an adjacent column or row to our table data, the programs will assume the table needs to extend to include it.</p>
<p>Then, we can use a version of the formula from our previous example to insert the full names. Now that we are inside of the table, though, it's not necessary to include the title of the table in our formula.</p>
<p>Now, all that's needed in Excel is <code>=[@[first_name]]&amp;" "&amp;[@[last_name]]</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-119.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reference table columns in Excel</em></p>
<p>For Google Sheets, it's the same inside the table as outside it: <code>=Table2[first]&amp;" "&amp;Table2[last]</code>. Sheets also requires us to drag the formula down. It does not handle spilling like Excel (yet).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-118.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reference table columns in Sheets</em></p>
<p>To add columns within a table, we can right click the column name and select insert.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-120.png" alt="Image" width="600" height="400" loading="lazy">
<em>Insert column in Excel</em></p>
<p>Google has a slight edge here in that you can select whether to insert to the left or the right, whereby Excel only inserts to the left.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-121.png" alt="Image" width="600" height="400" loading="lazy">
<em>Insert column Google Sheets</em></p>
<p>Inserting rows is exactly the same. Excel allows for inserting rows above, while Sheets allows you to select above or below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-122.png" alt="Image" width="600" height="400" loading="lazy">
<em>Inserting rows Google Sheets</em></p>
<p>In both programs, deleting rows and columns is as simple as selecting the row(s) or column(s), right clicking, and selecting delete.</p>
<p>In Excel you have the added benefit of a keyboard shortcut. <code>CTRL + -</code> will delete the selected rows or columns.</p>
<p>Both programs will also allow you to convert a table back to a regular data range. In Excel, it's the <code>Convert to Range</code> button in the <code>Table Design</code> tab of the menu</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/convert.png" alt="Image" width="600" height="400" loading="lazy">
<em>Convert to Range option in Excel</em></p>
<p>And in Google Sheets, it's the <code>Revert to unformatted data</code> option from the table dropdown menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/revert.png" alt="Image" width="600" height="400" loading="lazy">
<em>Revert to unformatted data option in Sheets</em></p>
<p><strong>⭐Winner: TIE</strong></p>
<h2 id="heading-how-to-add-a-total-row-in-a-table">How to Add a Total Row in a Table</h2>
<p>There's a good chance you'll want to total up the amounts in a column. How easy is this to add in a table?</p>
<p>You can do it in both programs, but...</p>
<p>Excel makes it incredibly easy. There's a toggle option for this in the Table Design menu in the Ribbon. Toggle this on, and a Total row is automatically included and calculated at the bottom.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/total-row.png" alt="Image" width="600" height="400" loading="lazy">
<em>Total row in Excel</em></p>
<p>Can you do the same in Sheets? </p>
<p>Yes, you've just got to do it yourself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-124.png" alt="Image" width="600" height="400" loading="lazy">
<em>Total row in Sheets</em></p>
<p><strong>⭐Winner: EXCEL</strong></p>
<h2 id="heading-who-wins">Who Wins?</h2>
<p>Well, it's no surprise that Excel comes out on top. Sheets users (myself included) have a lot to be excited about with the ability to finally create proper tables. By and large, the functionality is just as powerful as Excel. </p>
<p>And much like many features compared between the two programs, Sheets can probably get the job done for most use cases.</p>
<p>Excel, as per normal, simply does more and does it a little bit better.</p>
<p>I'm Eamonn, and I'll help you <strong>get good at spreadsheets</strong>. Join my free newsletter, <a target="_blank" href="https://www.gotsheet.xyz/subscribe">Got Sheet, here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Pop-up Image in Your Spreadsheet ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I'll show you two ways to create a lightbox effect in a spreadsheet. The first will trigger the image to be displayed in a large area in the sheet. The second will be an actual HTML popup on top of the sheet. If you want to follow ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-an-image-lightbox/</link>
                <guid isPermaLink="false">66b8de0647c23b7ae1ad0bc0</guid>
                
                    <category>
                        <![CDATA[ google apps script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 16 May 2024 10:17:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/Lightbox-2-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I'll show you two ways to create a lightbox effect in a spreadsheet. The first will trigger the image to be displayed in a large area in the sheet. The second will be an actual HTML popup on top of the sheet.</p>
<p>If you want to follow along with the sheet I used, you can access it <a target="_blank" href="https://docs.google.com/spreadsheets/d/1Uz9sZJW1ts_YZc2-Ifd-UAQ8Pkgn23XLzmNdE_sDYrg/copy">here</a>. The link will prompt you to create a copy of the spreadsheet and accompanying Apps Script file.</p>
<h2 id="heading-what-is-an-image-lightbox">What is an Image Lightbox?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-35.png" alt="Image" width="600" height="400" loading="lazy">
<em>image thumbnails in a spreadsheet</em></p>
<p>An image lightbox is what we call it when we hover over or click on an image and it pops up into a bigger version on-screen.</p>
<p>It’s something we’re used to seeing on websites, and it gives things a nice, professional touch when done well.</p>
<p>What about in a spreadsheet, though? 🤔</p>
<p>Well, we’ve got two versions of a solution:</p>
<ol>
<li>Using built-in functions to display a larger version in a larger cell.</li>
<li>Using Apps Script to actually create a popup box on top of our spreadsheet.</li>
</ol>
<p>As a bonus to the first solution, we’ll also include optional Apps Script to make things a little smoother. More on that below 😉.</p>
<p>As usual, here's a walkthrough video where I go through the whole process:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/J39nMbuycEk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-image-popup-with-built-in-functions">Image Popup With Built-In Functions</h2>
<p>First, we need images in cells. From the top menu, <code>Insert - Image - Insert image in cell</code> will do the trick for this.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-37.png" alt="Image" width="600" height="400" loading="lazy">
<em>inserting image in spreadsheet cell</em></p>
<p>Next, we need to merge some cells together so that there’s a larger container that will hold our larger picture after the next step.</p>
<p>You can use one cell and change the width and height of it, but in my <a target="_blank" href="https://docs.google.com/spreadsheets/d/1Uz9sZJW1ts_YZc2-Ifd-UAQ8Pkgn23XLzmNdE_sDYrg/copy">example sheet</a>, the “lightbox” area is sharing rows with the rest of the data so I didn’t want to do that.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-38.png" alt="Image" width="600" height="400" loading="lazy">
<em>a large range of merged cells</em></p>
<p>In the column next to my image thumbnails, I’ve put checkboxes by selecting <code>Data - Data validation - Criteria: Checkboxes</code> from the top menu.</p>
<p>This will let us select which image to popup in our lightbox area.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-39.png" alt="Image" width="600" height="400" loading="lazy">
<em>data validation in google sheets</em></p>
<p>I’ve named the range <code>A2:A11</code> as <code>pics</code> and the range <code>B2:B11</code> as <code>checkboxes</code> to allow for easier readability in the function we’ll write next.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-41.png" alt="Image" width="600" height="400" loading="lazy">
<em>named ranges in google sheets</em></p>
<p>Now all that remains is one <code>XLOOKUP()</code> function to put inside our lightbox range.</p>
<p><code>=XLOOKUP(TRUE,checkboxes,pics,"")</code> is the function that searches for a check and then displays the corresponding image. By putting this in a big cell or range of merged cells, we can display whichever small image we select in the bigger area.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-40.png" alt="Image" width="600" height="400" loading="lazy">
<em>xlookup function in google sheets</em></p>
<p>Remember, all a checkbox is doing is storing either a <code>TRUE</code> (checked) or a <code>FALSE</code> (unchecked) value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>checkboxes and image thumbnails in google sheets</em></p>
<h2 id="heading-warning">⚠️WARNING⚠️</h2>
<p>This does have one issue, though. Do you know what it is?</p>
<p><code>XLOOKUP()</code> is going to return whichever checkboxes it comes to first with a TRUE value. So if you have multiple images checked, it’s only going to display the <em>first one it gets to</em>, not the most <em>recently clicked</em> one.</p>
<p>To get around this, let’s write some code.</p>
<h2 id="heading-apps-script-improvement">Apps Script Improvement</h2>
<p>Open up Apps Script by selecting <code>Extensions - Apps Script</code> from the top menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>opening apps script in google sheets</em></p>
<p>Delete the built-in function in the code editor that opens. We'll start from scratch with an <code>onEdit</code> function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onEdit</span>(<span class="hljs-params">e</span>) </span>{
</code></pre>
<p>We need to grab the range that we are currently editing.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> range = e.range
</code></pre>
<p>Then the checkboxes range.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> checkboxes = SpreadsheetApp.getActive().getRangeByName(<span class="hljs-string">"checkboxes"</span>)
</code></pre>
<p>Then we need to check whether what we just edited is in that checkbox range.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (range.getColumn() == <span class="hljs-number">2</span> &amp;&amp; range.getRow() &gt;= <span class="hljs-number">2</span> &amp;&amp; range.getRow() &lt;= <span class="hljs-number">10</span>)
</code></pre>
<p>If it was a checkbox, then we want to uncheck all the checkboxes and re-check the one we just checked.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Uncheck all other checkboxes in the range</span>
checkboxes.uncheck();
<span class="hljs-comment">// Check the edited cell</span>
range.check();
</code></pre>
<p>Now, there is a slight delay when you run the code. After clicking a checkbox, all of them are cleared right before the one you checked gets checked again.</p>
<p>Here’s what the full code looks like:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onEdit</span>(<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">var</span> range = e.range;
  <span class="hljs-keyword">var</span> checkboxes = SpreadsheetApp.getActive().getRangeByName(<span class="hljs-string">"checkboxes"</span>)

  <span class="hljs-comment">// Check if the edited cell is a checkbox in the desired range</span>
  <span class="hljs-keyword">if</span> (range.getColumn() == <span class="hljs-number">2</span> &amp;&amp; range.getRow() &gt;= <span class="hljs-number">2</span> &amp;&amp; range.getRow() &lt;= <span class="hljs-number">10</span>) {
    <span class="hljs-comment">// Uncheck all other checkboxes in the range</span>
    checkboxes.uncheck();
    <span class="hljs-comment">// Check the edited cell</span>
    range.check();
  }
}
</code></pre>
<h2 id="heading-a-real-popup-box-with-html">A Real Popup Box with HTML</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>modal dialog box in google sheets</em></p>
<p>Okay, that’s all fine and dandy. What about the real thing, though?</p>
<p>This takes more Apps Script, but it’s doable thanks to the built-in <code>howModalDialog</code> method.</p>
<p>This is basically a popup window that can hold HTML. And since the internet is built with HTML, all we need to do is use a little bit to plug in an image.</p>
<p>This method requires an image live on the internet somewhere. So, we cannot reference the image that we've embedded in our sheet and use it in the HTML we're going to write.</p>
<p>Weird, I know.</p>
<p>Let’s find an image URL we can use. I’ve grabbed an eagle off of <a target="_blank" href="https://unsplash.com/">unsplash</a>.</p>
<p>We’ll hold this in a variable.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> imageURL = <span class="hljs-string">"https://images.unsplash.com/photo-1715002383611-63488b956401?q=80&amp;w=1887&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"</span>
</code></pre>
<p>Then we need to build our HTML. In our case, all we want is one element, so we won’t worry ourself with constructing a full, semantically correct page (although we certainly could 😉)</p>
<p>Another variable will hold this <code>img</code> element:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> html = <span class="hljs-string">'&lt;img src="'</span> + imageURL + <span class="hljs-string">'" style="max-width: 100%; max-height: 100%;"&gt;'</span>;
</code></pre>
<p>We have access to <a target="_blank" href="https://developers.google.com/apps-script/reference/base/ui">Class Ui</a> in Apps Script where we can “…add features like menus, dialogs, and sidebars.”</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">var</span> ui = SpreadsheetApp.getUi();
</code></pre>
<p>And finally, by calling the <code>showModalDialog()</code> method, we can generate HTML from our <code>html</code> variable using the <a target="_blank" href="https://developers.google.com/apps-script/reference/html/html-service">Class HtmlService</a>.</p>
<pre><code class="lang-javascript">ui.showModalDialog(HtmlService.createHtmlOutput(html).setWidth(<span class="hljs-number">700</span>).setHeight(<span class="hljs-number">1000</span>), <span class="hljs-string">'Eagle 🦅'</span>);
</code></pre>
<p>A final touch is to add a thumbnail version of our eagle image into our spreadsheet so that it is inserted on top of our cells (this next bit won’t work if it’s embedded in a cell itself).</p>
<p>Once it’s in our sheet, we can click the three black dots in the top right corner and assign a script directly to the image.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-44.png" alt="Image" width="600" height="400" loading="lazy">
<em>assigning a script to image in google sheets</em></p>
<p>We named our script <code>displayImagePopup</code>, so this is what we enter. Make sure to leave off the parentheses when typing it into the image's script form.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/image-45.png" alt="Image" width="600" height="400" loading="lazy">
<em>assigning script</em></p>
<p>Now, anytime we click the small image of the eagle, a popup box opens with the full image.</p>
<p>Here’s what the full code looks like:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayImagePopup</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Get the active sheet</span>
  <span class="hljs-keyword">var</span> sheet = SpreadsheetApp.getActiveSheet();
  <span class="hljs-keyword">var</span> imageURL = <span class="hljs-string">"https://images.unsplash.com/photo-1715002383611-63488b956401?q=80&amp;w=1887&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"</span>
  <span class="hljs-comment">// Create an HTML string for the popup</span>
  <span class="hljs-keyword">var</span> html = <span class="hljs-string">'&lt;img src="'</span> + imageURL + <span class="hljs-string">'" style="max-width: 100%; max-height: 100%;"&gt;'</span>;

  <span class="hljs-comment">// Show the dialog</span>
  <span class="hljs-keyword">var</span> ui = SpreadsheetApp.getUi();
  ui.showModalDialog(HtmlService.createHtmlOutput(html).setWidth(<span class="hljs-number">700</span>).setHeight(<span class="hljs-number">1000</span>), <span class="hljs-string">'Eagle 🦅'</span>);
}
</code></pre>
<h2 id="heading-thank-you-so-much">Thank you so much!</h2>
<p>I hope this was helpful for you. </p>
<p>Check out my <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube channel</a> and <a target="_blank" href="https://www.gotsheet.xyz/subscribe">free newsletter</a> to get good at spreadsheets!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Advanced Google Sheets Concepts – How to Build a Vigenère Cipher ]]>
                </title>
                <description>
                    <![CDATA[ A Vigenère Cipher encrypts and decrypts text using a different alphabet for each letter. It consists of text to encrypt and a key with a different letter corresponding to each letter in the text.  Creating a grid of alphabets helps illustrate this pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/advanced-google-sheets-concepts-build-a-vigenere-cipher/</link>
                <guid isPermaLink="false">66b8ddc90a89d796f29a16d9</guid>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Wed, 13 Dec 2023 18:13:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/2cipher.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A Vigenère Cipher encrypts and decrypts text using a different alphabet for each letter. It consists of text to encrypt and a key with a different letter corresponding to each letter in the text. </p>
<p>Creating a grid of alphabets helps illustrate this practice. If the first letter in your text is <code>A</code> and the first letter in your key is <code>L</code>, you would find the encrypted letter, <code>L</code>, where the plaintext and key intersect:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/cipher2.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of a grid of alphabets</em></p>
<p>So your text to encrypt might look like this: <code>attackatdawn</code>, your key might be this: <code>LEMONLEMONLE</code>, and the ciphertext would be this: <code>LXFOPVEFRNHR</code>.</p>
<p>This is the same example used on the <a target="_blank" href="https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher">Wikipedia page</a> which I'll walk you through in this article.</p>
<p>You could create a cipher encoder/decoder with any number of programming languages. But spreadsheets are a nice tool to use for this kind of project because they come with some pretty robust built-in functions that will help us dissect the cipher. </p>
<p>I've chosen Google Sheets because it's a hair simpler to jump into, especially if you already have a Gmail account. But you can do all the same things in Microsoft Excel.</p>
<p>Here's the <a target="_blank" href="https://docs.google.com/spreadsheets/d/1i_auliGPhTOIOk3WrsIRuHveXyEdQxi16BcvSBo6MTA/edit#gid=1257498594">Google Sheet I used</a>.</p>
<p>If you'd like to check out a video walkthrough, here you go 👇</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/dM_Ims4KnVc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-spreadsheet-preparation">Spreadsheet Preparation</h2>
<p>This isn't too complicated. We need a grid of alphabets. No, you don't have to type them in over and over, either.</p>
<p>In fact, you don't even have to type the whole first alphabet. Let's use Unicode characters. For capital letters, the Unicode for the alphabet starts with 65. </p>
<p>The <code>CHAR()</code> function in spreadsheets converts a number into a character according to the current Unicode table.</p>
<p>The <code>COLUMN()</code> function returns a number corresponding to the current column where column A returns 1, column B returns 2, and so on. </p>
<p>So if we start our alphabet in column B, we can access each letter by adding 63 to the <code>COLUMN()</code> function and wrapping it in the <code>CHAR()</code> function:</p>
<pre><code>=CHAR(COLUMN()+<span class="hljs-number">63</span>)
</code></pre><p>Then we can drag this over to the right until we've got the full alphabet.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-41.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of CHAR and COLUMN functions</em></p>
<p>The same thing applies going down. We'll just use the <code>ROW()</code> function instead:</p>
<pre><code>=CHAR(ROW()+<span class="hljs-number">63</span>)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of CHAR and ROW functions</em></p>
<p>Then we can reference the cell above and to the right for every cell below to fill out the full alphabet grid:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of spreadsheet cell</em></p>
<p>The only one that will be different will be in the last column where we'll need to reference the first column to have the alphabet wrap:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-44.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of spreadsheet cell</em></p>
<p>We only have to do this on the second line. Then, select the full second row and drag the formulas down to fill out the grid:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/drag.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of spreadsheet grid</em></p>
<p>At this point, you can copy <code>CTRL + C</code> and paste values only <code>CTRL + SHIFT + V</code> for all the alphabet. If you add or shift rows, the alphabets may get skewed since their formulas reference fixed columns.</p>
<h2 id="heading-the-game-plan">The Game Plan</h2>
<p>Now the fun stuff. We want our text to be encrypted automatically. Let's highlight three cells: one for the text to encrypt, one for a key, and then a blank cell for our encrypted text:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of text to encrypt</em></p>
<p>Note: the key needs to be the same length as the text to encrypt/decrypt. In this example, the key is the word LEMON, but we extend it by repeating it for every character we need to encrypt.</p>
<p>Now we need to do three things: </p>
<ol>
<li>Split out each character of our text into its own cell</li>
<li>Loop through each character and encrypt it based on the corresponding key character.</li>
<li>Join all those characters together and place the result in our encrypted text cell.</li>
</ol>
<h2 id="heading-split-text-to-setup">Split Text to Setup</h2>
<p>Interestingly, we cannot use the <code>SPLIT()</code> - or if you're in Excel, the <code>TEXTSPLIT()</code> - function without a delimiter. That is, we can't just tell it to split each character without there being something in between the characters.</p>
<p>So, we have to get fancy. In the video walkthrough, I explore a Google Sheets-specific approach using regular expressions...which are hard fun.</p>
<p>Here's what it looks like, and it involves creating character groups, inserting something in between each one, and then splitting using that same something as the delimiter. I used a blank space as the thing which I inserted and then split by:</p>
<pre><code>=SPLIT(REGEXREPLACE(AG6,<span class="hljs-string">"(.)"</span>,<span class="hljs-string">"$1 "</span>),<span class="hljs-string">" "</span>)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/hard.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of woman saying, that's just hard</em></p>
<p>Excel users and mortals, fear not – there's a more elegant way that I'll show you here that can be done in either program by using the <code>MID()</code> and <code>COLUMNS()</code> functions.</p>
<p>The <code>MID()</code> function extracts a segment of a string, and <code>COLUMNS()</code> returns the number of columns in an array. By nesting <code>COLUMNS()</code> inside <code>MID()</code> we can one by one extract each character from the string:</p>
<pre><code>=MID($AG$<span class="hljs-number">6</span>,COLUMNS($AG6:AG6),<span class="hljs-number">1</span>)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-47.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of MID and COLUMNS functions</em></p>
<p>By locking <code>$AG6</code> as the first part of the array referenced in the <code>COLUMNS()</code>  function, this number adds one for every column we drag our formula over.</p>
<p>Drag this over until you reach the end of the text to encrypt. Every character should be in its own cell now. Do the same for the key.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-48.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of spreadsheet cells</em></p>
<h2 id="heading-how-to-use-xlookup-to-encrypt">How to Use <code>XLOOKUP()</code> to Encrypt</h2>
<p>Below each pairing of plaintext and key text, we will now do a double <code>XLOOKUP()</code>. </p>
<p>Yes, it's as awesome as it sounds.</p>
<p>Here's what it looks like, and let's walkthrough what's happening:</p>
<pre><code>=XLOOKUP(AD9,<span class="hljs-attr">$B$2</span>:$B$<span class="hljs-number">27</span>,XLOOKUP(AD10,<span class="hljs-attr">$B$2</span>:$AA$<span class="hljs-number">2</span>,<span class="hljs-attr">$B$2</span>:$AA$<span class="hljs-number">27</span>))
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-49.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of double XLOOKUP functions</em></p>
<p>For the beginning <code>XLOOKUP()</code>, we are looking up the plaintext and we're referencing the first plaintext alphabet for our lookup range. But then for our result range, we're opening up another <code>XLOOKUP()</code>...</p>
<p>This is because we still have to use the correct key alphabet to return an encrypted value.</p>
<p>So, we need the second <code>XLOOKUP()</code> to return a full alphabet based on the position of the key character.</p>
<p>We're using the key character as our lookup value, we're using the first alphabet along the top key row for our lookup range, and then we're returning the whole grid as our result range. This will let us return a full alphabet which is in turn referenced as the result range for our first <code>XLOOKUP()</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/12/cipher3.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of alphabet grid and XLOOKUP example</em></p>
<p>You can see the second <code>XLOOKUP()</code> by itself in the picture above. The formula is in the top left. We're using the first letter of key text as the lookup value. The lookup range is the top alphabet in the purple box. The result range is the whole grid in the blue box. And the returned alphabet is the one that starts with L in the red box.</p>
<p>You can see it being returned underneath the formula where there is an arrow in the picture.</p>
<p>Drag the double <code>XLOOKUP()</code> function over to encrypt every character of the plaintext with the key text.</p>
<h2 id="heading-join-text-for-final-solution">Join Text for Final Solution</h2>
<p>Now that we've encrypted each letter, we want them to be joined into one string and returned in our encrypted text cell.</p>
<p>To do this, we can use the <code>JOIN()</code> function - or <code>TEXTJOIN()</code> for Excel - with an empty quote as the delimiter. </p>
<pre><code>=JOIN(<span class="hljs-string">""</span>,<span class="hljs-attr">AD11</span>:AO11)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-50.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of JOIN function</em></p>
<p>And voilà! We've just encrypted a string using a double <code>XLOOKUP()</code>.</p>
<h2 id="heading-how-to-decrypt-text">How to Decrypt Text</h2>
<p>Decryption works exactly the same. The only difference is the placement of the second <code>XLOOKUP()</code>. Instead of using it as the result range, we're using it as the lookup range:</p>
<pre><code>=XLOOKUP(AD20,XLOOKUP(AD21,<span class="hljs-attr">$B$2</span>:$AA$<span class="hljs-number">2</span>,<span class="hljs-attr">$B$2</span>:$AA$<span class="hljs-number">27</span>),<span class="hljs-attr">$B$2</span>:$B$<span class="hljs-number">27</span>)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/12/image-51.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of decryption double XLOOKUP example</em></p>
<h2 id="heading-thanks-for-reading">Thanks for reading</h2>
<p>I hope this was helpful for you and that you learned something new!</p>
<p>You can find more of my tutorials on <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube</a>, and please sign up for my newsletter about <a target="_blank" href="https://got-sheet.beehiiv.com/">coding and spreadsheets here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create HTML Accordion Elements With and Without JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Accordion elements are very handy for displaying topic titles and expandable details below them when you click the title. In this article, I'll walk you through creating an FAQ section with some expandable accordion elements. I'll show you how to do ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-html-accordions-with-and-without-javascript/</link>
                <guid isPermaLink="false">66b8ddd10a89d796f29a16db</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 30 Nov 2023 19:10:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/accordion-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Accordion elements are very handy for displaying topic titles and expandable details below them when you click the title.</p>
<p>In this article, I'll walk you through creating an FAQ section with some expandable accordion elements.</p>
<p>I'll show you how to do this without any JavaScript, and then we'll add a bit of JavaScript to make it even better.</p>
<p>I've also made a video tutorial of the whole process here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/NYleh6wzDRE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-make-an-accordion-using">How to Make an Accordion Using <details></details></h2>
<p>HTML has a disclosure element called <code>&lt;details&gt;</code> that can be in one of two states: open and closed. When opened, the information within the element is displayed. When closed, only the <code>&lt;summary&gt;</code> information is displayed.</p>
<p>This is an extremely easy version of the "accordion", although it's arguably not a true accordion by itself. When using <code>&lt;details&gt;</code>, more than one of the panels may be open at any one time – and because there's no JavaScript yet, panels will remain open until you click them again to close them.</p>
<p>Still, this is a quick and easy way to get an accordion-like element up and running. If you only need a few and aren't picky about functionality, this may be all you're looking for.</p>
<p>Here's what a basic example looks like. The <code>&lt;summary&gt;</code> is visible until clicked, at which point the rest of the content is displayed below it.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- With just &lt;details&gt; --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Accordion using details<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span> <span class="hljs-attr">open</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>Who is Eamonn?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        A guy from TN who makes content on the internet.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>What kind of content does he make?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        He focuses on productivity tips using coding and spreadsheets. He makes <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://youtube.com/@eamonncottrell"</span>&gt;</span>YouTube<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> videos and writes articles on freeCodeCamp, <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.linkedin.com/in/eamonncottrell/"</span>&gt;</span>LinkedIn<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> and his <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://got-sheet.beehiiv.com/"</span>&gt;</span>personal newsletter<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>What does he do for fun?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        Hangs out with his wife and four kids, and runs ultramarathons.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>We can also have the first details panel open by default by simply including the open command: <code>&lt;details open&gt;</code>. </p>
<p>Here's what that will look like with only a sprinkling of CSS:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-92.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of HTML accordion made with &lt;details&gt; only</em></p>
<p>This is a great start, but we can go further. A little bit of JavaScript will go a long way👇</p>
<h2 id="heading-how-to-add-javascript-to-an-accordion-element">How to Add JavaScript to an Accordion Element</h2>
<p>Let's make another section with three more <code>&lt;details&gt;</code> elements. And let's add a <code>class = "withJS"</code> to each one so we can do some different things to them for comparison's sake.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- With JavaScript --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Accordion with some JavaScript added<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span>  <span class="hljs-attr">open</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>What's the difference?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        We're adding JavaScript to these three.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span> &gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>Why add JavaScript?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        We can make it so only one panel can be open at a time.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">details</span> &gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>Try clicking each of these<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
        See how one closes as soon as the other opens?.
    <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>To keep things tidy and in one file, we can add a <code>&lt;script&gt;</code> tag at the bottom of our <code>&lt;body&gt;</code>. </p>
<p>First, select all of the summary elements with the <code>.withJS</code> class by using <code>document.querySelectorAll()</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> summaries = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".withJS"</span>)
</code></pre>
<p>Then add a click event listener to each of them:</p>
<pre><code class="lang-javascript">summaries.forEach(<span class="hljs-function"><span class="hljs-params">e</span>=&gt;</span>{
    e.addEventListener(<span class="hljs-string">'click'</span>,openCloseDetails)
})
</code></pre>
<p>This will run the function <code>openCloseDetails</code> every time one of these summary elements is clicked.</p>
<p>It won't do anything except give us an error until we declare that function, though...so, let's do that next.</p>
<p>Within the <code>&lt;script&gt;</code> after the <code>forEach</code> loop, let's have the <code>openCloseDetails()</code> function loop through those summaries again. This time, we want to modify the <code>open</code> status on the <code>&lt;details&gt;</code> element.</p>
<p>Remember how we have this setup: The first <code>&lt;details&gt;</code> element is set to <code>open</code> by default, and the others are closed.</p>
<p>We need a way to toggle the clicked element from open to closed, and close any previously <code>open</code> element when we click a new one.</p>
<p>To do this, we'll set a variable for the <code>&lt;details&gt;</code> element of each of the <code>&lt;summary&gt;</code> elements by setting it equal to <code>e.parentNode</code> in the <code>forEach</code> loop. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> details = e.parentNode;
</code></pre>
<p>The parentNode is the element directly preceding the current element. Since the <code>&lt;summary&gt;</code> elements are within the <code>&lt;details&gt;</code> elements, the <code>parentNode</code> for the <code>&lt;summary&gt;</code> elements will be the <code>&lt;details&gt;</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/clearly.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of woman saying, "clearly"</em></p>
<p>From there, we check if that <code>&lt;details&gt;</code> is NOT <code>this.parentNode</code>. If it's not, then we'll remove the <code>open</code> attribute.</p>
<p>The native functionality of the <code>&lt;details&gt;</code> elements will open the clicked one, we just needed to make sure all the other ones close.</p>
<p>Here's the code. It's not complicated, but it may take a second to wrap your head around the logic:</p>
<pre><code class="lang-javascript">summaries.forEach(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span>{
    <span class="hljs-keyword">let</span> details = e.parentNode;
    <span class="hljs-keyword">if</span>(details != <span class="hljs-built_in">this</span>.parentNode){
        details.removeAttribute(<span class="hljs-string">'open'</span>)
    }
</code></pre>
<p>And that's it. Now when we click each <code>&lt;details&gt;</code> the other ones automatically close:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/accordion-gif.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of html accordion in action</em></p>
<p>Here is the entire HTML file for your reference:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Accordion<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
        <span class="hljs-selector-tag">body</span>{
            <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">230</span>);
            <span class="hljs-attribute">color</span>: <span class="hljs-number">#444</span>;
        }
        <span class="hljs-selector-tag">details</span>{
            <span class="hljs-attribute">font-family</span>:<span class="hljs-string">'Trebuchet MS'</span>, <span class="hljs-string">'Lucida Sans Unicode'</span>, <span class="hljs-string">'Lucida Grande'</span>, <span class="hljs-string">'Lucida Sans'</span>, Arial, sans-serif;
            <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">5px</span>;
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5em</span> <span class="hljs-number">0.5em</span> <span class="hljs-number">0</span>;
        }
        <span class="hljs-selector-tag">details</span><span class="hljs-selector-attr">[open]</span>{
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5em</span>;
        }
        <span class="hljs-selector-tag">summary</span>{
            <span class="hljs-attribute">font-weight</span>: bold;
            <span class="hljs-attribute">margin</span>: -<span class="hljs-number">0.5em</span> -<span class="hljs-number">0.5em</span> <span class="hljs-number">0</span>;
            <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5em</span>;
            <span class="hljs-attribute">cursor</span>: pointer;
        }
        <span class="hljs-selector-tag">details</span><span class="hljs-selector-attr">[open]</span> <span class="hljs-selector-tag">summary</span>{
            <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0.5em</span>;
        }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Accordions<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- With just &lt;details&gt; --&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Accordion using details<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span> <span class="hljs-attr">open</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>Who is Eamonn?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            A guy from TN who makes content on the internet.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>What kind of content does he make?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            He focuses on productivity tips using coding and spreadsheets. He makes <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://youtube.com/@eamonncottrell"</span>&gt;</span>YouTube<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> videos and writes articles on freeCodeCamp, <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.linkedin.com/in/eamonncottrell/"</span>&gt;</span>LinkedIn<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> and his <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://got-sheet.beehiiv.com/"</span>&gt;</span>personal newsletter<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span>&gt;</span>What does he do for fun?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            Hangs out with his wife and four kids, and runs ultramarathons.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>


    <span class="hljs-comment">&lt;!-- With JavaScript --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Accordion with some JavaScript added<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span>  <span class="hljs-attr">open</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>What's the difference?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            We're adding JavaScript to these three.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span> &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>Why add JavaScript?<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            We can make it so only one panel can be open at a time.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">details</span> &gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">summary</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"withJS"</span>&gt;</span>Try clicking each of these<span class="hljs-tag">&lt;/<span class="hljs-name">summary</span>&gt;</span>
            See how one closes as soon as the other opens?.
        <span class="hljs-tag">&lt;/<span class="hljs-name">details</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
        <span class="hljs-keyword">const</span> summaries = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">`.withJS`</span>)
        summaries.forEach(<span class="hljs-function"><span class="hljs-params">e</span>=&gt;</span>{
            e.addEventListener(<span class="hljs-string">'click'</span>,openCloseDetails)
        })

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">openCloseDetails</span>(<span class="hljs-params"></span>)</span>{
            summaries.forEach(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span>{
                <span class="hljs-keyword">let</span> details = e.parentNode;
                <span class="hljs-keyword">if</span>(details != <span class="hljs-built_in">this</span>.parentNode){
                details.removeAttribute(<span class="hljs-string">'open'</span>)
            }
            })
        }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h2 id="heading-thanks-for-reading">Thanks for Reading</h2>
<p>I hope this was useful for you!</p>
<p>Come follow me on YouTube: <a target="_blank" href="https://www.youtube.com/@eamonncottrell">https://www.youtube.com/@eamonncottrell</a> </p>
<p>And sign up for my coding &amp; spreadsheet newsletter: <a target="_blank" href="https://got-sheet.beehiiv.com/">https://got-sheet.beehiiv.com/</a></p>
<p>Have a great one!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Numbers in Excel ]]>
                </title>
                <description>
                    <![CDATA[ Did you know you can write Python code in a spreadsheet? You'd be surprised how many different ways there are to do things in Excel. Below, I'll show you 9 ways to add two or more numbers. You can skip to a certain section if you'd like to see that ]]>
                </description>
                <link>https://www.freecodecamp.org/news/add-numbers-in-excel/</link>
                <guid isPermaLink="false">66b8ddc62755c964523f056c</guid>
                
                    <category>
                        <![CDATA[ excel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Math ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 12 Oct 2023 21:02:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/add-numbers-thumb-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Did you know you can write Python code in a spreadsheet?</p>
<p>You'd be surprised how many different ways there are to do things in Excel. Below, I'll show you 9 ways to add two or more numbers. You can skip to a certain section if you'd like to see that method:</p>
<ol>
<li><a class="post-section-overview" href="#">Manual</a></li>
<li><a class="post-section-overview" href="#-1">References</a></li>
<li><a class="post-section-overview" href="#-2">SUM()</a></li>
<li><a class="post-section-overview" href="#-3">SUMIF()</a></li>
<li><a class="post-section-overview" href="#-4">SUBTOTAL()</a></li>
<li><a class="post-section-overview" href="#-5">AGGREGATE()</a></li>
<li><a class="post-section-overview" href="#-6">VBA</a></li>
<li><a class="post-section-overview" href="#-7">Python</a></li>
<li><a class="post-section-overview" href="#-8">Highlight</a></li>
</ol>
<h2 id="heading-video-walkthrough">Video Walkthrough</h2>
<p>If you prefer to watch me go through each of these in a demo workbook, here's a video for that:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/xe5Ohlgizi8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>To write a formula or a function in Excel (which we'll be doing in the examples below), start out by simply typing an equals sign in a cell.</p>
<p><code>=</code></p>
<p>This triggers Excel to know that what follows will be a formula or a built-in function.</p>
<p><a id="manual"></a></p>
<h2 id="heading-manual">Manual</h2>
<p>This is simplest version of a formula in Excel. Start out with the equals sign, and then type in the numbers and operation you want to do. Just like a calculator:</p>
<p><code>=6+102</code></p>
<p>Pressing enter will result in <code>108</code> being listed in the cell</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-30.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of manual addition in Excel</em></p>
<p><a id="reference"></a></p>
<h2 id="heading-references">References</h2>
<p>The next step up in Excel is to start using cell references. Notice that on the top and on the left side of the main spreadsheet area, there are columns designated by letters and rows designated by numbers.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/rowscolumns.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of rows and columns</em></p>
<p>We can refer to specific cells using "A1" notation. Like a set of (x,y) coordinates on a graph, this simply means that by referring to C4, for instance, we are referring to the cell found in column C, row 4.</p>
<p>To add numbers using references, we start again with the equals sign and refer to the values in specific cells directly.</p>
<p>This has the added advantage of being dynamic. If a value is changed in one of the cells, the result of the sum automatically updates.</p>
<p><code>=SUM(A1+A3)</code> provides us with the value of the numbers in <code>A1</code> and <code>A3</code>.</p>
<p><a id="sum"></a></p>
<h2 id="heading-sum">SUM()</h2>
<p>The first two methods are examples of using formulas. We manually give Excel a series of instructions that it executes. </p>
<p>Excel also has built-in functions which we can use by starting with the equals sign and then referring to the function by name. Functions also take variables which we pass to them by using a set of parenthesis after the name of the function.</p>
<p>The <code>SUM()</code> function takes either a range or a comma-separated list of cell references. It then returns the sum of all the numbers in the range. </p>
<p>You can select a range by either clicking and dragging or by declaring one by typing in the A1 notation with a colon in between the top left cell and the bottom right cell of the range.</p>
<p><code>SUM(A5:A11)</code> adds all the numbers in cells <code>A5, A6, A7, A8, A9, A10, A11</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-31.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of the SUM() function</em></p>
<p><a id="sumif"></a></p>
<h2 id="heading-sumif">SUMIF()</h2>
<p>A more powerful version of <code>SUM()</code> is the <code>SUMIF()</code> function. This adds conditional logic. It needs at least two variables: a range and a condition. We could give it the same range as above and have a condition be that it only adds up numbers that are greater than zero.</p>
<p>A third, optional variable is a <code>sum_range</code>. This allows for us to match a condition in one range with the sum of values in another range.</p>
<p>In the example sheet, I have inserted checkboxes in column C. Checkboxes in Excel are <a target="_blank" href="https://youtu.be/hROvLovbl8E">a new feature</a>. This is the range that I'm checking for a condition. The condition is TRUE. Now I enter the range that I want to sum if the condition in the corresponding row of the first range is indeed TRUE.</p>
<p>When using a range and a sum_range separately like this, they do have to be of the same size or it will not behave as you want it to.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-32.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of SUMIF() function in Excel</em></p>
<p><a id="subtotal"></a></p>
<h2 id="heading-subtotal">SUBTOTAL()</h2>
<p>Ok, here's where things start to get interesting.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/butts.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <code>SUBTOTAL()</code> function allows us to do a ton of different things. Ultimately, it returns a subtotal of a list or database. But inside of <code>SUBTOTAL()</code> there are other functions. The first argument that we give <code>SUBTOTAL()</code> is a number corresponding to one of these functions:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-33.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of functions within SUBOTAL from Microsoft Excel</em></p>
<p>Looking at the function list, we see that 9 or 109 both correspond to the <code>SUM()</code> function which we want to use. If we have hidden rows in our range that we don't want to include in the sum, we use 109 to ignore those – if not, simply 9.</p>
<p>So the function looks like this: <code>SUBTOTAL(9,B3:B12)</code>. This sums <code>B3:B12</code> even if one or more of those rows are hidden.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-34.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of SUBTOTAL in Excel</em></p>
<p><a id="aggregate"></a></p>
<h2 id="heading-aggregate">AGGREGATE()</h2>
<p>We can think of <code>AGGREGATE()</code> as a souped-up version of <code>SUBTOTAL()</code>. It works in the same way but has a lot more built-in functions (19 of them) and allows for detailed specificity on what values, if any, to ignore in the calculation.</p>
<p><code>AGGREGATE(function_num, options, ref1, [ref2], …)</code> is the full reference formula. Again, we pass it a number corresponding to one of the 19 built-in functions, then an optional argument for what type of values to ignore, followed by the reference array and an optional second reference array.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-35.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of options for Aggregate function from Microsoft Excel</em></p>
<p>For our example, we again use 9 as our function number, but we can use option 5 to explicitly exclude hidden rows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-36.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Aggregate function in Excel</em></p>
<p><a id="vba"></a></p>
<h2 id="heading-vba">VBA</h2>
<p>Now we're warmed up. Let's get overly complicated.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/complicated.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of complicated nonsense</em></p>
<p>Visual Basic for Applications is Microsoft's baked-in programming language in Microsoft Office applications.</p>
<p>Open it up by selecting Visual Basic from the Developer tab. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/vba.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of VBA in Developer tab in Excel</em></p>
<p>If you don't see the developer tab, go to File - Options - Customize Ribbon and add it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/developer-tab.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Customizing Ribbon in Excel</em></p>
<p>Also, <code>Alt +11</code> is the keyboard shortcut to open up VBA.</p>
<p>Once here, we can write code to do all sorts of things. Our example isn't very practical since a function will do it quicker, but the following code will Sum the range <code>A1:A11</code>, put the result in <code>F11</code> and display a message pop-up with the result:</p>
<pre><code class="lang-vba">Sub AssignSumVariable()
   Dim result As Double
   'Assign the variable
   result = WorksheetFunction.Sum(Range("B1:B11"))
   'Show the result
   MsgBox "The total of the ranges is " &amp; result
   'Put the result in cell F9
  Range("F9") = result
End Sub
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-37.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of VBA in Excel</em></p>
<p><a id="python"></a></p>
<h2 id="heading-python">Python</h2>
<p>Yes, this is now ridiculous. But, it's good to know what Excel can do when you have more complicated tasks that require tools like VBA or Python. At the time of this writing, Python is available in Excel for people using the Beta Channel of Excel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/overkill.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of woman saying "seems like overkill"</em></p>
<p>You can check your eligibility and join Microsoft 365 Insider if you want to test out new features like this in the future.</p>
<p>Go to File - Account, and then select the 365 Insider channel button for more info.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-38.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Microsoft 365 Insider options</em></p>
<p>Once Python is usable in Excel, you activate it by typing <code>=py</code> and then the <code>tab</code> key. This turns the cell into a Python command line.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-39.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Python command line in Excel</em></p>
<p>From here, we can write Python code directly in the cell. The following code uses the custom xl() function for Python to use a range. We hold the range in the numbers variable and then using dot notation, we sum that range with the <code>numbers.sum()</code> line:</p>
<pre><code class="lang-python">numbers = xl(<span class="hljs-string">"'Sum➕'!$B$3:$B$12"</span>)
numbers.sum()
</code></pre>
<p>Now to execute the Python code, click <code>CTRL + ENTER</code>.</p>
<p>What we now see is that we've got a Python Series in the cell:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-40.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In order to just display the answer, we can click the Python Output selector just to the left of the formula bar and select <code>Excel Value</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/python-object.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Python Output in Excel</em></p>
<p>Now, our cell is updated with the correct value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of cells in Excel</em></p>
<p>The real value of Python in Excel comes with manipulating dataframes using built-in libraries like Matplotlib, NumPy, or Pandas.</p>
<p>Okay, take a breath, we'll finish with something simple and easy...👇</p>
<p><a id="highlight"></a></p>
<h2 id="heading-highlight">Highlight</h2>
<p>Bonus time. If you highlight cells in Excel by either clicking and dragging mouse over a range, or by <code>CTRL</code>+ <code>Left-Click</code> individual cells, some automatic calculations are visible in the bottom right of the window, including the Average, Count and Sum:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/highlight.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If the sum isn't immediately visible, right clicking will pull up auto-calculations that you can toggle on and off:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/image-29.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of auto-calculation options in Excel</em></p>
<h2 id="heading-thanks-for-reading">Thanks for reading!</h2>
<p>Hope this is helpful for you!</p>
<p>Follow me on LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/eamonncottrell/">https://www.linkedin.com/in/eamonncottrell/</a></p>
<p>And YouTube: <a target="_blank" href="https://www.youtube.com/@eamonncottrell">https://www.youtube.com/@eamonncottrell</a></p>
<p>Have a great one! 👋</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Code Dark Mode for Google Sheets with Apps Script and JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Google Sheets is a great tool for working and collaborating on spreadsheets, but it doesn't have native support for dark mode.  In this article, we'll create our own dark mode. One way to do that would be by selecting all the cells and manually chang... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-code-dark-mode-for-google-sheets/</link>
                <guid isPermaLink="false">66b8de03753e1e313e83948f</guid>
                
                    <category>
                        <![CDATA[ dark mode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google apps script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Wed, 20 Sep 2023 22:23:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/code-your-own-dark-mode.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google Sheets is a great tool for working and collaborating on spreadsheets, but it doesn't have native support for dark mode. </p>
<p>In this article, we'll create our own dark mode. One way to do that would be by selecting all the cells and manually changing their background color and font color. This will get the job done, but we can automate the process and add more style options to choose from.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/automate-2.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of cartoon character grabbing a computer</em></p>
<p>Here’s what we’ll build: a style selector that has four different styles triggered by either a new dropdown menu or by clicking a custom button icon.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/1-12.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Google Sheets with different background modes</em></p>
<p>And here's the video walkthrough if you'd like to follow along with that instead: </p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/TxSGuXPav70" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-create-dark-mode-in-apps-script">How to Create Dark Mode in Apps Script</h2>
<p>We’ll create four functions, one for each style mode. Each of our functions will do the following:</p>
<ol>
<li>Set background color</li>
<li>Set font color</li>
<li>Set font family</li>
<li>Set border color and style</li>
</ol>
<p>Let’s walk through how to create a <code>darkMode</code> function in <a target="_blank" href="https://script.google.com/home/start">Apps Script</a>. We'll define each function with the <code>function</code> keyword, followed by whatever we’ll name it.</p>
<p>Because the functions take no arguments (they just run without needing more info from us). That is, we have open and closed parentheses with nothing inside them followed by an open curly brace.</p>
<p>All of our code for the function goes between the <code>darkMode</code> function's curly braces:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">darkMode</span>(<span class="hljs-params"></span>) </span>{
  SpreadsheetApp.getActive().getRange(<span class="hljs-string">'A1:Z'</span>)
    .setBackground(<span class="hljs-string">"#333333"</span>)
    .setFontColor(<span class="hljs-string">"white"</span>)
    .setFontFamily(<span class="hljs-string">"Google Sans"</span>)
    .setBorder(<span class="hljs-literal">false</span>,<span class="hljs-literal">false</span>,<span class="hljs-literal">false</span>,<span class="hljs-literal">false</span>,<span class="hljs-literal">true</span>,
     <span class="hljs-literal">true</span>,<span class="hljs-string">"#444444"</span>,SpreadsheetApp.BorderStyle.SOLID)
}
</code></pre>
<p>To select all the cells, we used the built-in methods from the <code>SpreadsheetApp</code> class: <code>getActive()</code> and <code>getRange()</code>. These select the active sheet as well as a given range.</p>
<p>In our case, we’ll plug in <code>A1:Z</code> as the range, but you can extend this further if you’d like. For instance,  <code>A1:AZ</code>, would add columns <code>AA:AZ</code> and then apply our styling to them.</p>
<p>The four lines that follow are simply dot notation extensions telling what styles to apply. You can write this on one line if you’d like, but it’s good practice to have line breaks to make the code easy to read.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/clever.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of man saying, that’s clever</em></p>
<h2 id="heading-how-to-set-colors-and-fonts">How to Set Colors and Fonts</h2>
<p>You'd notice that we used both <code>setBackground(#333333)</code> and <code>setFontColor("white")</code> in the code. This is because we can use CSS notation colors in either hex format or by using the color’s name.</p>
<p>Using <code>setFontFamily("Google Sans")</code>, we gave it the font family name within quotations. Being a Google product, you can use any of the <a target="_blank" href="https://fonts.google.com/">Google Fonts</a> as well as Google’s own Google Sans font as I found out making this project.</p>
<h2 id="heading-how-to-set-the-border">How to set the Border</h2>
<p>The <code>setBorder(false,false,false,false,true, true,"#444444",SpreadsheetApp.BorderStyle.SOLID)</code> function let’s you enter <code>true</code> or <code>false</code> values for the top, left, bottom, right, vertical, or horizontal borders, in that order, followed by the color and style.</p>
<p>To set the style, we had to invoke a built in <a target="_blank" href="https://developers.google.com/apps-script/reference/document/attribute">Enum Attribute</a> — <code>BorderStyle</code> — to change the style of the border.</p>
<h2 id="heading-how-to-create-the-style-menu">How to Create the Style Menu</h2>
<p>To be able to select any of the styles we’re making from the actual spreadsheet, we need a menu.</p>
<p>To add the menu, we'll create a new function called  <code>onOpen()</code> that runs as soon as the spreadsheet opens and then the built-in methods from the <code>getUi()</code> to build our custom menu.</p>
<p>We can create the menu with <code>.createMenu()</code> and then add each of our functions to the menu with the <code>addItem()</code> function.</p>
<p>Here's the code:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onOpen</span>(<span class="hljs-params"></span>)</span>{
  SpreadsheetApp.getUi()
    .createMenu(<span class="hljs-string">'Style'</span>)
    .addItem(<span class="hljs-string">"Dark"</span>,<span class="hljs-string">"darkMode"</span>)
    .addItem(<span class="hljs-string">"Papyrus"</span>,<span class="hljs-string">"papyrusMode"</span>)
    .addItem(<span class="hljs-string">"Light"</span>,<span class="hljs-string">"lightMode"</span>)
    .addItem(<span class="hljs-string">"Synth"</span>,<span class="hljs-string">"synthMode"</span>)
    .addToUi();
}
</code></pre>
<p>Google Apps Script automatically integrates with Google Workspace apps (like Google Sheets) so the functions we've added in the code will make the functionalities accessible in your Google Sheets.</p>
<h2 id="heading-how-to-add-icon-buttons">How to Add Icon Buttons</h2>
<p>As a bonus, I added four icon images to the sheet, and by selecting <code>Assign script</code> we can have these icons act as buttons to trigger any of the four styles we’ve built:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of icons in spreadsheet</em></p>
<p>When you type the function name into the Assign script dialog box, make sure you do not to use parentheses. You should only enter the name of the function itself:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/3.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of assigning script to image</em></p>
<p>And bingo! We’ve got ourselves a style picker. You can add or edit these to create any number of combinations that you can easily toggle on and off in your own Google Sheet!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/4.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Synth Mode Style</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article shows how you can create can code dark, and other background modes for your Google Sheets using Apps Script and JavaScript.</p>
<p>I hope this has been useful for you!</p>
<h2 id="heading-more-resources">More Resources😄</h2>
<p>▶ Find all my video tutorials and walkthroughs on YouTube: <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">https://www.youtube.com/@eamonncottrell?sub_confirmation=1</a></p>
<p>▶ Connect with me on LinkedIn where I share daily tips: <a target="_blank" href="https://www.linkedin.com/in/eamonncottrell/">https://www.linkedin.com/in/eamonncottrell/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Web Scraping with Google Sheets – How to Scrape Web Pages with Built-in Functions ]]>
                </title>
                <description>
                    <![CDATA[ You read that right – you can practice web scraping without leaving your happy place: Google Sheets. Google Sheets has five built-in functions that help you import data from other sheets and other web pages. We'll walk through all of them in order fr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/web-scraping-google-sheets/</link>
                <guid isPermaLink="false">66b8de2af805ffd579552e9e</guid>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web scraping ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 07 Sep 2023 21:14:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/5-functions-for-web-scraping-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You read that right – you can practice web scraping without leaving your happy place: Google Sheets.</p>
<p>Google Sheets has five built-in functions that help you import data from other sheets and other web pages. We'll walk through all of them in order from easiest (most limited) to hardest (most powerful).</p>
<p>Here they are, and you can click each function to skip down to its dedicated section. I've made a video as well that walks through everything:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Hx1Uepq3lLI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-section-shortcuts">Section Shortcuts</h3>
<ul>
<li>How to use the <a class="post-section-overview" href="#">IMPORTRANGE</a> function</li>
<li>How to use the  <a class="post-section-overview" href="#-1">IMPORTDATA</a> function</li>
<li>How to use the <a class="post-section-overview" href="#-2">IMPORTFEED</a> function</li>
<li>How to use the <a class="post-section-overview" href="#-3">IMPORTHTML</a> function</li>
<li>How to use the <a class="post-section-overview" href="#-4">IMPORTXML</a> function</li>
</ul>
<p><a target="_blank" href="https://docs.google.com/spreadsheets/d/1n8CYEHYktePXJzt5quCBn2gwHvnvTH49vvJziXLnQSE/edit#gid=511198009">Here's the Google Sheet</a> we'll be using to demo each function.</p>
<p>If you'd like to edit it, make a copy by selecting File - Make a copy when you open it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Google Sheet</em></p>
<p><a id="importrange"></a></p>
<h2 id="heading-how-to-use-the-importrange-function">How to use the IMPORTRANGE function</h2>
<p>This is the only function that imports a range from another sheet rather than data from another web page. So, if you've got another Google Sheet, you can link the two sheets together and import the data you need from one sheet into the other sheet.</p>
<p>For instance, <a target="_blank" href="https://docs.google.com/spreadsheets/d/1S0H1FDHBC_7oxe2NCpnfuJcklaLpYCFuo_eRhADnyWg/edit#gid=1363138812">here's a sheet</a> with a bunch of random Samsung Galaxy data in it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can see that we have a few hundred rows of data about phones. If we want to import this data into another spreadsheet, we can use <code>IMPORTRANGE()</code>. This is the simplest to use of the five functions we'll look at. All it needs is a URL for a Google Sheet and the range we want to import.</p>
<p>Check out the tab for IMPORTRANGE in the Google Sheet <a target="_blank" href="https://docs.google.com/spreadsheets/d/1n8CYEHYktePXJzt5quCBn2gwHvnvTH49vvJziXLnQSE/edit#gid=0">here</a>, and you'll see that in cell <code>A5</code>, we've got the function <code>=IMPORTRANGE(B4,"data!a1:K")</code>. This is pulling in the range <code>A1:K</code> from the <code>data</code> tab of our second spreadsheet whose URL is in cell <code>B4</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of IMPORTRANGE function</em></p>
<p>Once your data is pulled into your spreadsheet, you can do one of two things. </p>
<ol>
<li>Leave it linked through the <code>IMPORTRANGE</code> function. This way, if your data source is going to be updated, you'll pull in the updated data.</li>
<li>Copy and CTRL+SHIFT+V to paste values only. This way, you have the raw data in your new spreadsheet and you won't have to be dependent on something changing with the URL down the road.</li>
</ol>
<p><a id="importdata"></a></p>
<h2 id="heading-how-to-use-the-importdata-function">How to use the IMPORTDATA function</h2>
<p>This is pretty straightforward. It'll import .csv or .tsv data from anywhere on the internet. These stand for Comma Separated Values and Tab Separated Values. </p>
<p>.csv is the most commonly used file type for financial data that needs to be imported into spreadsheets and other programs. </p>
<p>Like <code>IMPORTRANGE</code>, we only need a couple pieces of information for <code>IMPORTDATA</code>: the URL where the file lives, and the delimiter. There's also an optional variable for locale, but I found that it was unnecessary.</p>
<p>In fact, Google Sheets is pretty smart – you can leave off the delimiter too, and it will usually decipher what type of data (.csv or .tsv) lives at the URL.</p>
<p>You can see that I've found a New York government data website where there lives some winning lottery number data. I've put the URL for a .csv file in <code>A5</code>, and then used the function <code>=IMPORTDATA(A5,",")</code> to pull in the data from the .csv file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of IMPORTDATA function</em></p>
<p>You could alternatively download the .csv file and then select File - Import to bring in this data. But in the event that you do not have download permissions or simply want to get it straight from a site, <code>IMPORTDATA</code> works great.</p>
<p><a id="importfeed"></a></p>
<h2 id="heading-how-to-use-the-importfeed-function">How to use the IMPORTFEED function</h2>
<p>This imports RSS feed data. If you're familiar with podcasting, you may recognize the term. Every podcast has an RSS feed which is a structured file full of XML data. </p>
<p>Using the URL for the RSS feed, IMPORTFEED will pull in data about a podcast, news article, or blog from its RSS information.</p>
<p>This is the first function that begins to have a few more options at its disposal, too.</p>
<p>All that's required is the URL of a feed, and it'll bring in data from that feed. However, we can specify a few other parameters if we like. The options include:</p>
<ol>
<li>[query]: this specifies which pieces of data to pull from the feed. We can select from options like "feed " where type can be title, description, author or URL. Same deal with "items " where type can be title, summary, URL or created.</li>
<li>[headers]: this will either bring in headers (TRUE) or not (FALSE)</li>
<li>[num_items]: this will specify how many items to return when using Query. (The docs state that if this isn't specified, all items currently published are returned, but I did not find this to be the case. I had to specify a larger number to get back more than a dozen or so).</li>
</ol>
<p>You can see from the screenshots below that I am querying one of my feeds to pull in the episode titles and URLs. </p>
<p>First, to get all the titles, I used <code>IMPORTFEED(A3, "items title", TRUE, 50</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of IMPORTFEED</em></p>
<p>Then, similarly for the URLs, I used <code>IMPORTFEED(A3, "items url", TRUE, 50)</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-7.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of IMPORTFEED #2</em></p>
<p><a id="importhtml"></a></p>
<h2 id="heading-how-to-use-the-importhtml-function">How to use the IMPORTHTML function</h2>
<p>Now we're getting into scraping data straight off of a web site. This will take a URL and then a query parameter where we specify to look for either a "table" or a "list".</p>
<p>This is followed by an index value representing which table or list to look for if there are multiple on the page. It is zero indexed, so input zero if you're looking for the first one.</p>
<p>IMPORTHTML looks through the HTML code on a website for <code>&lt;table&gt;</code> and <code>&lt;list&gt;</code> HTML elements.</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!--Here's what a simple table looks like:--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>table header 1<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>table header 2<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>table data row 1 cell1<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>table data row 1 cell2<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>table data row 2 cell1<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>table data row 2 cell2<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>

<span class="hljs-comment">&lt;!--Here's what an ordered list looks like:--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ol</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>ordered item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>ordered item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>ordered item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ol</span>&gt;</span>
<span class="hljs-comment">&lt;!--Here's what an unordered list looks like:--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>unordered item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>unordered item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>unordered item 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>In the sample sheet, I've got the URL for some stats about the Barkley Marathons in cell <code>B3</code> and am then referencing that in <code>A4</code>'s function: <code>=IMPORTHTML(B3,"table",0)</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-8.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of IMPORTHTML</em></p>
<p>FYI, freeCodeCamp created <a target="_blank" href="https://scrapepark.org/">ScrapePark</a> as a place to practice web scraping, so you can use it for <code>IMPORTHTML</code> and <code>IMPORTXML</code> coming up next👇.</p>
<p><a id="importxml"></a></p>
<h2 id="heading-how-to-use-the-importxml-function">How to use the IMPORTXML function</h2>
<p>We saved the best for last. This will look through websites and scrape darn near anything we want it too. It's complicated, though, because instead of importing all the table or list data like with <code>IMPORTHTML</code>, we write our queries using what's called XPath. </p>
<p>XPath is an expression language itself used to query XML documents. We can write XPath expressions to have <code>IMPORTXML</code> scrape all kinds of things from an HTML page.</p>
<p>There are many resources to find the proper XPath expressions. <a target="_blank" href="https://devhints.io/xpath">Here's one</a> that I used for this project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-182.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of XPath cheat sheet</em></p>
<p>In the <a target="_blank" href="https://docs.google.com/spreadsheets/d/1n8CYEHYktePXJzt5quCBn2gwHvnvTH49vvJziXLnQSE/edit#gid=438611895">sheet</a> for <code>IMPORTHTML</code>, I have several examples that I encourage you to click through and check out.</p>
<p>For example, using the function <code>=IMPORTXML(A11,"//*[@class='post-card-title']")</code> allows us to bring in all the titles of my articles because from inspecting the HTML on my author page here, I found that they all have the class <code>post-card-title</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/class.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of inspecting a web page with dev tools</em></p>
<p>In the same way, we can use the function <code>=IMPORTXML(A11,"//*[@class='post-card-title']//a/@href")</code> to grab the URL slug of each of those articles.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-10.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of IMPORTXML</em></p>
<p>You'll notice that it does bring in the full URL, so as a bonus, we can simply prepend the domain to each of these. Here's the function for the first row which we can drag down to get all those proper URLs: <code>="https://www.freecodecamp.org"&amp;B13</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-11.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of prepending domain to slug</em></p>
<h2 id="heading-follow-me">Follow Me</h2>
<p>I hope this was helpful for you! I learned a lot myself, and enjoyed putting the video together. </p>
<p>You can find me on YouTube: <a target="_blank" href="https://www.youtube.com/@eamonncottrell">https://www.youtube.com/@eamonncottrell</a></p>
<p>And, I've got a newsletter here: <a target="_blank" href="https://got-sheet.beehiiv.com/">https://got-sheet.beehiiv.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Google Sheets – A Beginner's Guide ]]>
                </title>
                <description>
                    <![CDATA[ Google Sheets is an online spreadsheet app with real-time collaboration features. It's like Microsoft Excel for regular people. 🙌 gif of guy saying aren't ordinary people adorable And, these days, it's actually giving Excel a run for its money. It'... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-sheets-for-beginners/</link>
                <guid isPermaLink="false">66b8ddef0a89d796f29a16e1</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Tue, 25 Jul 2023 17:53:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/maxresdefault.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google Sheets is an online spreadsheet app with real-time collaboration features. It's like Microsoft Excel for regular people. 🙌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/ordinary.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of guy saying aren't ordinary people adorable</em></p>
<p>And, these days, it's actually giving Excel a run for its money. It's picked up a lot of features and processing power over the years that used to be exclusive to Excel.</p>
<p>But we're here to talk about the basics today.</p>
<p>🧾I'm going to cover:</p>
<ol>
<li>How to create new Google Sheets</li>
<li>Intro to Templates</li>
<li>Menu and toolbar overview</li>
<li>Basic data entry and calculations</li>
<li>Basic formatting</li>
<li>How to create a table</li>
<li>How to sort and filter data</li>
<li>Intro to formulas and functions</li>
</ol>
<h2 id="heading-video-walkthrough">Video Walkthrough</h2>
<p>I've made a video walkthrough of the things we'll be covering in this article. You can check it out below:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/_bvRa7T-59U" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-create-a-new-sheet">How to Create a New Sheet</h2>
<p>Spreadsheets can be intimidating even in their most basic form. </p>
<p>Don't be scared, though.👇 </p>
<p>To use Google Sheets, you need a free Google account. (If you're using Gmail, you already have this.) Go <a target="_blank" href="https://www.google.com/sheets/about/">here</a> to sign up if you don't have one yet.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-141.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of the Google Sheets homepage</em></p>
<p>Go ahead and go to <a target="_blank" href="https://sheets.new">sheets.new</a> to create a brand new Google Sheet. It will also prompt you to sign up if you don't have an account yet. </p>
<p> 💥This is what you'll see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-138.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of a blank spreadsheet</em></p>
<p>😓Some of you may already have begun perspiring because a spreadsheet looks like an unapproachable blank slate reserved for data analysts, financial gurus, and overly ambitious content creators. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/sweat.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of man stressing out</em></p>
<p>💪Fear not. </p>
<p>A spreadsheet, and particularly a Google Sheet, is ripe with possibilities for the average person.</p>
<p>You can use them to enhance productivity after learning only a few basic things. </p>
<p>📊A spreadsheet is a <strong>big grid</strong> made up of <strong>columns labeled with letters</strong> and <strong>rows labeled with numbers</strong>. Each of the rectangles of the grid are called a <strong>cell</strong>, and the active cell is the one with the blue outline. </p>
<p>If you start typing, whatever you type will appear in the active cell.</p>
<p>The cells can contain numbers, words, formulas, dates, pretty much anything...</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-140.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of spreadsheet cell</em></p>
<h2 id="heading-google-sheets-templates">Google Sheets Templates</h2>
<p>Google has supplied us with a respectable amount of templates to get started with. </p>
<p>I will not be covering these in any detail because it's important to get the basics down first. I just want you to be aware of them if you need a starting point <strong>after</strong> you've gotten comfortable with Sheets. </p>
<p>You can look through the template gallery <a target="_blank" href="https://docs.google.com/spreadsheets/u/0/?ftv=1">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-142.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Google Sheets templates</em></p>
<h2 id="heading-menu-and-toolbar-overview">Menu and Toolbar Overview</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/menus.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Google Sheets menu and toolbar</em></p>
<p>You will likely be familiar with the menu and toolbar setup. As with most modern applications, they are at the top of the page. The menu has many familiar options like File, Edit, View, Insert, and so on. And the toolbar below it consists of mostly icons related to formatting and text options.</p>
<p>The <strong>File</strong> menu has options to share, download, copy, import, rename and other such things related to the whole spreadsheet.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-144.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of file menu</em></p>
<p><strong>Edit</strong> and <strong>View</strong> have familiar options regarding copy/paste and choosing different levels of visibility for your spreadsheet.</p>
<p><strong>Insert</strong> gives us a host of options of things to import into our sheet like charts, pivot tables, checkboxes, emojis, dropdown lists, and many more.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-145.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of insert menu</em></p>
<p><strong>🎨Format</strong> contains many options for formatting our sheet. We can add color, borders, tables styles, and more from here.</p>
<p>The <strong>Data</strong> menu has a lot of spreadsheet specific functions. It contains shortcuts to sort and filter data, to protect different ranges of cells, to group ranges together by naming them, data validation, and advanced items like connecting data sources.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-146.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of the Data menu in Google Sheets</em></p>
<p>Tools and Extensions will be lesser used menus, at least in the beginning. But some really exciting stuff is possible by leveraging the power of <strong>Google Apps Script</strong> through the Extensions menu. This lets us write programs in a language similar to JavaScript all while in a spreadsheet.</p>
<p>But, that's for later – or check out some of my other <a target="_blank" href="https://www.youtube.com/@eamonncottrell">videos</a> and <a target="_blank" href="https://www.freecodecamp.org/news/author/eamonn">articles</a> to get a taste of Apps Script.</p>
<h2 id="heading-basic-data-entry-and-calculations">Basic Data Entry and Calculations</h2>
<p>What is data? According to my Google search, data are "facts and statistics collected together for reference or analysis."</p>
<p>Spreadsheets thrive on data. Yes, think numbers, dates, percentages...things that are easily calculable.</p>
<p>In Google Sheets, we can enter in some data. Say, a list of names, dollar amounts, and dates. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-150.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of some data</em></p>
<p>Now, we have a simple list of data. Because it's small, we can scan it and analyze it ourselves pretty easily. </p>
<ol>
<li>We can see that it's ordered by date</li>
<li>We can see that Paul either has or owes the most</li>
<li>We can see that Sara either has or owes the least</li>
</ol>
<p>But imagine this is a list of thousands of records (each row of an amount, a name, and a date can be referred to as one record).</p>
<p>Suddenly it gets a lot harder to analyze or make sense of the data. </p>
<p>Then add a dozen or a hundred more columns of data for each record. It becomes virtually impossible for a human to draw anything meaningful from the data without the help of a spreadsheet or computer program.</p>
<p>Next, we'll see how some organization and simple spreadsheet operations can help us draw insights from our data.👇</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/easy.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of woman saying this is so easy</em></p>
<h2 id="heading-basic-formatting">Basic Formatting</h2>
<p>Highlight the table. You can do this by clicking and dragging across the whole range of cells. Now, you should have an active <strong>range</strong> instead of an active <strong>cell</strong>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-151.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Google Sheets table</em></p>
<p>Take a moment and click through some of the formatting options on the toolbar. I've changed the text, the font size, and then made bold the first header row. </p>
<p>I've also highlighted only the dollar amounts, and changed their format to <strong>currency</strong> instead of just a number.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/menus-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Google Sheets formatting</em></p>
<p>Already, the information is a little more readable. In the next steps we will go further.👇</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/rabbit-hole.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of Alice falling down rabbit hole</em></p>
<h2 id="heading-how-to-create-a-table-in-sheets">How to Create a Table in Sheets</h2>
<p>Alas, we don't (yet) have a swift shortcut like Excel does to make a table. But if we highlight our data again, and select <strong>Format -&gt; Alternating Colors</strong> from the toolbar, we can create table formatting for enhanced readability.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-153.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Alternating Colors table style in Google Sheets</em></p>
<p>Now, we have banded rows of alternating colors. This becomes very useful in large data sets, but is equally pleasing in our small example. Once satisfied with your color selections, click done.</p>
<p>Now, if we add rows of data to the bottom of our table, Google Sheets is smart enough to know that we probably want to extend the table downward. It will extend the alternating color formatting as we add two more lines:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-154.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of extended Google Sheets table</em></p>
<h2 id="heading-how-to-sort-data-with-a-filter-in-sheets">How to Sort Data with a Filter in Sheets</h2>
<p>Tables are useful because, with some small steps, we can sort and filter data in ways that make it easier to draw conclusions or extract meaning from our data.</p>
<p>Click anywhere in the range of data, and select <strong>Data -&gt; Create a filter</strong> from the Menu bar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-155.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of creating a filter in Google Sheets</em></p>
<p>Again, Google Sheets knows to create a filter for the entire data set, and you can see two things visually represented: </p>
<ol>
<li>The rows and columns of the data set are now given a highlight color to show that a filter has been applied.</li>
<li>To the right of each header label, there are three horizontal lines that look like an upside-down pyramid. These are the filters.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-156.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of filter on a Google Sheets table</em></p>
<p>From here, we can both sort and/or filter our data. If we sort, for instance, Z -&gt; A, we can display each row from highest to lowest dollar amount.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-157.png" alt="Image" width="600" height="400" loading="lazy">
<em>sorted table</em></p>
<p>If we click the data column's pyramid, we can see that for filtering options, we can either filter by condition or by value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-158.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of filtering options in Google Sheets</em></p>
<p>Filtering by <strong>values</strong> lets us toggle on or off certain dates. Filtering by <strong>condition</strong> allows for all sorts of options. We can choose dates that are before or after certain dates. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-159.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of filter options in Google Sheets</em></p>
<p>Or we can select "Is between" and then write in a period of dates we want to filter for.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-161.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of filter options in Google Sheets</em></p>
<p>This becomes immensely helpful to narrow down a field of results for analysis. Now we can focus on only the subset of filtered results.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-162.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-intro-to-formulas-and-functions">Intro to Formulas and Functions</h2>
<p>The final piece we'll touch on is the ability to <strong>write formulas</strong> and <strong>use functions</strong>.</p>
<h3 id="heading-formulas-in-google-sheets">Formulas in Google Sheets</h3>
<p>Formulas are instructions we manually type into a cell to manipulate data. If we wanted to add the values in cells A16 and A17, we could write a formula that did this like so: <code>=A16+A17</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-163.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of a formula in Google Sheets</em></p>
<p>We can do basic math very easily like this, but there's an even better way to do this by using functions.</p>
<h3 id="heading-functions-in-google-sheets">Functions in Google Sheets</h3>
<p>Functions are built-in formulas that we use by typing their name. Again, we start out by typing the equals sign, but then we type the name of the function, in this case SUM: <code>=SUM(A16:A17)</code>.</p>
<p>When we begin typing a function, a tooltip will pop up giving us options for the different functions available. You can hit the TAB key to select a function, click one from the list, or complete the spelling of the function and type an open parentheses to select a function.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-165.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of available functions in Google Sheets</em></p>
<p>Once selected, the tooltip will display helper text about that function in case we need an explanation of what it does and/or the variables it needs:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-164.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of the SUM function in Google Sheets</em></p>
<p>These are straightforward examples of adding numbers, but there are over 400 built-in functions that range greatly in complexity. </p>
<h2 id="heading-whats-next">What's Next?</h2>
<p>As you've probably figured out, this barely scratches the surface of Google Sheets. Once you're comfortable with the basics, it's time to dive deeper and use Sheets to solve some problems of your own.</p>
<p>Check out the templates I've linked above for inspiration, spin up a personal finance tracker, make a workout calendar, track stock prices, build a cost of goods sheet for a small business, build an amortization sheet to see if you can afford a house, track your time with a project management sheet...the possibilities are vast.</p>
<p>🔗Check out my <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube channel</a> and <a target="_blank" href="https://got-sheet.beehiiv.com/subscribe">newsletter</a> for more Sheets content and projects.</p>
<p>🔗Connect with me on <a target="_blank" href="https://www.linkedin.com/in/eamonncottrell/">LinkedIn</a>.</p>
<p>Hope you have a great one!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/bye-gosling.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of Gosling waving bye</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Intro to Generative AI – 10 Free Courses by Google ]]>
                </title>
                <description>
                    <![CDATA[ Are you tired of all the AI talk yet? I am too, but I'm also intrigued by the technology behind it. If you'd like to dive into some of the details behind how AI actually works and take a break from the many creepy AI examples on the internet, check ]]>
                </description>
                <link>https://www.freecodecamp.org/news/intro-to-generative-ai-10-free-courses-by-google/</link>
                <guid isPermaLink="false">66b8de0cf805ffd579552e99</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ online courses ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 22 Jun 2023 22:22:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/gen-AI.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you tired of all the AI talk yet?</p>
<p>I am too, but I'm also intrigued by the technology behind it.</p>
<p>If you'd like to dive into some of the details behind how AI actually works and take a break from the many creepy AI examples on the internet, check this out:</p>
<p>Google has released a free set of training courses for generative AI. <a target="_blank" href="https://cloud.google.com/blog/topics/training-certifications/new-google-cloud-generative-ai-training-resources">Here's their announcement post</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/cloudify-your-skills.png" alt="Image" width="600" height="400" loading="lazy">
<em>Picture for generative AI courses</em></p>
<h3 id="heading-video-walkthrough">Video Walkthrough</h3>
<p>I've made a short video of the coursework if you'd prefer a visual walkthrough of my first impressions:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/OgE0DSSWk2M" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-overview">Overview</h2>
<p>There are 10 courses in this free learning path. Many are aimed at beginners with no prerequisite knowledge. Some suggest a background in Python, SQL, and/or machine learning. All of them deliver content through a combination of videos, articles, labs and quizzes.</p>
<p>There are badges to show that you've completed them, and I'm happy to see a freely available set of courses around the technology behind AI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/badge.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google course badge</em></p>
<p>The amount of content produced by and highlighting AI is overwhelming right now, but it's a safe bet that this is going to stick around. As such, it's best to arm yourselves with as much information about it as you can so that you can responsibly create tools and content for the future.</p>
<h2 id="heading-courses-material">Courses Material</h2>
<p>I've created a Google Sheet with all the course info pulled from each of these courses. <a target="_blank" href="https://docs.google.com/spreadsheets/d/1lHvmTj7SEZU_6vMg7E8yDpBctYdlEYNxc5fJtZzlwCc/edit#gid=0">Check it out here</a>. Google has done a fine job of creating a brief FAQ for each of the courses, and I've pulled them all into one sheet for easy comparison.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/google-sheet-summary.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google Sheet summary of all courses</em></p>
<p>Inside each course, you'll be presented with a straightforward navigation for the content. It's broken into video instruction, a curated collection of readings to peruse, and quizzes. Some courses also have online labs to complete in a certain amount of time.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/create-image-capturing-models.png" alt="Image" width="600" height="400" loading="lazy">
<em>Video content for the Create Image Captioning Models course</em></p>
<p>The curated list of readings is quite comprehensive, and you could easily exceed the estimated 45 minutes of time to complete the modules if you read through every one. But it is nice to have such a large list of resources compiled in one place.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/llms.png" alt="Image" width="600" height="400" loading="lazy">
<em>The list of readings for the Intro to Large Language Models course</em></p>
<p>There are also Labs hosted in some of the courses. If you've taken any of Google's Coursera courses, you'll be familiar with this delivery method. You're given a handful of tasks and a countdown timer, in this case 1hr, will begin when you start the lab.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/lab-work.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of lab work</em></p>
<p>Here is the full list of courses:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/intro-screenshot.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/536">Introduction to Generative AI</a> – designed to be an overview of what generative AI is and how it differs from machine learning methods. </li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3634938/video/379143">Introduction to Large Language Models</a> – explores what large language models are, where they are used, and how to use prompt tuning. (If you haven't noticed, prompt writing is being touted as a skill of the future right now.)</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/554">Introduction to Responsible AI</a> – an ethical course on what responsible AI is, how it's implemented in Google products, and why it's important. This course introduces Google's 7 AI Principles. I didn't know this was a thing, but there's a <a target="_blank" href="https://ai.google/responsibility/principles/">whole page</a> devoted to it. Covering topics from social responsibility, to safety, accountability and privacy design principles, I was happy to see that there is large effort being paid to build in solid principles.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3652912/quizzes/381263">Generative AI Fundamentals</a> – A quiz covering topics from the first three courses.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/541">Introduction to Image Generation</a> – An introduction to diffusion models which are a family of models used in image generation. Some pre-existing knowledge of machine learning, deep learning, convolutional neural nets and/or Python programming is suggested.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/543">Encoder-Decoder Architecture</a> – overview of a machine learning architecture for tasks like machine translation, text summarization, and question answering. Python and Tensorflow knowledge is suggested as a prerequisite.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/537">Attention Mechanism</a> – a technique that allows neural networks to focus on specific parts of an input sequence. Some pre-existing knowledge of machine learning, deep learning, natural language processing, and/or Python programming is suggested.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3635001/video/377866">Transformer Models and BERT Model</a> – Bidirectional Encoder Representations from Transformers...this is what BERT stands for in case you didn't know. You'll learn the main components of the Transformer architecture and intermediate machine learning experience as well, and knowledge of Python and TensorFlow are recommended.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3652936/video/379207">Create Image Captioning Models</a> – how to create an image captioning model using deep learning. Deep learning, machine learning, natural language processing, computer vision and Python are recommended prerequisites.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/552">Introduction to Generative AI Studio</a> – you'll walk through demos of the Generative AI Studio which helps prototype and customize generative AI models. There is a hands-on lab at the end.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/generative-ai-studios-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-my-thoughts">My Thoughts</h2>
<p>After spending some time browsing through all of these courses, it's a nice mix of truly beginner-friendly content and some intermediate level stuff that requires previous knowledge of machine learning, Python, deep learning, and/or natural language processing.</p>
<p>I appreciate how there are answers to many common questions in the drop down menus for each course (and I've compiled all of those in one place in this <a target="_blank" href="https://docs.google.com/spreadsheets/d/1lHvmTj7SEZU_6vMg7E8yDpBctYdlEYNxc5fJtZzlwCc/edit#gid=0">Google Sheet</a>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/google-cloud-screenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google Cloud certifications</em></p>
<p>This is a great starting point if you are truly interested in the inner-workings of AI. It also looks to be a potential on-ramp to some of <a target="_blank" href="https://cloud.google.com/learn/certification#why-get-google-cloud-certified">Google Cloud's larger certifications</a> as there are links to further training sprinkled in the courses.</p>
<p>What do you think?</p>
<p>👋My name is <a target="_blank" href="https://www.linkedin.com/post/edit/7077633795897622528/?author=urn%3Ali%3Afs_miniProfile%3AACoAAAirLdUBMHodHKOoTMZvUxoRedTeclnkxfw#">Eamonn Cottrell</a>, and I'm building content around Google Sheets &amp; Workspace. </p>
<p>Get my 📨 <a target="_blank" href="https://got-sheet.beehiiv.com/subscribe">newsletter here</a>. Find me on 📺 <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube here</a>.</p>
<p>Please ask questions in the comments, or send me a message; I love making new spreadsheet connections!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ AI in Google Sheets – How to Use GPT Copilot ]]>
                </title>
                <description>
                    <![CDATA[ It seems to be the year of AI. And my favorite tool, Google Sheets, is not to be left out of the fun. 🎉 Coefficient produced a Google sheets extension with the ability to use OpenAI's GPT models from within a spreadsheet. It’s called GPT Copilot an... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/ai-in-google-sheets/</link>
                <guid isPermaLink="false">66b8ddcc0cedc1f2a4f70674</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Mon, 12 Jun 2023 22:10:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/ai-in-google-sheets-thumb.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It seems to be the year of AI. And my favorite tool, Google Sheets, is not to be left out of the fun. 🎉</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/giphy.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://coefficient.io/gpt-google-sheets">Coefficient</a> produced a Google sheets extension with the ability to use OpenAI's GPT models from within a spreadsheet. It’s called GPT Copilot and it’s available to try for free. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.00.44-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Coefficient's GPT in Sheets page</em></p>
<p>I have been putting off looking into this tool for quite some time, though I've been following Coefficient's Google Sheets work for a while now.</p>
<p>To be honest, I'd gotten a little tired of all the AI talk and was wary of yet another effort in that realm. Do I really need to use AI in spreadsheets? </p>
<p>🤷Yes and no.</p>
<h2 id="heading-video-example">Video Example</h2>
<p>I made a quick video walking through a handful of the GPTx functions, and I'll detail all of them in the article below. If you have a sec, check out the 2.5 min video and give it a 👍.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/HaKYyPLaOFA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>The extension is pretty cool.</p>
<p>AI is not some thing that is going to do all of my work for me. But it is a pretty powerful tool with which I can do work faster, more efficiently, and in some cases get some unique inspiration from.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/potential.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of ted lasso saying, smells like potential</em></p>
<h2 id="heading-gpt-copilot-functions">GPT Copilot Functions</h2>
<p>In the GPT Copilot extension on Google Sheets, we are given a list of several built-in <code>GPTX</code> functions we can now use directly in the sheet itself. </p>
<p><a target="_blank" href="https://docs.google.com/spreadsheets/d/1CaLdC22IS_9K42ycwkyYlnsCSGsEpyJtedPWXxn5poI/edit#rangeid=903106705">Here</a> is a document with all the functions listed out, and we'll go through each below.</p>
<p>And <a target="_blank" href="https://docs.google.com/spreadsheets/d/10suhdcRdi5NI_PCGO0VK1TXiLIGdy44T8R3zL9938So/edit?usp=sharing">here's the spreadsheet</a> I used for all my samples and the video. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.12.07-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The first function, <code>=GPTX(prompt)</code> simply lets us generate text using Open AI's GPT model.</p>
<p>I used this to generate a subject line for an email below. This generic <code>GPTX</code> function can be used to query ChatAI's model for anything you can think of: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-113.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of GPTX() function</em></p>
<p>Then we get <code>**=GPTX_LIST(prompt)**</code> which lets us generate a list of values in the same way. </p>
<p>This is similar to the first example, but the list of items will appear in separate cells so it's handy if you want...say, the top 10 video games by sales in Korea:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-114.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>LIST() function</em></p>
<p><code>**=GPTX_EDIT(text,[task])**</code> was useful as I went through and created email body messages based on a prompt that I fed into the function. So it lets us perform a task or transformation on an input text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.14.09-PM.png" alt="Image" width="600" height="400" loading="lazy">
_screenshot of GPTX<em>EDIT function</em></p>
<p><code>**GPTX_MAP(search_keys, inputs)**</code> performs a fuzzy search, given a list of search keys in the list of input values, and then outputs the most similar search for each input value.</p>
<p>If we have a list of games and platform companies, it can map the company values to the correct game:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-124.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>MAP()</em></p>
<p><code>**GPTX_FILL(text, [task])**</code> fills in missing information in the table based on example rows.</p>
<p>This will let you feed it some example data and have GPTX fill in the rest:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-115.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>FILL</em></p>
<p><code>**GPTX_TABLE(prompt, [header_row])**</code> generates a table of values. This one was particularly cool because you can give it a real query to get data from, or have it fill out a table with dummy data.</p>
<p>Here we can pull in some population info on the top 5 cities in Tennessee: 😀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-116.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>TABLE()</em></p>
<p><code>**GPTX_FORMAT(text, language)**</code> converts input values into the specified format. </p>
<p><code>**GPTX_TAG(text, tags)**</code> does what it sounds like: it applies one or more tags matching a piece text.</p>
<p>If you have a list of movies, and a list of genres, you can tag them here. Interestingly:</p>
<ol>
<li>GPT doesn't seem to have a sense of humor as it didn't classify Waterworld as a flop.</li>
<li>It also won't blindly fill in genres that are missing from the list (Goldeneye and Seven)</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/flop.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>TAG()</em></p>
<p>Another cautionary tale, though...when I added crime to see if it would fill in Seven's blank, it actually came back with different answers on some of the others...and left off Casper and Jumanji this time. So, while nothing is really tagged incorrectly, it does have varying results. </p>
<p>In this case, it does behave like a human, in a way. You'll get different people answering this type of tagging question in different ways too. 🤷‍♂️</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>**GPTX_CLASSIFY(text, labels)**</code>, in the same way, classifies text given a set of labels or categories.</p>
<p><code>**GPTX_EXTRACT(text, info_to_extract)**</code> extracts the desired information from the input text. So if you have an address in a cell, it can extract the city name from the address.</p>
<blockquote>
<p>Caution though; I encountered several instances while writing these GPTX functions where I got #ERROR!s and had to refresh the page, close it and reopen, or simply wait a while...</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-118.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>**GPTX_SUMMARIZE(text, language)**</code> summarizes the input text according to the given format.</p>
<p>I tried to be clever here. I pasted the first chapter of The Great Gatsby into a cell. Pretty quickly got a "too large" error 😂)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-119.png" alt="Image" width="600" height="400" loading="lazy">
_screenshot of GPTX<em>Summarize error</em></p>
<p>But! Reducing down to the first 726 words was sufficient to have it actually summarize the beginning of this awesome novel:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-121.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>SUMMARIZE() summarizing the start of The Great Gatsby</em></p>
<p><code>**GPTX_TRANSLATE(text, language)**</code> translates the input text into the specified language.</p>
<p>This one's straightfoward and not incredibly useful for my spreadsheets...but nonetheless, it's pretty neat:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-122.png" alt="Image" width="600" height="400" loading="lazy">
_Screenshot of GPTX<em>TRANSLATE()</em></p>
<p><code>**GPTX_CONVERT(text, format)**</code> converts the input text into the specified structured format.</p>
<p><code>**GPTX_CODE(task, language)**</code>generates code in a specified language, which performs the specified task. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.21.54-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>GPTX_CODE()</code> was really neat. I also see the most chances for problems here because novices will be tempted to blindly use code not knowing how or if it works.</p>
<p>This seems most beneficial as a helper for when I know how the code should work, but can prompt for the basic skeleton instead of needing to search for methods on my own.</p>
<h2 id="heading-limits-to-gpt-copilot">Limits to GPT Copilot</h2>
<p>Are there limits to the number of prompts you can feed these functions? Yes. Of course there are. 😆</p>
<p>To stay free, you get 10,000 executions. Monthly plans start at 100,000 executions per month.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.33.46-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot from the Coefficient GPT CopilotFAQ</em></p>
<h2 id="heading-what-i-think">What I Think</h2>
<p>I walk through some real basic stuff that I could have generated on my own in the <a target="_blank" href="https://youtu.be/HaKYyPLaOFA">example video</a> that I encourage you to watch. But I do see the potential for this to be a very helpful tool as the ecosystem matures.</p>
<p>Insofar as dummy data is concerned, it is really helpful to just generate stuff in a spreadsheet quickly.</p>
<p>And it works great to fill in the blanks where you previously might do a little bit more manual labor, extracting values, formatting things, classifying things, and so on.</p>
<p>In addition to these built-in functions, the Coefficient add-on also contains a pivot builder, a formula builder, and a chart builder tool.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-2023-06-09-at-8.25.26-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Coefficient's extension</em></p>
<p>These allow you to feed a prompt into the extension based on the data in your spreadsheet, and it will generate either a pivot table, a formula, or a chart.</p>
<p>These are kind of crutches for doing some pretty basic operations in Google Sheets. But they do have an interesting utility and are pretty reliable when you give well-written prompts to them.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>🤔 AI tools can be a big time sink. It's pretty easy to spend more time getting mediocre results from them than it would have taken to do things manually.</p>
<p>But, that's part of the learning curve for any toolkit. Upfront investments can certainly pay off in the long run. I'll keep using these tools to hopefully make better spreadsheets more efficiently.</p>
<p>❓What do you think? Is this another example of over-engineering simple things? Or is it the next big thing in Google Sheets?</p>
<p>Come join the conversation on my YouTube channel: <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">https://www.youtube.com/@eamonncottrell?sub_confirmation=1</a></p>
<p>Or my LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/eamonncottrell/">https://www.linkedin.com/in/eamonncottrell/</a></p>
<p>Have a great one! 👋</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Sheets – How to Make a Dynamic Search Bar ]]>
                </title>
                <description>
                    <![CDATA[ This tutorial is for when CTRL + F is not enough. 🔥 I bet I've used the CTRL + F shortcut more than any other keyboard shortcut in my life. CTRL + Z probably comes close, but I use CTRL + F to find things... 💥ALL 💥 💥💥THE 💥💥 💥💥💥TIME ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dynamic-search-bar-google-sheets/</link>
                <guid isPermaLink="false">66b8dddbfedc3fd92fddb767</guid>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Fri, 02 Jun 2023 13:31:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/Google-Sheets-Dynamic-Search-Bar-with-profile.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This tutorial is for when CTRL + F is not enough. 🔥</p>
<p>I bet I've used the CTRL + F shortcut more than any other keyboard shortcut in my life. CTRL + Z probably comes close, but I use CTRL + F to find things...</p>
<p>💥<strong>ALL 💥</strong></p>
<p>💥💥<strong>THE</strong> 💥💥</p>
<p>💥💥💥<strong>TIME</strong> 💥💥💥</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/more2.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of man saying we need more</em></p>
<p>And yes, it'll work just fine in a Google Sheet to find information.</p>
<p>But sometimes I want to display a range of results based on a word I'm searching for. To do that, we'll create a dynamic search bar in our Google Sheet.</p>
<p>You can also follow along in this walkthrough video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/5xgwvokDhT0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-the-search-bar">The Search Bar</h2>
<p>Our search bar is nothing more than a cell or range of cells. In the example below, it starts in J2.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/google-sheets-search-bar.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of a search bar on Google Sheets</em></p>
<p>By adding a <code>=QUERY()</code> function in J5 we can look at whatever is typed into <code>J2</code> (the red circle) and display the search results below it (the blue rectangle).</p>
<p>In my example, I'm searching through a bunch of personal finance transactions (with randomized amounts😀) that are in columns <code>A:F</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/google-sheets-finance-data.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of finance data on Google Sheets</em></p>
<h2 id="heading-the-query-function">The Query Function</h2>
<p>The <code>=QUERY()</code> function looks in the Transactions range (which is that <code>A3:F</code> range where all the transactions live).</p>
<p>And it grabs all the info in either column B or column D that <code>CONTAINS</code> what we type in <code>J2</code>.</p>
<p>So it searches through all our transaction descriptions in column B and categories in column D for whatever we type in <code>J2</code>. The <code>LOWER</code> command turns the info in B and D into lowercase. This makes it easier to search because the <code>CONTAINS</code> command is case-sensitive.</p>
<pre><code class="lang-javascript">=QUERY(Transactions, 
       <span class="hljs-string">"SELECT A,B,C,D,E WHERE LOWER(B) CONTAINS '"</span>&amp;J2&amp;<span class="hljs-string">"' OR LOWER(D) CONTAINS '"</span>&amp;J2&amp;<span class="hljs-string">"'"</span>)
</code></pre>
<ul>
<li>the only caveat is that if you type in uppercase in the search bar, it won't work properly.</li>
</ul>
<h2 id="heading-the-filter-function">The Filter Function</h2>
<p>By using the <code>=FILTER()</code> function in combination with the <code>=SEARCH()</code> function, we can do the same thing in a little bit shorter formula and without having to worry about case sensitivity.</p>
<pre><code class="lang-xls">=<span class="hljs-built_in">IF</span>(<span class="hljs-built_in">ISBLANK</span>(<span class="hljs-symbol">J2</span>),<span class="hljs-string">""</span>,FILTER(Transactions,<span class="hljs-built_in">SEARCH</span>(<span class="hljs-symbol">J2</span>,<span class="hljs-symbol">B3</span>:<span class="hljs-symbol">B225</span>)))
</code></pre>
<p>The tradeoff here is that when we want to add multiple conditions like we did in the <code>=QUERY()</code> statement, it breaks down. Both <code>=FIND()</code> and <code>=SEARCH()</code> did not work properly when trying to use them more than once inside the <code>=FILTER()</code>.</p>
<p>I was able to find a work around by using the plus operator and constructing the formula in this way:</p>
<pre><code class="lang-xls">=<span class="hljs-built_in">IF</span>(<span class="hljs-built_in">ISBLANK</span>(<span class="hljs-symbol">J2</span>),<span class="hljs-string">""</span>,FILTER(Transactions,(<span class="hljs-symbol">B3</span>:<span class="hljs-symbol">B225</span>=<span class="hljs-symbol">J2</span>)+(<span class="hljs-symbol">D3</span>:<span class="hljs-symbol">D225</span>=<span class="hljs-symbol">J2</span>)))
</code></pre>
<p>Unfortunately when you filter in this way, partial matches are not included in the search results. </p>
<p>In the case of Query, partial answers are always returned. </p>
<p>So, when we enter "hom" all the lines with "home" in it would be returned. When using multiple conditions with filter, nothing would return unless you entered the whole word "home".</p>
<h2 id="heading-what-about-xlookup">What About XLOOKUP?</h2>
<p>The issue with XLOOKUP is twofold. One, it doesn't handle partial matches well unless you add wildcard characters:</p>
<pre><code class="lang-xls">=XLOOKUP(<span class="hljs-string">"*"</span>&amp;<span class="hljs-symbol">J2</span>&amp;<span class="hljs-string">"*"</span>,<span class="hljs-symbol">B3</span>:<span class="hljs-symbol">B225</span>,<span class="hljs-symbol">A3</span>:<span class="hljs-symbol">F225</span>,,<span class="hljs-number">2</span>)
</code></pre>
<p>This increases complexity but still works. </p>
<p>The more important difference is that it will only return one result so it's not going to work at all for us for this use case.</p>
<h2 id="heading-the-winner-is-query">The Winner is Query</h2>
<p>Query takes the prize simply because it doesn't need further manipulation to add multiple conditions, and it will return all the values that meet our search criteria.</p>
<p>It may take you a minute to wrap your head around the syntax, but it's just as powerful and more versatile than Filter in the long haul.</p>
<p>The only thing to make sure to remember is case sensitivity. If you're using the <code>LOWER</code> command in your query, don't use any uppercase search letters. </p>
<h2 id="heading-make-it-neat">Make it Neat</h2>
<p>In the full formula, I've added an <code>=IF()</code> function at the start to handle the blank search bar. We want to return nothing in that case:</p>
<pre><code class="lang-xls">=<span class="hljs-built_in">IF</span>(<span class="hljs-built_in">ISBLANK</span>(<span class="hljs-symbol">J2</span>),<span class="hljs-string">""</span>, QUERY(Transactions <span class="hljs-string">"SELECT A,B,C,D,E WHERE LOWER(B) CONTAINS '"</span>&amp;<span class="hljs-symbol">J2</span>&amp;<span class="hljs-string">"' OR LOWER(D) CONTAINS '"</span>&amp;<span class="hljs-symbol">J2</span>&amp;<span class="hljs-string">"'"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-30.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of a blank search bar in Google Sheets</em></p>
<h2 id="heading-follow-along">Follow Along</h2>
<p>Come <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">follow me over on YouTube</a> as I make tutorials each week.</p>
<p><a target="_blank" href="https://got-sheet.beehiiv.com/subscribe">Sign up here</a> to get my newsletter in your email each week.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Beehiivp.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Eamonn's Sheets | Coding | Education logo</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Sheets – How to Automatically Post Events to Google Calendar with Apps Script ]]>
                </title>
                <description>
                    <![CDATA[ In this article we'll link two Google services -> Google Sheets and Google Calendar. By using a very short custom function in Google Apps Script, we can add a list of events from a Google Sheet to a Google Calendar. 🤯 And we'll even have it email ou... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-sheets-automatically-post-events-to-google-calendar-with-apps-script/</link>
                <guid isPermaLink="false">66b8ddec0a89d796f29a16df</guid>
                
                    <category>
                        <![CDATA[ google apps script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Wed, 24 May 2023 21:44:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Sheets-to-Calendar3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article we'll link two Google services -&gt; Google Sheets and Google Calendar.</p>
<p>By using a very short custom function in Google Apps Script, we can add a list of events from a Google Sheet to a Google Calendar. 🤯</p>
<p>And we'll even have it email our guests as well. 🔥</p>
<p>Here's the video walkthrough to accompany the article:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/FxxPq2wXcK4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-google-sheets-setup">Google Sheets Setup</h2>
<p>Our sheet is quite straightforward. We have event names, dates, start times, end times and guest emails. </p>
<p>The only curious thing is the formatting of our dates and times - I'll cover this as we go on, but you can see that columns B and C are repeating information from columns D, E and F...</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684886378577.png" alt="Screenshot of Google Sheet event information" width="600" height="400" loading="lazy"></p>
<p>Google Calendar needs to receive the start and end times in the form of a full date/time object. But in the Google Sheet, there's not an easy way to create a dropdown data validation for users to select a date/time object.</p>
<p>In column D, I've put data validation to select a valid date.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684886609169.png" alt="Screenshot of data validation for a valid date" width="600" height="400" loading="lazy"></p>
<p>And in columns E and F, I've created a dropdown list of valid times.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684886767503.png" alt="Screenshot of data validation for a valid time" width="600" height="400" loading="lazy"></p>
<p>Columns B and C combine these together into a format that's useable to send to Google Calendar by using the =TEXT() function to concatenate the date and times together.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684886775902.png" alt="Screenshot of google sheets text concatenation" width="600" height="400" loading="lazy"></p>
<p>I promise it'll make more sense in a second! 😃</p>
<h2 id="heading-calendar-setup">Calendar Setup</h2>
<p>Let's make a new calendar in Google Calendar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684887186669.png" alt="Screenshot of new calendar options" width="600" height="400" loading="lazy"></p>
<p>Underneath your calendars on the left sidebar of Google Calendar, click the plus icon to add a new one.</p>
<p>Give it a name and a description if you want, and then we're ready to roll.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684887287557.png" alt="Screenshot of creating a new calendar" width="600" height="400" loading="lazy"></p>
<p>Scroll down a bit in the calendar's settings to the Integrate Calendar section. Copy the calendar ID. This is how we'll get Apps Script talking to Calendar!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684887643027.png" alt="Screenshot of calendar ID" width="600" height="400" loading="lazy"></p>
<h2 id="heading-apps-script-calendarapp">Apps Script + CalendarApp</h2>
<p>Apps Script is awesome. 👏</p>
<p>The <a target="_blank" href="https://developers.google.com/apps-script/reference/calendar/calendar-app">Class CalendarApp</a> allows a script to access a user's Google Calendar and make changes to it.</p>
<p>Here is the full script, and we'll walk through what's going on below.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Creates an events variable which is an array of arrays</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createCalendarEvent</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> events = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(<span class="hljs-string">"events"</span>).getValues();

    <span class="hljs-comment">// Creates an event for each item in events array</span>

    events.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
        CalendarApp.getCalendarById(<span class="hljs-string">"f7574e7b4d1ad00c9ecd7f1eba5bed329e8600e317cd387a400748d67f301d06@group.calendar.google.com"</span>).createEvent(
          e[<span class="hljs-number">0</span>],
          <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(e[<span class="hljs-number">1</span>]),
          <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(e[<span class="hljs-number">2</span>]),
          {<span class="hljs-attr">guests</span>: e[<span class="hljs-number">6</span>],<span class="hljs-attr">sendInvites</span>: <span class="hljs-literal">true</span>}
    );
  })
}
</code></pre>
<p>I've named the range <code>A3:B8</code> as "events". Then in Apps Script, we create a variable named events that grabs all the values in that whole range. We used a small range, but you could make this as many rows long as need be.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> events = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(<span class="hljs-string">"events"</span>).getValues();
</code></pre>
<p>Then, we loop through each item and add the events to our calendar.</p>
<p>The first part is where we use that calendar ID string we grabbed from Google Calendar for the <code>getCalendarById</code> method.</p>
<p>Then we use the <code>createEvent</code> method to pull data from each row in our Google Sheet and make new events.</p>
<p>Here's the <code>createEvent</code> description from the <a target="_blank" href="https://developers.google.com/apps-script/reference/calendar/calendar-app#createeventtitle,-starttime,-endtime,-options">developers page</a>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684888482755.png" alt="Screenshot of createEvent method" width="600" height="400" loading="lazy"></p>
<p>You can think of each row of data in the Google Sheet as an array of values. In the zero position is the event name, in the one position is the event date and start time, and so on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684938707460.jpeg" alt="Screenshot of array of arrays illustrated" width="600" height="400" loading="lazy"></p>
<p>By using <code>e[0]</code> we can access the element that is in the zero position for every time we loop through the forEach loop...effectively looping through each row of data.</p>
<p>And this is where the funky stuff we did with the start and end times comes into play.</p>
<p>Because the values in columns B and C are strings since we concatenated them together, we need to turn them back into complete date objects now.</p>
<p>That's why we're passing <code>new Date(e[1])</code> and <code>new Date (e[2])</code> into our createEvent function.</p>
<p>It's a bit of a cumbersome way to allow ourselves to use those dropdown selections in Google Sheets rather than painfully typing in a full date/time object.</p>
<p>User experience &gt; code. 👍</p>
<p>And lastly, we add an optional parameter to send invites to guests.</p>
<h2 id="heading-send-with-button">Send with Button</h2>
<p>That's all there is to the Apps Script. 🎉</p>
<p>As an added feature, we've attached a script to the rounded rectangle drawing to make it function like a button. Any time this is pressed, the events in the Google Sheet will populate the Google Calendar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/1684938905901.png" alt="Screenshot of assigning a script to a drawing in Google Sheets" width="600" height="400" loading="lazy"></p>
<p>I hope this has been useful for you!</p>
<p>Please come check out and subscribe to my <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">YouTube channel</a> where I'm making weekly videos on coding and spreadsheets.</p>
<p>If you'd like my newsletter in your inbox, <a target="_blank" href="https://got-sheet.beehiiv.com/subscribe">check it out here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Google Apps Script Basics by Building a Tic Tac Toe Game ]]>
                </title>
                <description>
                    <![CDATA[ Google Sheets are powerful, and Apps Script makes them even more versatile and useful. Yes, you can use them for finance dashboards, personal budgets, and project management (and we'll cover these as future topics). But in this article, I'll go throu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-google-apps-script-basics-by-building-tic-tac-toe/</link>
                <guid isPermaLink="false">66b8de150cedc1f2a4f7067c</guid>
                
                    <category>
                        <![CDATA[ google apps script ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google sheets ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Tue, 16 May 2023 16:58:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Tic-Tac-Toe-Google-Sheet2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google Sheets are powerful, and Apps Script makes them even more versatile and useful.</p>
<p>Yes, you can use them for finance dashboards, personal budgets, and project management (and we'll cover these as future topics). But in this article, I'll go through the basics of Apps Script by building a simple and playable Tic Tac Toe gameboard.</p>
<p>Here's the <a target="_blank" href="https://docs.google.com/spreadsheets/d/1I3mjQgfaZ9hFuUui6irpTdXg17TZXfK_jjtMvPrlGlM/edit?usp=sharing">link to the spreadsheet</a> we'll be making if you'd like to check it out while you follow along:</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQF91mJiUd4F5w/article-inline_image-shrink_1500_2232/0/1684162312276?e=1689811200&amp;v=beta&amp;t=ue0QHmYwX0I7oqirS6GZx66YXl5y_-zSkA6iPdDGKBM" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>Let's go gif</em></p>
<h3 id="heading-video-walkthrough-available">Video Walkthrough Available</h3>
<p>If you'd like to check out a video walkthrough of the Google Sheet, here you go:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/LYN3Cvlsflg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-project-setup">Project Setup</h2>
<p>Create a new Google Sheet by either going to your Google Drive and selecting NEW -&gt; Google Sheet or by simply typing in sheets.new in the URL bar of your browser.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQGtAhxBgZCiPQ/article-inline_image-shrink_1500_2232/0/1684161563448?e=1689811200&amp;v=beta&amp;t=5TuDNK0iSggXlKST3fzl-wv5JV04qwbYizc3ev8F51E" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Google Drive</em></p>
<p>Since this is a gameboard, we are going to give it a little bit of formatting to look good, add data validation and conditional formatting to add functionality to the game, and create useable buttons for our scorecard.</p>
<p>Here's what we'll end up with:</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQFmLTdzhlehew/article-inline_image-shrink_1000_1488/0/1684161671894?e=1689811200&amp;v=beta&amp;t=2nJ0ZTnaCo2Dtq7u3zzSP7av2MHjtPtAyVp7dRQUwvY" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Tic Tac Toe Google Sheet</em></p>
<p>Let's remove gridlines, add borders to the gameboard and the scorecard, and set an alternative font for the board.</p>
<p>To get rid of gridlines, select View -&gt; Show -&gt; Gridlines to uncheck this option.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQFsYtEPWEAxjA/article-inline_image-shrink_400_744/0/1684161946643?e=1689811200&amp;v=beta&amp;t=r6rUrzy6NSj-KQDb0o7Jx64N_u3CmTWQJxr_KaTAtII" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Google Sheets view options</em></p>
<p>To get a nice square grid with large X's and O's, I set the row height and column width of rows 2 - 4 and columns B - D by highlighting them, right clicking, and selecting the resize options.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQGJGcSpYb2KyA/article-inline_image-shrink_1000_1488/0/1684162096408?e=1689811200&amp;v=beta&amp;t=uU37mbBSZBSMgi25ICD9r3hzAyCkepCmXAYx2ebCKsw" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of resizing columns in Google Sheets</em></p>
<p>I chose 150 pixels for the height and width. You'll need to do these separately – you cannot change both the row height and column width at the same time.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQHzgbT4rS6f6w/article-inline_image-shrink_1000_1488/0/1684162162590?e=1689811200&amp;v=beta&amp;t=J-yExtOPV3icc6-YhGUmWESA0FUMzaJQu6N4qemzCwU" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of resizing columns in Google Sheets</em></p>
<p>For the font size of the board, select 100, and for the Font, I am using Lexend. You can add additional Google Fonts from the toolbar dropdown:</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQF6Ss_zEGVSug/article-inline_image-shrink_1500_2232/0/1684162246754?e=1689811200&amp;v=beta&amp;t=R548yqr57k0ffuORMeqbZ3fmhQEWYL_QCiJv1EOGNo4" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Fonts options in Google Sheets</em></p>
<p>Add a border to the board and the scorecard areas by highlighting the cells and then selecting the border options from the toolbar.</p>
<p>Click and drag over cells to select the whole range, and hold down the CTRL button to click and drag a second area. You can style these at the same time.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQHGcJin6dOdtw/article-inline_image-shrink_1000_1488/0/1684162477801?e=1689811200&amp;v=beta&amp;t=lfxyTUvqmv7KjhZ5B2X9eDeVw9bWVm5rNiCBmReF6OE" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of border options in Google Sheets</em></p>
<h2 id="heading-data-validation">Data Validation</h2>
<p>Highlight the gameboard (B2:D4) and select Data -&gt; Data validation from the menu.</p>
<p>This allows us to select Dropdown as the Criteria and add X and O as the two options to select.</p>
<p>Then click Advanced options and select Reject the input if the data is invalid, and plain text for the display style. This will keep the dropdown chips and handles from cluttering the gameboard.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQGj3dQDQ4QGuQ/article-inline_image-shrink_1500_2232/0/1684162681967?e=1689811200&amp;v=beta&amp;t=_HfNZ0C9L7tWucbWMMpzKf9gItYhkMP3G1cRlVGioxQ" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Data validation menu in Google Sheets</em></p>
<h2 id="heading-conditional-formatting">Conditional Formatting</h2>
<p>We'll use conditional formatting for our gameboard also. We need to check for all the winning conditions, and if one of the players gets three in a row, we will highlight those cells.</p>
<p>Keeping the gameboard highlighted, select Format -&gt; Conditional formatting.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQFJwi61h00_3g/article-inline_image-shrink_1000_1488/0/1684162938075?e=1689811200&amp;v=beta&amp;t=rdKBw21dV6Q82CgxNfiOG8Zg9N3fKXA135SauhAAYhA" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Format window in Google Sheets</em></p>
<p>There are eight conditions we'll check for three-in-a-row: going across x3, going down x3, and diagonal x2.</p>
<p>But we only need to write four formulas (two for the diagonals, one for across, and one for down) since we can use dollar ($) signs to drag the formula down and across for those.</p>
<p>For the down three-in-a-row:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Apply to range B2:D2 </span>
=AND($B2=$C2,$B2=$D2,ISTEXT($B2))
</code></pre>
<p>For the across three-in-a-row:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Apply to range B2:D2</span>
=AND(B$<span class="hljs-number">2</span>=B$<span class="hljs-number">3</span>,B$<span class="hljs-number">2</span>=B$<span class="hljs-number">4</span>,ISTEXT(B$<span class="hljs-number">3</span>))
</code></pre>
<p>For the diagonals we have to define them separately:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Apply to range B2, C3, D4 </span>
=AND($B$<span class="hljs-number">2</span>=$C$<span class="hljs-number">3</span>,$B$<span class="hljs-number">2</span>=$D$<span class="hljs-number">4</span>,ISTEXT($B$<span class="hljs-number">2</span>))

<span class="hljs-comment">//Apply to range B4, C3, D2 </span>
=AND($B$<span class="hljs-number">4</span>=$C$<span class="hljs-number">3</span>,$B$<span class="hljs-number">4</span>=$D$<span class="hljs-number">2</span>,ISTEXT($B$<span class="hljs-number">4</span>))
</code></pre>
<p>We test for equality of each cell and whether there is anything in the cell with the <code>=ISTEXT()</code> function. By wrapping each item in an <code>=AND()</code> function, we'll only apply the formatting if all conditions are met.</p>
<p>I selected a green background for the conditional formatting.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQERGL76FWm8nA/article-inline_image-shrink_1500_2232/0/1684163627050?e=1689811200&amp;v=beta&amp;t=9C0IASvwa_KE1wm68iez-FxJ2YjmuwDRB42-ASak_5s" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of conditional formatting window</em></p>
<h2 id="heading-apps-script">Apps Script</h2>
<p>Now for the scorecard logic. Let's open Apps Script by selecting Extensions -&gt; Apps Script from the menu:</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQHtQjZ3mujfUQ/article-inline_image-shrink_1500_2232/0/1684178999142?e=1689811200&amp;v=beta&amp;t=N5Wvx0y2md14-2Ih_PGj1_lHbKpW2mcEIPRNnRsvUAI" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of Apps Script menu</em></p>
<p>We'll write four functions to handle our logic:</p>
<ol>
<li><code>xScore()</code> will increment X's score in the scorecard</li>
<li><code>oScore()</code> will increment O's score in the scorecard</li>
<li><code>clearBoard()</code> will clear the board but keep the scores</li>
<li><code>reset()</code> will clear the board and set the scores back to zero</li>
</ol>
<p>To make things more legible, let's set a few named ranges.</p>
<p>Highlight the gameboard again and select Data -&gt; Named ranges. Give this range a name of <strong>Board</strong>. Do the same for cells G4 and H4 for <strong>xScore</strong> and <strong>oScore</strong>, respectively.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQHS7_YVdCFbog/article-inline_image-shrink_1500_2232/0/1684163925497?e=1689811200&amp;v=beta&amp;t=8-jk-X5iea045w1ZBkCqiExObkF6c4A572zR4dqIrI0" alt="No alt text provided for this image" width="600" height="400" loading="lazy"></p>
<p>Now for the scores, we'll have the exact same function for each using only the two different ranges: xScore for X and oScore for O. Here's how those will look using the xScore as an example:</p>
<p><strong><code>xScore()</code> &amp; <code>oScore()</code>:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">xScore</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> sheet = SpreadsheetApp.getActive(); 
    <span class="hljs-keyword">var</span> xScore = sheet.getRangeByName(<span class="hljs-string">'xScore'</span>).getValue();
    sheet.getRangeByName(<span class="hljs-string">'xScore'</span>).setValue(xScore+<span class="hljs-number">1</span>); clearBoard();
}
</code></pre>
<ul>
<li>Line 1: This sets a variable (we'll do this in each function) for the active spreadsheet.</li>
<li>Line 2: This sets a variable for xScore as the value in the named range xScore (cell G4)</li>
<li>Line 3: This sets a new value for the xScore cell as whatever it was plus 1.</li>
<li>Line 4: This runs the clearBoard() function which we'll write next...</li>
</ul>
<p><strong><code>clearBoard()</code>:</strong></p>
<p>This will simply clear the gameboard but leave the score board untouched.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">clearBoard</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> sheet = SpreadsheetApp.getActive();
    <span class="hljs-keyword">let</span> board = sheet.getRangeByName(<span class="hljs-string">'Board'</span>);
    board.clearContent(); 
}
</code></pre>
<ul>
<li>Line 1: Our sheet variable again.</li>
<li>Line 2: Our board variable. This is grabbing the range B2:D4 which we named 'Board'</li>
<li>Line3: This built-in <code>clearContent()</code> method simply clears everything in those cells. Pretty simple.</li>
</ul>
<p><strong><code>reset()</code>:</strong></p>
<p>Now we need a function to set the score board and gameboard back to their original states.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reset</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">let</span> sheet = SpreadsheetApp.getActive(); 
    sheet.getRangeByName(<span class="hljs-string">'xScore'</span>).setValue(<span class="hljs-number">0</span>);
    sheet.getRangeByName(<span class="hljs-string">'oScore'</span>).setValue(<span class="hljs-number">0</span>); clearBoard(); 
}
</code></pre>
<ul>
<li>Line 1: our active sheet</li>
<li>Line 2: we grab our xScore range and set its value to 0.</li>
<li>Line 3: we do the same for our oScore</li>
<li>Line 4: we run the reset function to handle the gameboard.</li>
</ul>
<p>And that's it! Now we can run any of these functions from within the Apps Script editor and see that they work.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQFUTfyjYKeECQ/article-inline_image-shrink_1000_1488/0/1684178952423?e=1689811200&amp;v=beta&amp;t=ek0cIfi0cCqZfWKM7q7ygA7n18pKwMD5wdqUVizCQjU" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>screenshot of running code within Apps Script editor</em></p>
<h2 id="heading-how-to-create-buttons">How to Create Buttons</h2>
<p>It would be a lot nicer to have buttons in our actual spreadsheet to be able to run the functions.</p>
<p>To do this, we'll draw a button and then assign a script to it.</p>
<p>Select Insert -&gt; Drawing from the menu.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQEmlXrm9lNOjw/article-inline_image-shrink_1500_2232/0/1684179236609?e=1689811200&amp;v=beta&amp;t=wSn2IgbM2H6_flsNE0CecTzLqKj9K2ILIgCDL9N5x9w" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>Screenshot of Insert menu in Google Sheets</em></p>
<p>You can draw anything you'd like, but I chose the basic rounded rectangle.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQFbc8Vp8xMAEw/article-inline_image-shrink_400_744/0/1684179297444?e=1689811200&amp;v=beta&amp;t=M7QO7ZdcylQ6W4grOmguGY3aI_S-G-cpAVWiJOiyMcc" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>Screenshot of shapes in Google Sheets drawings menu</em></p>
<p>Double click in the shape to add text, and resize, recolor, restyle as needed.</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQHSkIBOsRvNdg/article-inline_image-shrink_1000_1488/0/1684179429349?e=1689811200&amp;v=beta&amp;t=9G87KKPY_efHEOTU_K2POBbUzeSfFlbs5nG282Oo4Gc" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>Screenshot of button in Google Sheets</em></p>
<p>Once you've created your button, click Save and Close. Then resize and position it where you'd like it in the Google Sheet. I've put mine right under the scorecard, and I made one for each score as well as a reset button.</p>
<p>Finally, to make the button work, click the three little dots at the top right of the button and select <strong>assign script</strong>. Then type in the name of the script (without the parentheses).</p>
<p><img src="https://media.licdn.com/dms/image/D5612AQGCHPMJ8FW-hw/article-inline_image-shrink_1500_2232/0/1684179559428?e=1689811200&amp;v=beta&amp;t=41p0tXKvG3Moj8bTJAI45nUhcZAUjhzPNoSbD_IP57I" alt="No alt text provided for this image" width="600" height="400" loading="lazy">
<em>Screenshot of assigning a script to a button in Google Sheets</em></p>
<p>Now, all you've got to do is click one of the buttons and the assigned script will run 🔥.</p>
<p>Two notes:</p>
<ol>
<li>The first time you run a script, there will be a pop-up dialog box asking you to accept the security allowances. It's a safety net to make sure you know you're running the code that's written in Apps Script, and to examine it if you didn't write it. You'll need to click through those and accept the risk to allow it to run.</li>
<li>If you need to move a button after assigning the script, you may get frustrated when clicking it doesn't bring up the three dots for the menu and only runs the script. To get around this and allow for movement and the three dot menu, right click the button.</li>
</ol>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>I hope this has been helpful for you!</p>
<p>Please subscribe to <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">my YouTube channel here</a> for more content like this.</p>
<p>Have a great one!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google's New Cybersecurity Professional Certificate Explained ]]>
                </title>
                <description>
                    <![CDATA[ Google has released a new professional certificate in Cybersecurity. The announcement came on May 4th, 2023 and marks the 6th topical branch in their continually expanding certificate program. It follows five other successful entry-level certificate ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cybersecurity-professional-certificate-by-google/</link>
                <guid isPermaLink="false">66b8ddd4f805ffd579552e97</guid>
                
                    <category>
                        <![CDATA[ Certification ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Mon, 08 May 2023 21:38:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Cybersecurity-CertificateFCC.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google has released a new professional certificate in Cybersecurity. The <a target="_blank" href="https://blog.google/outreach-initiatives/grow-with-google/google-cybersecurity-career-certificate/">announcement</a> came on May 4th, 2023 and marks the 6th topical branch in their continually expanding certificate program.</p>
<p>It follows five other successful entry-level certificate programs in IT Support, Data Analytics, Digital Marketing &amp; E-commerce, Project Management and UX Design.</p>
<p>I made a first impressions video to accompany this article that you can find here:(more links in the summary at the bottom of the article, too)</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Q2w6fEFfWyQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-grow-with-google">What is "Grow with Google"?</h2>
<p>The Grow with Google program is for people interested in "training, tools and resources to grow skills, careers, or businesses". You can find all the certificate programs and resources <a target="_blank" href="https://grow.google/">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/grow-with-google-site.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Grow with Google website</em></p>
<p>Grow with Google's mission is to enable anyone to have access to quality technology training. They've been training digital skills since 2017, and currently partner with Coursera for course delivery.</p>
<p>Coursera's been in the MOOC (Massive Open Online Course) space since 2012, and has grown to be a leader in the online education world.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/faqs.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of FAQ from Grow With Google</em></p>
<p>Though Google has released a few Advanced level courses recently (<a target="_blank" href="https://www.freecodecamp.org/news/starting-and-excelling-in-data-analytics/">I wrote about this here</a>) in the Data Analytics, Business Intelligence and IT Automation tracts, the new Cybersecurity certificate has been designed with beginners in mind.</p>
<p>There is no experience necessary to begin. The structure of the certificate program starts in a foundational introductory module, works through some technical topics like SQL, Linux, and Python, and then culminates with a module on preparing for Cybersecurity Jobs.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/no-experience-required.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-get-job-ready">Get Job Ready</h2>
<p>This is also part of Google's Grow With Me pathways: they are partnering with businesses and universities to pair together jobs and program graduates.</p>
<p>The initial job platform was deprecated as of February 7th, 2023, but the new one for this year is maintained on <a target="_blank" href="https://www.careercircle.com/">CareerCircle</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/career-circle-screenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of CareerCircle</em></p>
<p>This is a strong draw to participants, especially as the entry-level salaries for many of the fields approach and exceed six figures. Cybersecurity has a $100K+ amount listed in the marketing material.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/cybersecurity-median-entry-salaries.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Cybersecurity marketing material for median entry salaries</em></p>
<p>Naturally, these amounts are easily skewed and may not be realistic depending on the applicant's background. But it's no secret that on the whole, these technical jobs do lead to higher paying salaries.</p>
<h2 id="heading-whats-the-coursework-like">What's the Coursework Like?</h2>
<p>I took a look through the 8 courses that make up the Cybersecurity certificate, and found it to be a similar makeup to the first Data Analytics certificate that I completed a couple years ago.</p>
<p>It begins with some basic overviewing of the field, and then moves into an assortment of high level concepts and technical skill building. Here is the full list:</p>
<ul>
<li>Foundations of Cybersecurity</li>
<li>Play it Safe: Manage Security Risks</li>
<li>Connect and Protect: Networks and Network Security</li>
<li>Tools of the Trade: Linux and SQL</li>
<li>Assets, Threats, and Vulnerabilities</li>
<li>Sound the Alarm: Detection and Response</li>
<li>Automate Cybersecurity Tasks with Python</li>
<li>Put it to Work: Prepare for Cybersecurity Jobs</li>
</ul>
<p>As you can see from some of the titles, Google does get a little general in their topics, which is to be expected in an introductory course.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/cybersecurity-professional-coursework.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Cybersecurity Professional Certificate coursework</em></p>
<p>They have also been long-winded in the video courses in my experience, and I recommend increasing the video playback speed to 1.5x or 2.0x normal speed. I found I had little difficulty in keeping up with the presenters when I did this in other courses.</p>
<h2 id="heading-more-course-details-and">More Course Details and $$$</h2>
<p>Coursera would like you to pay $49 a month for this certificate program, and that's perfectly reasonable. Especially since Google estimates you can complete it in 6 months by working only 7 hours a week</p>
<p>...and I estimate you can complete it in a max of 3 months working 7-10 hours a week. 😀</p>
<p>But, if you're strapped for cash, you can click into any one of the individual courses and <strong>audit the whole thing for FREE</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/corsera-course-audit.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Coursera course audit</em></p>
<p>You won't get the certificate, or access to the CareerCircle network, but if you're just leveling up your knowledge, you can do that for free.</p>
<p>You can also see each module's details within each of the courses. This detailed view breaks down each lesson to exactly what topics will be covered and how much time will be spent on each video, reading, or quiz.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/module-details.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is a great place to look in case you're not starting from zero and wonder if it will be repeating information you already know. I found that many of the items were very beginner-based (as they stated), especially in the Python course.</p>
<h2 id="heading-summary-links-and-video">Summary, Links, and Video</h2>
<p>This looks to be another solid offering from Google into a field that promises to be intriguing to many people.</p>
<p>If you're interested in Cybersecurity and have been wondering where to start, I believe this is as good an entry point as any.</p>
<ul>
<li>Check out my first impressions video <a target="_blank" href="https://youtu.be/Q2w6fEFfWyQ">here</a>.    </li>
<li>Check out the Coursera page <a target="_blank" href="https://www.coursera.org/professional-certificates/google-cybersecurity">here</a>.</li>
<li>Check out Google's Cybersecurity program overview page <a target="_blank" href="https://grow.google/certificates/cybersecurity/#?modal_active=none">here</a>.</li>
</ul>
<p>Have a great one!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
