Partage et niveaux d’accès
Fichier > Partager > Partager avec des personnes et groupes
Niveaux:
Lecteur peut voir, pas commenter ni modifier
Commentateur peut insérer des commentaires
Éditeur peut modifier le contenu et la structure
Liens d'accès:
Restreint (par défaut): seuls les invités ajoutés voient le fichier
Toute personne avec le lien (Lecteur/Commentateur/Éditeur)
Bonnes pratiques:
- Grouper les éditeurs par groupe Google Workspace (groupe-commercial@itsc.sn)
- Ne jamais mettre un fichier sensible en "Public sur le web"
- Protéger les feuilles ou plages critiques (Données > Protéger les feuilles)
Collaboration en direct : marqueurs utiles
- Curseurs colorés par utilisateur (visibles en temps réel)
- @mention dans un commentaire envoie une notification email
- Historique: Fichier > Historique des versions > Afficher l'historique
- Nommer une version: "Avant présentation Q2"
- Reconnaissance d'auteur par cellule (cmd/ctrl + Alt + Shift + H)
Fonctions puissantes propres à Sheets
// QUERY — SQL-like sur une plage
=QUERY(Ventes!A1:F10000;
"SELECT B, SUM(E)
WHERE C = 'Dakar' AND D > date '2026-01-01'
GROUP BY B
ORDER BY SUM(E) DESC
LABEL SUM(E) 'CA Total'
FORMAT SUM(E) '#,##0 FCFA'"; 1)
// IMPORTRANGE — relier plusieurs classeurs
=IMPORTRANGE(
"https://docs.google.com/spreadsheets/d/ABC123.../edit";
"Ventes!A1:F10000")
// Une fois autorisé, combinable avec QUERY:
=QUERY(IMPORTRANGE("ABC123..."; "Ventes!A:F");
"SELECT Col2, SUM(Col5) WHERE Col3='Dakar' GROUP BY Col2"; 1)
// IMPORTHTML / IMPORTXML — scrapper une page publique
=IMPORTHTML("https://www.bceao.int/fr/taux-directeur"; "table"; 1)
=IMPORTXML("https://example.sn/sitemap.xml"; "//loc")
// ARRAYFORMULA — étendre une formule sur toute la colonne
=ARRAYFORMULA(SI(ESTVIDE(A2:A); ""; B2:B * 1,18))
// FILTER — filtrage dynamique sans macro
=FILTER(A2:F; C2:C="Dakar"; E2:E>100000)
// UNIQUE + SORT — listes dynamiques
=SORT(UNIQUE(FILTER(A2:A; A2:A<>"")))
GOOGLEFINANCE et GOOGLETRANSLATE
// Taux USD/XOF en temps réel
=GOOGLEFINANCE("CURRENCY:USDXOF")
// Historique 30 jours
=GOOGLEFINANCE("CURRENCY:USDXOF"; "close"; AUJOURDHUI()-30; AUJOURDHUI())
// Traduction automatique d'une colonne
=ARRAYFORMULA(GOOGLETRANSLATE(A2:A; "fr"; "en"))
Mise en forme conditionnelle avec formules
Format > Mise en forme conditionnelle > La formule personnalisée est:
=$E2 > $F2 * 1,1 // rouge si réel dépasse budget +10%
=ET($B2="Dakar"; $D2<AUJOURDHUI()) // bleu si client Dakar en retard
=NB.SI($A$2:$A$1000; $A2) > 1 // jaune si doublon
Apps Script — automatiser Google Sheets
// Extensions > Apps Script
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('ITSkillsCenter')
.addItem('Envoyer résumé quotidien', 'envoyerResume')
.addItem('Marquer factures payées', 'marquerPayees')
.addToUi();
}
function envoyerResume() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Ventes');
const data = sheet.getRange('A2:E').getValues().filter(r => r[0]);
const total = data.reduce((s, r) => s + r[4], 0);
const parRegion = data.reduce((acc, r) => {
acc[r[1]] = (acc[r[1]] || 0) + r[4];
return acc;
}, {});
const html = `
<h2>Résumé du ${new Date().toLocaleDateString('fr-FR')}</h2>
<p><strong>CA total:</strong> ${total.toLocaleString('fr-FR')} FCFA</p>
<ul>${Object.entries(parRegion).map(([k,v]) =>
`<li>${k}: ${v.toLocaleString('fr-FR')} FCFA</li>`).join('')}</ul>
`;
MailApp.sendEmail({
to: 'direction@itsc.sn',
subject: `[Ventes] Résumé du jour - ${total.toLocaleString('fr-FR')} FCFA`,
htmlBody: html,
});
}
Déclencheurs automatiques
// Déclencheur temporel: tous les jours à 18h
function creerTrigger() {
ScriptApp.newTrigger('envoyerResume')
.timeBased()
.everyDays(1)
.atHour(18)
.create();
}
// Déclencheur sur modification: valider les données à la saisie
function onEdit(e) {
if (e.range.getSheet().getName() !== 'Factures') return;
if (e.range.getColumn() !== 3) return; // colonne Montant
const montant = e.value;
if (isNaN(montant) || montant < 0) {
e.range.setBackground('#fde2e2');
e.range.setNote('Le montant doit être un nombre positif');
} else {
e.range.setBackground(null);
e.range.clearNote();
}
}
Appel d’une API externe depuis Apps Script
function enrichirAvecClaudeAPI() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getRange('A2:B10').getValues();
data.forEach((row, i) => {
const question = row[0];
if (!question || row[1]) return;
const response = UrlFetchApp.fetch('https://api.anthropic.com/v1/messages', {
method: 'post',
contentType: 'application/json',
headers: {
'x-api-key': PropertiesService.getScriptProperties().getProperty('ANTHROPIC_KEY'),
'anthropic-version': '2023-06-01',
},
payload: JSON.stringify({
model: 'claude-haiku-4-5',
max_tokens: 300,
messages: [{role: 'user', content: question}],
}),
});
const json = JSON.parse(response.getContentText());
sheet.getRange(i + 2, 2).setValue(json.content[0].text);
Utilities.sleep(500);
});
}
Protéger des plages sensibles
function proteger() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Salaires');
const protection = sheet.protect().setDescription('Accès direction uniquement');
protection.addEditor('directrice@itsc.sn');
protection.removeEditors(protection.getEditors());
protection.setDomainEdit(false);
}
Validation de données
Données > Validation des données > Ajouter une règle:
Région (menu déroulant depuis liste):
Critère: Liste à partir d'une plage
Plage: =Config!$A$2:$A$10
Date plausible:
Critère: La date se situe entre 01/01/2020 et AUJOURDHUI()+365
Email valide:
Critère: Le texte correspond à l'expression régulière
Pattern: ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
Montant positif:
Critère: La valeur est un nombre
Entre 0 et 1000000000
Refuser la saisie si invalide (pas juste un avertissement)
Connecter Sheets à une base SQL via Connected Sheets
Données > Connecteurs de données > BigQuery / Looker / Salesforce
- Requête SQL paramétrée dans la feuille
- Rafraichissement manuel ou planifié
- Tables de milliards de lignes restent côté BigQuery
- L'utilisateur voit une feuille native rapide
Exemple BigQuery:
SELECT region, SUM(ca) AS total
FROM `projet.analytics.ventes_2026`
WHERE date >= @periode_debut
GROUP BY region
Historique des versions + commentaires
Fichier > Historique des versions > Afficher l'historique
Ctrl+Alt+Shift+H raccourci
Pour chaque modification:
- Nommer la version (Avant/Après migration, Présentation Q2)
- Restaurer une version antérieure
- Voir qui a modifié quoi
Commentaires:
- Sélectionner cellule > Insertion > Commentaire
- @nom pour notifier
- Résoudre une fois traité
- Recherche de commentaires: bouton cloche en haut à droite
Déploiement en Web App
// Apps Script > Déployer > Nouveau déploiement > Web app
function doGet(e) {
const sheet = SpreadsheetApp.openById('ID_SHEET').getSheetByName('Prix');
const produit = e.parameter.produit;
const prix = sheet.getRange('B2:B1000').getValues().flat();
const codes = sheet.getRange('A2:A1000').getValues().flat();
const index = codes.indexOf(produit);
return ContentService.createTextOutput(JSON.stringify({
produit,
prix: index >= 0 ? prix[index] : null,
})).setMimeType(ContentService.MimeType.JSON);
}
// Accessible via:
// https://script.google.com/macros/s/DEPLOY_ID/exec?produit=FORMATION-EXCEL-N2
Quand préférer Excel à Sheets
Sheets: collaboration temps réel, < 10 M cellules, partage simple, gratuit
Excel: modèles > 10 M cellules, Power Query complet, VBA riche, formats rares
Hybride: Sheets en front user, export Excel mensuel pour comptabilité