Cette question a maintenant eu plus de 12K vues - il est donc temps pour une mise à jour, car les caractéristiques de performance des nouvelles feuilles sont différentes de lorsque Serge a effectué ses tests initiaux.
Bonne nouvelle : les performances sont bien meilleures dans l'ensemble !
Le plus rapide :
Comme dans le premier test, lire les données de la feuille une seule fois, puis opérer sur le tableau, a donné un énorme bénéfice en termes de performances. Fait intéressant, la fonction originale de Don a mieux performé que la version modifiée testée par Serge. (Il semble que while
est plus rapide que for
, ce qui n'est pas logique.)
Le temps d'exécution moyen sur les données d'échantillon est seulement de 38ms, en baisse par rapport aux 168ms précédents.
// Approche du tableau de Don - vérifie uniquement la première colonne
// Avec condition d'arrêt ajoutée et bon résultat.
// De la réponse https://stackoverflow.com/a/9102463/1677912
function getFirstEmptyRowByColumnArray() {
var spr = SpreadsheetApp.getActiveSpreadsheet();
var column = spr.getRange('A:A');
var values = column.getValues(); // obtenir toutes les données en une seule fois
var ct = 0;
while ( values[ct] && values[ct][0] != "" ) {
ct++;
}
return (ct+1);
}
Résultats du test :
Voici les résultats, résumés sur 50 itérations dans une feuille de calcul avec 100 lignes x 3 colonnes (remplies avec la fonction de test de Serge).
Les noms des fonctions correspondent au code dans le script ci-dessous.
![capture d'écran]()
"Première ligne vide"
La question initiale était de trouver la première ligne vide. Aucun des scripts précédents ne répond réellement à cela. Beaucoup vérifient juste une colonne, ce qui signifie qu'ils peuvent donner des résultats faussement positifs. D'autres ne trouvent que la première ligne qui suit toutes les données, ce qui signifie que les lignes vides dans des données non contiguës sont ignorées.
Voici une fonction qui répond à la spécification. Elle a été incluse dans les tests et, bien qu'elle soit plus lente que le vérificateur de colonne unique ultra-rapide, elle est arrivée à 68ms respectables, une prime de 50% pour une réponse correcte !
/**
* Vérificateur de ligne entière de Mogsdad.
*/
function getFirstEmptyRowWholeRow() {
var feuille = SpreadsheetApp.getActiveSheet();
var plage = feuille.getDataRange();
var valeurs = plage.getValues();
var ligne = 0;
for (var ligne=0; ligne
`
Script complet :
Si vous voulez répéter les tests ou ajouter votre propre fonction pour la comparer, copiez simplement l'ensemble du script et utilisez-le dans une feuille de calcul.
/**
* Configuration d'une option de menu pour plus de facilité d'utilisation.
*/
function onOpen() {
var entreesMenu = [ {name: "Remplir la feuille", functionName: "fillSheet"},
{name: "tester getFirstEmptyRow", functionName: "testTime"}
];
var sh = SpreadsheetApp.getActiveSpreadsheet();
sh.addMenu("exécuter des tests",entreesMenu);
}
/**
* Tester un tableau de fonctions, mesurer l'exécution de chacune sur plusieurs itérations.
* Produire des statistiques à partir des données collectées et les présenter dans une feuille "Résultats".
*/
function testTime() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheets()[0].activate();
var iterations = parseInt(Browser.inputBox("Entrez le nombre d'itérations, min 2 :")) || 2;
var fonctions = ["getFirstEmptyRowByOffset", "getFirstEmptyRowByColumnArray", "getFirstEmptyRowByCell","getFirstEmptyRowUsingArray", "getFirstEmptyRowWholeRow"]
var résultats = [["Itération"].concat(fonctions)];
for (var i=1; i<=iterations; i++) {
var ligne = [i];
for (var fn=0; fn"&B$'+ligne+"-3*B$"+(ligne+1)+")" ]]);
formules.setNumberFormat("##########.");
for (var col=3; col<=résultats[0].length;col++) {
formules.copyTo(feuilleRésultat.getRange(ligne, col))
}
// Format pour plus de lisibilité
for (var col=1;col<=résultats[0].length;col++) {
feuilleRésultat.autoResizeColumn(col)
}
}
// Fonction originale d'Omiod. Vérifie seulement la première colonne
// Modifiée pour donner le bon résultat.
// question https://stackoverflow.com/questions/6882104
function getFirstEmptyRowByOffset() {
var spr = SpreadsheetApp.getActiveSpreadsheet();
var cellule = spr.getRange('a1');
var ct = 0;
while ( cellule.offset(ct, 0).getValue() != "" ) {
ct++;
}
return (ct+1);
}
// Approche du tableau de Don - vérifie seulement la première colonne.
// Avec condition d'arrêt ajoutée et bon résultat.
// De la réponse https://stackoverflow.com/a/9102463/1677912
function getFirstEmptyRowByColumnArray() {
var spr = SpreadsheetApp.getActiveSpreadsheet();
var colonne = spr.getRange('A:A');
var valeurs = colonne.getValues(); // obtenir toutes les données en une seule fois
var ct = 0;
while ( valeurs[ct] && valeurs[ct][0] != "" ) {
ct++;
}
return (ct+1);
}
// Fonction getFirstEmptyRow de Serge, adaptée de celle d'Omiod, mais
// en utilisant getCell à la place de offset. Vérifie seulement la première colonne.
// Modifiée pour donner le bon résultat.
// De la réponse https://stackoverflow.com/a/18319032/1677912
function getFirstEmptyRowByCell() {
var spr = SpreadsheetApp.getActiveSpreadsheet();
var ran = spr.getRange('A:A');
var arr = [];
for (var i=1; i<=ran.getLastRow(); i++){
if(!ran.getCell(i,1).getValue()){
break;
}
}
return i;
}
// Adaptation de Serge de la réponse du tableau de Don. Vérifie seulement la première colonne.
// Modifiée pour donner le bon résultat.
// De la réponse https://stackoverflow.com/a/18319032/1677912
function getFirstEmptyRowUsingArray() {
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var données = ss.getDataRange().getValues();
for(var n=0; n
`