Entfernungen berechnen und Meter in Meilen umrechnen

Programmierstufe: Anfänger
Dauer: 10 Minuten
Projekttyp: Benutzerdefinierte Funktion und Automatisierung mit einem benutzerdefinierten Menü

Zielsetzungen

  • Verstehen Sie, was die Lösung leisten kann.
  • Was die Apps Script-Dienste innerhalb der Lösung leisten
  • Richten Sie das Skript ein.
  • Führen Sie das Skript aus.

Informationen zu dieser Lösung

Mit benutzerdefinierten Funktionen können Sie die Fahrstrecke zwischen zwei Standorten berechnen und die Entfernung von Meter in Meilen umrechnen. Eine zusätzliche Automatisierung bietet ein benutzerdefiniertes Menü, über das Sie in einem neuen Tabellenblatt Schritt-für-Schritt-Anleitungen von der Start- bis zur Zieladresse hinzufügen können.

Screenshot einer Wegbeschreibung in einem Tabellenblatt.

Funktionsweise

Im Script werden zwei benutzerdefinierte Funktionen und eine Automatisierung verwendet.

  • Die Funktion drivingDistance(origin, destination) verwendet den Maps-Dienst, um die Route zwischen zwei Standorten zu berechnen und die Entfernung zwischen den beiden Adressen in Metern zurückzugeben.
  • Mit der Funktion metersToMiles(meters) wird die äquivalente Anzahl von Meilen für eine bestimmte Anzahl von Metern berechnet.
  • Bei der Automatisierung wird der Nutzer aufgefordert, die Zeilen von Start- und Zieladressen einzugeben, für die die Route berechnet werden soll. Anschließend wird die Schritt-für-Schritt-Anleitung in ein neues Tabellenblatt eingefügt.

Apps Script-Dienste

Diese Lösung verwendet die folgenden Dienste:

  • Tabellendienst: Damit wird das benutzerdefinierte Menü hinzugefügt und Demodaten zum Testen dieser Lösung hinzugefügt. Die neuen Tabellenblätter werden formatiert, wenn vom Skript Wegbeschreibungen hinzugefügt werden.
  • Basisdienst: Verwendet die Klasse Browser, um den Nutzer zur Eingabe einer Zeilennummer für Wegbeschreibungen aufzufordern und den Nutzer zu benachrichtigen, wenn ein Fehler auftritt.
  • Dienstprogrammdienst: Aktualisiert Vorlagen-Strings mit benutzerdefinierten Informationen.
  • Maps-Dienst: Ruft detaillierte Routen in Google Maps von der Start- bis zur Zieladresse ab.

Voraussetzungen

Sie benötigen die folgenden Voraussetzungen, um dieses Beispiel verwenden zu können:

  • Ein Google-Konto (Google Workspace-Konten erfordern möglicherweise die Administratorgenehmigung).
  • Ein Webbrowser mit Zugang zum Internet.

Skript einrichten

  1. Erstellen Sie eine Kopie der Tabelle Fahrstrecke berechnen und Meter in Meilen umrechnen. Das Apps Script-Projekt für diese Lösung ist an die Tabelle angehängt.
    Kopie erstellen
  2. Wenn Sie Überschriften und Demodaten in Ihre Tabelle einfügen möchten, klicken Sie auf Directions > Tabellenblatt vorbereiten. Möglicherweise müssen Sie die Seite aktualisieren, damit dieses benutzerdefinierte Menü angezeigt wird.
  3. Autorisieren Sie das Skript, wenn Sie dazu aufgefordert werden. Wenn auf dem OAuth-Zustimmungsbildschirm die Warnung Diese Anwendung wurde nicht überprüft angezeigt wird, wählen Sie Erweitert > Zu {Projektname} (unsicher) aus.

  4. Klicken Sie noch einmal auf Wegbeschreibung > Tabellenblatt vorbereiten.

Skript ausführen

  1. Geben Sie in Zelle C2 die Formel =DRIVINGDISTANCE(A2,B2) ein und drücken Sie die Eingabetaste. Wenn Sie sich an einem Ort befinden, an dem Dezimaltrennzeichen verwendet werden, müssen Sie möglicherweise stattdessen =DRIVINGDISTANCE(A2;B2) eingeben.
  2. Geben Sie in Zelle D2 die Formel =METERSTOMILES(C2) ein und drücken Sie die Eingabetaste.
  3. (Optional) Fügen Sie zusätzliche Zeilen mit Start- und Zieladressen hinzu und kopieren Sie die Formeln in die Spalten C und D, um die Fahrtentfernungen zwischen verschiedenen Orten zu berechnen.
  4. Klicken Sie auf Routenplaner > Detaillierte Anleitung generieren.
  5. Geben Sie im Dialogfeld die Zeilennummer der Adressen ein, für die Sie eine Wegbeschreibung generieren möchten, und klicken Sie auf OK.
  6. Sehen Sie sich die Wegbeschreibung in dem neuen Tabellenblatt an, das vom Skript erstellt wird.

Code ansehen

Klicken Sie unten auf Quellcode anzeigen, um den Apps Script-Code für diese Lösung zu sehen:

Quellcode ansehen

Code.gs

sheets/customFunctions/customFunctions.gs
/**
 * @OnlyCurrentDoc Limits the script to only accessing the current sheet.
 */

/**
 * A special function that runs when the spreadsheet is open, used to add a
 * custom menu to the spreadsheet.
 */
function onOpen() {
  try {
    const spreadsheet = SpreadsheetApp.getActive();
    const menuItems = [
      {name: 'Prepare sheet...', functionName: 'prepareSheet_'},
      {name: 'Generate step-by-step...', functionName: 'generateStepByStep_'}
    ];
    spreadsheet.addMenu('Directions', menuItems);
  } catch (e) {
    // TODO (Developer) - Handle Exception
    console.log('Failed with error: %s' + e.error);
  }
}

/**
 * A custom function that converts meters to miles.
 *
 * @param {Number} meters The distance in meters.
 * @return {Number} The distance in miles.
 */
function metersToMiles(meters) {
  if (typeof meters !== 'number') {
    return null;
  }
  return meters / 1000 * 0.621371;
}

/**
 * A custom function that gets the driving distance between two addresses.
 *
 * @param {String} origin The starting address.
 * @param {String} destination The ending address.
 * @return {Number} The distance in meters.
 */
function drivingDistance(origin, destination) {
  const directions = getDirections_(origin, destination);
  return directions.routes[0].legs[0].distance.value;
}

/**
 * A function that adds headers and some initial data to the spreadsheet.
 */
function prepareSheet_() {
  try {
    const sheet = SpreadsheetApp.getActiveSheet().setName('Settings');
    const headers = [
      'Start Address',
      'End Address',
      'Driving Distance (meters)',
      'Driving Distance (miles)'];
    const initialData = [
      '350 5th Ave, New York, NY 10118',
      '405 Lexington Ave, New York, NY 10174'];
    sheet.getRange('A1:D1').setValues([headers]).setFontWeight('bold');
    sheet.getRange('A2:B2').setValues([initialData]);
    sheet.setFrozenRows(1);
    sheet.autoResizeColumns(1, 4);
  } catch (e) {
    // TODO (Developer) - Handle Exception
    console.log('Failed with error: %s' + e.error);
  }
}

/**
 * Creates a new sheet containing step-by-step directions between the two
 * addresses on the "Settings" sheet that the user selected.
 */
function generateStepByStep_() {
  try {
    const spreadsheet = SpreadsheetApp.getActive();
    const settingsSheet = spreadsheet.getSheetByName('Settings');
    settingsSheet.activate();

    // Prompt the user for a row number.
    const selectedRow = Browser
        .inputBox('Generate step-by-step', 'Please enter the row number of' +
        ' the' + ' addresses to use' + ' (for example, "2"):',
        Browser.Buttons.OK_CANCEL);
    if (selectedRow === 'cancel') {
      return;
    }
    const rowNumber = Number(selectedRow);
    if (isNaN(rowNumber) || rowNumber < 2 ||
      rowNumber > settingsSheet.getLastRow()) {
      Browser.msgBox('Error',
          Utilities.formatString('Row "%s" is not valid.', selectedRow),
          Browser.Buttons.OK);
      return;
    }


    // Retrieve the addresses in that row.
    const row = settingsSheet.getRange(rowNumber, 1, 1, 2);
    const rowValues = row.getValues();
    const origin = rowValues[0][0];
    const destination = rowValues[0][1];
    if (!origin || !destination) {
      Browser.msgBox('Error', 'Row does not contain two addresses.',
          Browser.Buttons.OK);
      return;
    }

    // Get the raw directions information.
    const directions = getDirections_(origin, destination);

    // Create a new sheet and append the steps in the directions.
    const sheetName = 'Driving Directions for Row ' + rowNumber;
    let directionsSheet = spreadsheet.getSheetByName(sheetName);
    if (directionsSheet) {
      directionsSheet.clear();
      directionsSheet.activate();
    } else {
      directionsSheet =
        spreadsheet.insertSheet(sheetName, spreadsheet.getNumSheets());
    }
    const sheetTitle = Utilities
        .formatString('Driving Directions from %s to %s', origin, destination);
    const headers = [
      [sheetTitle, '', ''],
      ['Step', 'Distance (Meters)', 'Distance (Miles)']
    ];
    const newRows = [];
    for (const step of directions.routes[0].legs[0].steps) {
      // Remove HTML tags from the instructions.
      const instructions = step.html_instructions
          .replace(/<br>|<div.*?>/g, '\n').replace(/<.*?>/g, '');
      newRows.push([
        instructions,
        step.distance.value
      ]);
    }
    directionsSheet.getRange(1, 1, headers.length, 3).setValues(headers);
    directionsSheet.getRange(headers.length + 1, 1, newRows.length, 2)
        .setValues(newRows);
    directionsSheet.getRange(headers.length + 1, 3, newRows.length, 1)
        .setFormulaR1C1('=METERSTOMILES(R[0]C[-1])');

    // Format the new sheet.
    directionsSheet.getRange('A1:C1').merge().setBackground('#ddddee');
    directionsSheet.getRange('A1:2').setFontWeight('bold');
    directionsSheet.setColumnWidth(1, 500);
    directionsSheet.getRange('B2:C').setVerticalAlignment('top');
    directionsSheet.getRange('C2:C').setNumberFormat('0.00');
    const stepsRange = directionsSheet.getDataRange()
        .offset(2, 0, directionsSheet.getLastRow() - 2);
    setAlternatingRowBackgroundColors_(stepsRange, '#ffffff', '#eeeeee');
    directionsSheet.setFrozenRows(2);
    SpreadsheetApp.flush();
  } catch (e) {
    // TODO (Developer) - Handle Exception
    console.log('Failed with error: %s' + e.error);
  }
}

/**
 * Sets the background colors for alternating rows within the range.
 * @param {Range} range The range to change the background colors of.
 * @param {string} oddColor The color to apply to odd rows (relative to the
 *     start of the range).
 * @param {string} evenColor The color to apply to even rows (relative to the
 *     start of the range).
 */
function setAlternatingRowBackgroundColors_(range, oddColor, evenColor) {
  const backgrounds = [];
  for (let row = 1; row <= range.getNumRows(); row++) {
    const rowBackgrounds = [];
    for (let column = 1; column <= range.getNumColumns(); column++) {
      if (row % 2 === 0) {
        rowBackgrounds.push(evenColor);
      } else {
        rowBackgrounds.push(oddColor);
      }
    }
    backgrounds.push(rowBackgrounds);
  }
  range.setBackgrounds(backgrounds);
}

/**
 * A shared helper function used to obtain the full set of directions
 * information between two addresses. Uses the Apps Script Maps Service.
 *
 * @param {String} origin The starting address.
 * @param {String} destination The ending address.
 * @return {Object} The directions response object.
 */
function getDirections_(origin, destination) {
  const directionFinder = Maps.newDirectionFinder();
  directionFinder.setOrigin(origin);
  directionFinder.setDestination(destination);
  const directions = directionFinder.getDirections();
  if (directions.status !== 'OK') {
    throw directions.error_message;
  }
  return directions;
}

Beitragende

Dieses Beispiel wird von Google mit Unterstützung von Google Developers-Experten verwaltet.

Nächste Schritte