首页 > 解决方案 > Range.getValue 方法被脚本广泛用于执行提示(菜单中的灯泡)

问题描述

您好,我编写了一个脚本,该脚本使用电子表格中不同列的值来完成几个 Google 文档表。我声明了列变量:(总共 8 个)

var colonne_nom_de_projet = 3
var colonne_code_de_projet = 1
var colonne_chef_de_projet = 7
var colonne_service_pilote_de_projet = 8
var colonne_autres_services_projet = 11
var colonne_typede_projet = 10
var colonne_perimetre__projet  = 12
var colonne_date_de_projet = 18

所以var NUMERO_COLONNE_2019 = 2; 项目的名称在第三列......日期在第 18 列,只有当我在第二列中有“是”时我才想创建一个文档之后我开始用这个值完成我的谷歌文档表

    var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
      var data = sheet.getDataRange().getValues(); 

      var targetFolder = DriveApp.getFolderById(FOLDER_ID);
      Logger.log('targetFolder name: ' + targetFolder.getName());

      var numRows=sheet.getLastRow();
      var lastColumn = sheet.getLastColumn();
      var nombre_projets_2019 = 0 ;
      // à partir de 2 car la première ligne ne nous interesse pas
      for(n=2;n<=data.length;++n) {
          if (sheet.getRange(n,NUMERO_COLONNE_2019).getValue() == 'yes'){
 if(child.getType()==DocumentApp.ElementType.TABLE && child.asTable().getNumRows() >= 8)
            {
         child.asTable().getCell(0, k).editAsText().setText( sheet.getRange(n,colonne_nom_de_projet).getValue() );
                      child.asTable().getCell(1, k).editAsText().setText( sheet.getRange(n,colonne_code_de_projet).getValue() )  ;
                      child.asTable().getCell(2, k).editAsText().setText(sheet.getRange(n,colonne_chef_de_projet).getValue())  ;
                      child.asTable().getCell(3, k).editAsText().setText( sheet.getRange(n,colonne_service_pilote_de_projet).getValue() )  ;
                      child.asTable().getCell(4, k).editAsText().setText( sheet.getRange(n,colonne_autres_services_projet).getValue() )  ;
                      child.asTable().getCell(5, k).editAsText().setText( sheet.getRange(n,colonne_typede_projet).getValue() )  ;
                      child.asTable().getCell(6, k).editAsText().setText( sheet.getRange(n,colonne_perimetre__projet).getValue() )  ;
                      child.asTable().getCell(7, k).editAsText().setText( sheet.getRange(n,colonne_date_de_projet).getValue() )  ;

它有效,但我有一条消息和一个执行提示(菜单中的灯泡)

“Range.getValue 方法被脚本广泛使用。CollapseFile: Code Line: 75 该脚本使用了一种被认为代价高昂的方法。每次调用都会生成对远程服务器的长期调用。这会对脚本执行产生严重影响时间,特别是在大数据上。如果脚本有性能问题,我们建议您使用另一种方法,例如 Range.getValues()。如果您有任何想法,那就太好了^^^^,因为第 75 行对应于

if (sheet.getRange(n,NUMERO_COLONNE_2019).getValue() == 'yes')

编辑编辑:这是我非常慢的代码 4 分钟

    function create_Google_Docs_2019_0() {
      
      var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
      var numRows = sheet.getLastRow();
      var lastColumn = sheet.getLastColumn();
      var data = sheet.getRange(1,1,numRows,lastColumn).getValues()
    
      
      var targetFolder = DriveApp.getFolderById(FOLDER_ID);
      Logger.log('targetFolder name: ' + targetFolder.getName());
      
      var numRows=sheet.getLastRow();
      var lastColumn = sheet.getLastColumn();
      var nombre_projets_2019 = 0 ;
      
      
      // à partir de 2 car la première ligne ne nous interesse pas
       for(n=1;n < data.length;n++) {
        
        //verifier si c'est une projet 2019 >>>>>>>>>>>>>>>>>>>  ici on fait notre travail 
         if ( data[n][1] == 'o'){
          nombre_projets_2019 = nombre_projets_2019  + 1;
          var nom_projet = data[n][2];
           
          //var nom_document = 'Projet ' + nom_projet ;
          var nom_document = nom_projet ;
          /** Recherche si dans folder il y a déjà ce fichier avec ce nom on va l'actualiser avec les données changés**/
          
          if( checkFile_in_a_Folder(nom_document,targetFolder) == 1){
            //on ajoute le fichier dans le repertoire courant targetFolder
            Logger.log('On va réecrire le ficher / overwrite le ficher ');
          } 
          else
          {
            Logger.log('On va le créer avec les données qu on a dans le tableau ');
            //Make a copy of the template file
            var documentId = DriveApp.getFileById(TEMPLATE_DOC_ID).makeCopy().getId();
            
            //Rename the copied file
            var name = DriveApp.getFileById(documentId).setName(nom_document);
            var body = DocumentApp.openById(documentId).getBody();
            if(body)
            {
              var ok = 0;       //pour l'instant il n'y a pas de tableau
              var numChildren=body.getNumChildren();
              var i=0;
              //tant qu'on n'a pas du tableau on va parcourir
              while(ok ==0 && i<numChildren)
              {
                var child=body.getChild(i);
                /** ============On est concerné par le premier tableau seulement qui a au plus 8 lignes d'information ================**/
                Logger.log('Le type dans la boucle  ' + child.getType());
                //on a trouvé un tableau
                if(child.getType()==DocumentApp.ElementType.TABLE && child.asTable().getNumRows() >= 8)
                {
                  //on a trouve notre premier tableau
                  ok=1;   
                  
                  
                  var numrows = child.asTable().getNumRows();
                  Logger.log('Le nombre de lignes dans notre Google Doc  ' + numrows);
                  
                  var insertion_position  = n ;
                  Logger.log('Position pour inserer dans le spreadsheet  ' + insertion_position);
                  
                  var k = 1;
                  child.asTable().getCell(0, k).editAsText().setText( data[n][colonne_nom_de_projet-1]);
                  child.asTable().getCell(1, k).editAsText().setText( data[n][colonne_code_de_projet-1] )  ;
                  child.asTable().getCell(2, k).editAsText().setText( data[n][colonne_chef_de_projet-1])  ;
                  child.asTable().getCell(3, k).editAsText().setText( data[n][colonne_service_pilote_de_projet-1] )  ;
                  child.asTable().getCell(4, k).editAsText().setText( data[n][colonne_autres_services_projet-1] )  ;
                  child.asTable().getCell(5, k).editAsText().setText( data[n][colonne_typede_projet-1] )  ;
                  child.asTable().getCell(6, k).editAsText().setText( data[n][colonne_perimetre__projet-1] )  ;
                  child.asTable().getCell(7, k).editAsText().setText( data[n][colonne_date_de_projet-1] )  ;
                }
                i++;
              }
            }
          } 
        }
        Logger.log('Nombre de projets 2019 ' +  nombre_projets_2019 );
      }
    }

这是一个项目,因此通过在第二列中搜索“o”(法语中的 oui)意味着该项目将在 2019 年进行,因此我将从我想要的几个列中获取信息(名称项目、日期、项目厨师.. .) 然后将此信息放入使用具有 8 行和 2 列的 makecopy() 模板创建的 Google Doc Table 中,因此所有信息将放入第二列中。事实上,我的代码非常慢,如果你有任何改进它的想法会很棒,因为它在大约 4 分钟内完成工作

标签: google-sheetsgoogle-docs

解决方案


使用 range.getValues() 获取数组中的值(对 API 的一次调用),而不是多次使用 .getValue() (多次调用,“认为昂贵”)。

代替:

for(n=2;n<=data.length;++n) {
    child.asTable().getCell(0, k).editAsText().setText( sheet.getRange(n,colonne_nom_de_projet).getValue() );
    child.asTable().getCell(2, k).editAsText().setText(sheet.getRange(n,colonne_chef_de_projet).getValue())  ;

    //etc.

利用:

var values = sheet.getRange(0,0,20,20).getValues() //or whatever the range is
for(n=2;n<=data.length;++n) {
    child.asTable().getCell(0, k).editAsText().setText( values[n][colonne_nom_de_projet]) );
    child.asTable().getCell(2, k).editAsText().setText(values[n][colonne_chef_de_projet]))  ;
    //etc.

类似的东西,你明白了。


推荐阅读