5

I have a Google Slides presentation with charts that are linked to a specific Google Sheets Spreadsheet.

As there are many charts in the presentation, I'm looking for a way to update all these linked charts automatically, or at least all of them at once.

What is the best way to do this?

AviG
  • 83
  • 1
  • 2
  • 5

3 Answers3

9

You can add a custom function to a dropdown menu in the Slides UI with the following script. This gets the slides from the current presentation, loops through them, gets any charts in each slides and refreshes (updates) them.

function onOpen() {
  var ui = SlidesApp.getUi();
  ui.createMenu('Custom Menu')
  .addItem('Batch Update Charts', 'batchUpdate')
  .addToUi();
}

function batchUpdate(){

  var gotSlides = SlidesApp.getActivePresentation().getSlides();

  for (var i = 0; i < gotSlides.length; i++) {
    var slide = gotSlides[i];
    var sheetsCharts = slide.getSheetsCharts();
    for (var k = 0; k < sheetsCharts.length; k++) {
      var shChart = sheetsCharts[k];
      shChart.refresh();
    }
  }
}

Note: The functionality to update/refresh linked Slides doesn't appear to exist at the time of this response.

  • I tried running this script for my Google Presentations today and it worked perfectly. Now I wonder if anyone tried and adapted it successfully to Google Docs. I'm not experienced, but have tried a lot and I could not do it. And I did not find any posts specifically about the DocumentApp that has worked. Does anyone have any ideas about this? – Ivan Sinigaglia May 11 '19 at 11:58
  • 1
    How to get the function to appear in the custom menu once it is written in the script editor? – 4Z4T4R Jan 22 '20 at 18:39
  • 1
    @azatar - Save the script and reload the Slides and "OnOpen" the script should .createMenu and .addItem to the UI on its own. You may have to try to "run" the script one time in the Google Apps Script window first to grant permissions in advance. – Aleister Tanek Javas Mraz Jan 22 '20 at 19:58
  • 1
    Sweet, great help. Is there a way to refresh **tables** on the page too?? I don't see how to do that after looking at the API docs. – 4Z4T4R Jan 23 '20 at 19:39
  • 1
    @azatar I did a quick GSearch and found someone else asking the same here: https://stackoverflow.com/questions/48665888/using-google-appscript-to-refresh-tables-pasted-in-from-google-sheets-into-googl Looks like there is a feature request in an "assigned" state for refresh()'ing tables: https://issuetracker.google.com/issues/64027131 – Aleister Tanek Javas Mraz Jan 24 '20 at 15:02
  • @azatar I found this in the issuetracker link: "If anyone is reading this who wants the feature, one solution is to create a "table chart" in your sheet, from your existing table (that you were trying to link/update). It doesn't allow you to copy and paste from Sheets to Slides, but within Slides if you go to Insert -> Chart -> From Spreadsheet, then choose your sheet and chart (table). You can then use app scripts to automatically update it, as you can with a chart." Hope that helps ~! – Aleister Tanek Javas Mraz Jan 24 '20 at 15:05
  • Where do we find the UI? It sdoesnt seem to appear on mine :/ I have added script, run once, and opened in incognito to test. Nada. – Chen_Dogg Mar 30 '20 at 14:11
2

You can find it in official documentation about API (for different lang). https://developers.google.com/slides/how-tos/add-chart#refreshing_a_chart

You need to write a script for this and run it by schedule or manually.

I have found my own code that worked great.

from __future__ import print_function
import httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/slides.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Slides API Python Quickstart'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'slides.googleapis.com-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def main():
    """Shows basic usage of the Slides API.

    Creates a Slides API service object and prints the number of slides and
    elements in a sample presentation:
    """
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('slides', 'v1', http=http)

    # Here past your presentation id
    presentationId = '1Owma9l9Z0Xjm1OPp-fcchdcxc1ImBPY2j9QH1LBDxtk'
    presentation = service.presentations().get(
        presentationId=presentationId).execute()
    slides = presentation.get('slides')

    print ('The presentation contains {} slides:'.format(len(slides)))
    for slide in slides:
        for element in slide['pageElements']:

            presentation_chart_id = element['objectId']

            # Execute the request.
            try:
                requests = [{'refreshSheetsChart': {'objectId': presentation_chart_id}}]
                body = {'requests': requests}

                #print(element)
                requests = service.presentations().batchUpdate(
                    presentationId=presentationId, body=body).execute()
                print('Refreshed a linked Sheets chart with ID: {0}'.format(presentation_chart_id))

            except Exception:
                pass

if __name__ == '__main__':
    main()
2

Latest update: There is now an option in Slides's Tools drop-down menu to see all Linked Objects; the menu that appears has the option at the bottom to "Update all".

enter image description here enter image description here

  • 1
    Neat, but this does not "update all linked charts automatically", as per the question. You still have to manually hit buttons. – Jerther May 31 '22 at 20:57
  • 1
    @Jerther True, although the question does follow: "I'm looking for a way to update all these linked charts automatically, or at least all of them at once." – Aleister Tanek Javas Mraz Jun 01 '22 at 21:09