Créer des événements de calendrier Google à partir de la feuille de calcul, mais éviter les doublons

j'essaie d'écrire un script qui va prendre des données d'une feuille de calcul Google et créer des événements dans mon calendrier Google.

j'ai réussi cette amende mais il a produit des doubles à chaque fois que je l'ai couru. Donc maintenant j'essaie d'empêcher cela en créant une colonne 17 dans la feuille de calcul avec un ID d'événement unique produit automatiquement pour chaque ligne et puis chaque fois que le script est exécuté il regardera L'ID d'événement pour chaque ligne et supprimera l'événement correspondant dans le calendrier avant de recréer avec les données d'origine ou des données mises à jour, si j'ai changé la ligne.

je suis nouveau dans les scripts de toutes sortes et j'ai concocté ça ensemble mais je suis en train de frapper un mur maintenant. Quelqu'un peut-il aider à résoudre cela?

function CalInsert() {
    var cal = CalendarApp.getDefaultCalendar();
    var id = SpreadsheetApp.getActiveSheet().getRange(2,17).getValue();

    if (id != 0) {
        var event = cal.getEventSeriesById(id);
        event.deleteEventSeries();
    }

    var sheet = SpreadsheetApp.getActiveSheet();
    var startRow = 2; // First row of data to process
    var numRows = sheet.getLastRow(); // Number of rows to process
    var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
    var data = dataRange.getValues();

    for (i in data) {
        var row = data[i];
        var title = row[0]; // First column
        var desc = row[13]; // Second column
        var tstart = row[14];
        var tstop = row[15];

        var event = cal.createEvent(title, tstart, tstop, {description:desc});
        var eventid = event.getId();
        SpreadsheetApp.getActiveSheet().getRange(2,17).setValue(eventid);
    }
}
23
demandé sur RalphD 2013-04-03 17:36:40

2 réponses

c'est très similaire à une question posée il y a deux jours, qui portait sur la synchronisation d'un tableur d'événements avec un calendrier. Il semble que vous vouliez considérer le tableur comme le maître des événements dont il est issu, ce qui simplifierait considérablement le problème. Les bases de ce que vous devez faire sont couverts par cette réponse. Si vous préférez modifier le code existant, j'ai une implémentation ci-dessous.

j'ai une version modifiée de la code de ce blog, qui modifiera les entrées de calendrier pré-existantes pour correspondre à l'information dans le tableur. J'ai disposé ma feuille de calcul différemment, et ceci est reflété dans le code.

Date | Titre | Heure De Début | Heure De Fin | Lieu |Description / id de l'événement

la colonne event ID est remplie par le script lorsque de nouveaux événements sont créés, et est ensuite utilisée dans des invocations ultérieures pour récupérez les événements du calendrier, évitant ainsi la duplication.

Script

/**
 * Adds a custom menu to the active spreadsheet, containing a single menu item
 * for invoking the exportEvents() function.
 * The onOpen() function, when defined, is automatically invoked whenever the
 * spreadsheet is opened.
 * For more information on using the Spreadsheet API, see
 * https://developers.google.com/apps-script/service_spreadsheet
 */
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Export Events",
    functionName : "exportEvents"
  }];
  sheet.addMenu("Calendar Actions", entries);
};

/**
 * Export events from spreadsheet to calendar
 */
function exportEvents() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "YOUR_CALENDAR_ID";
  var cal = CalendarApp.getCalendarById(calId);
  for (i=0; i<data.length; i++) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[0]);  // First column
    var title = row[1];           // Second column
    var tstart = new Date(row[2]);
    tstart.setDate(date.getDate());
    tstart.setMonth(date.getMonth());
    tstart.setYear(date.getYear());
    var tstop = new Date(row[3]);
    tstop.setDate(date.getDate());
    tstop.setMonth(date.getMonth());
    tstop.setYear(date.getYear());
    var loc = row[4];
    var desc = row[5];
    var id = row[6];              // Sixth column == eventId
    // Check if event already exists, update it if it does
    try {
      var event = cal.getEventSeriesById(id);
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    if (!event) {
      //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
      var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
      row[6] = newEvent;  // Update the data array with event ID
    }
    else {
      event.setTitle(title);
      event.setDescription(desc);
      event.setLocation(loc);
      // event.setTime(tstart, tstop); // cannot setTime on eventSeries.
      // ... but we CAN set recurrence!
      var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
      event.setRecurrence(recurrence, tstart, tstop);
    }
    debugger;
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);
}

Supprimer / Recréer

dans cette alternative, l'eventID est utilisé pour trouver et supprimer l'événement existant précédemment. Après cela, un nouvel événement est créé avec les données dans le tableur. Cela a l'avantage que toutes les valeurs de l'événement peuvent être mises à jour, y compris les heures de début et d'arrêt (Voir Notes ci-dessous). D'autre part, tout changement apporté à l'original l'événement sera perdu - par exemple, si d'autres personnes avaient été invités à l'événement, ou des rappels personnalisés ont été ajoutés.

Pour utiliser cette solution, il suffit de remplacer le code correspondant:

// Check if event already exists, delete it if it does
try {
  var event = cal.getEventSeriesById(id);
  event.deleteEventSeries();
  row[6] = '';  // Remove event ID    
}
catch (e) {
  // do nothing - we just want to avoid the exception when event doesn't exist
}
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
row[6] = newEvent;  // Update the data array with event ID
debugger;

Notes

  • la Documentation pour getEventSeriesById déclare à tort qu'il retourne null quand aucun événement correspondant n'est trouvé, quand à la place il lance une exception. (méchant! Donc je l'ai enfermé dans un bloc "essayer / attraper" juste pour continuer natation.
  • Malheureusement, alors que les getEventSeriesById fonctionne pour récupérer un événement, c' returnsEventSeries objet, qui ne prend pas en charge l' setTime() méthode. Si vous ne vous attendez pas à changer l'heure des événements, C'est OK. Sinon, vous pouvez modifier le Event dans un EventSeries en mettant le récurrence rules & times, ou supprimer l'ancien événement et en créer un nouveau, comme indiqué dans Supprimer / Recréer. numéro 1154.
  • La feuille de calcul gagne toujours. Tout changement d'événement (dans les champs pertinents) enregistré via le calendrier Google sera écrasé par le script.
36
répondu Mogsdad 2017-05-23 10:30:49

Id tiens à ce Post pour tous ceux qui voudraient l'utiliser, j'ai modifié le script à l'intérieur d'une feuille, j'étais déjà à l'aide. Le Format de la Date et la duplication des événements étaient quelques problèmes qui devaient être résolus, mais après quelques tests, je suis assez satisfait de la façon dont cela fonctionne.Je L'utilise pour réserver des emplois et les partager avec mes employés qui sont mobiles et font des travaux de construction à travers la ville. La prochaine étape est de tirer des événements de calendrier sur le tableur de sorte qu'il peut fonctionner dans les deux sens et je peux utiliser l'application de calendrier sur mon téléphone pour réserver des travaux à la volée donc si quelqu'un a des conseils im tous les oreilles, aussi j'ai encore besoin d'un script pour insérer des données de réponse de formulaire dans la même feuille et ajouter des lignes complètes où les numéros de travail correspondent en gardant les données existantes intactes.

`function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Export Events",
functionName : "exportEvents"
}];     sheet.addMenu("Calendar Actions", entries);
};

function parseDate(s) {
var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,
            jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
var p = s.replace(".", "").split('-');
return new Date(p[2], months[p[1].toLowerCase()], p[0]);
}

/**
* Export events from spreadsheet to calendar
*/
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();

var headerRows = 6;  // Number of rows of header info (to skip)
var range = sheet.getDataRange();
var data = range.getDisplayValues();
//var calId = "Your calendar Id"; // PRODUCTION
var calId = "Your_calendar Id to test"; // TEST
var cal = CalendarApp.getCalendarById(calId);
//Logger.log(cal);
//Logger.log(data.length);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue; // Skip header row(s)
if (data[i][0].length < 1) continue; // Skip if no content.

var row    = data[i];
Logger.log(row);
var date   = parseDate(row[0]);  // First column
//Logger.log(date);
var title  = row[1];           // Second column

var tstart = new Date();
var s = row[2].split(":");
tstart.setHours(s[0]);
tstart.setMinutes(s[1]);
tstart.setSeconds(s[2]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());

var tstop = new Date();
var e = row[3].split(":");
tstop.setHours(e[0]);
tstop.setMinutes(e[1]);
tstop.setSeconds(e[2]);

tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc  = row[4];
var desc = row[5];
var id   = row[6];              // Sixth column == eventId
// Check if event already exists, update it if it does
var event = null;
if (id.length > 0) {
try {
event = cal.getEventSeriesById(id);
}
catch (e) {
// do nothing - we just want to avoid the exception when event doesn't            exist
} 
}
if (!event) {
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new
Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createEvent(title, tstart, tstop,                                     
{description:desc,location:loc}).getId();                     
var r = i + 1;
var cell = sheet.getRange("G" + r);
cell.setValue(newEvent);
}
else {
Logger.log(event);
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
// event.setTime(tstart, tstop); // cannot setTime on eventSeries.
// ... but we CAN set recurrence!
var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
event.setRecurrence(recurrence, tstart, tstop);
}
debugger;
}
}

`

3
répondu Jarrod Rapson 2016-06-27 12:54:04