使用工作表名称作为循环参数

时间:2017-08-29 15:44:22

标签: javascript arrays google-apps-script google-apps

说明 我有一个电子表格,我称之为“应用程序”。这是向客户提供服务的时间表以及提供这些服务的日期。我还有另一个名为“每日活动”的电子表格。我试图为每个客户创建一个汇总成本和服务。每日活动电子表格为每个客户提供一个选项卡,每个客户的选项卡名称是在应用程序电子表格中标识客户端的代码。我需要收集每天为每个客户提供的服务数量,以便我可以为每个客户创建成本和服务的摘要,以便我可以根据客户更好地了解客户的盈利能力。 / p>

我的进展和问题: 我已成功利用Google Script收集所需信息,但我一直遇到最长执行时间问题。我认为问题在于我必须为每个客户编写一个单独的脚本,因为我不知道如何将它全部集成到一个脚本中。

我注意到我可以使用如下函数获取所有工作表的数组:

function loopingSheets() {
 var ss = SpreadsheetApp.openById("id");
 var sheets = ss.getSheets();
 var sh = [];
 for (i=0; i<sheets.length; i++) {
 var newSh = sheets[i].getName();
 sh.push(newSh);
  }
 return sh;
  }

但我不知道如何将其集成到我的脚本中,这样我就可以拥有一个脚本来执行所有客户端的流程

以下是真正计算的脚本

此脚本扫描应用程序电子表格,该电子表格是在给定时间段内为每个客户提供的服务计划。此脚本需要每天运行,以便将所有必需的数据记录到每日活动电子表格中。

function countSheet1() { 
var ss=SpreadsheetApp.openById("ID");
var cntSh=ss.getSheetByName('Applications');
var cntRg=cntSh.getDataRange();
var vA=cntRg.getValues();
var today = new Date();
var toD = Utilities.formatDate(new Date(today), Session.getScriptTimeZone(), "dd/MM/yyyy");
var count=0;
var rowA = [];
var rowB = [];
for (i=2; i<vA.length; i++) {
rowA = vA[i][0];
rowB = vA[i][1];
var rowBb = Utilities.formatDate(new Date(rowB), Session.getScriptTimeZone(), "dd/MM/yyyy");
Logger.log(rowBb);
  if(rowA == "Sheet1" && rowBb == toD) {
    count++;
  }
}
return count;

}

除了不同的客户端

之外,这是与上面相同的脚本
function countSheet2() {
 var ss=SpreadsheetApp.openById("ID");
 var cntSh=ss.getSheetByName('Applications');
 var cntRg=cntSh.getDataRange();
 var vA=cntRg.getValues();
 var today = new Date();
 var toD = Utilities.formatDate(new Date(today), Session.getScriptTimeZone(), "dd/MM/yyyy");
var count=0;
var rowA = [];
var rowB = [];
 for (i=2; i<vA.length; i++) {
rowA = vA[i][0];
rowB = vA[i][1];
var rowBb = Utilities.formatDate(new Date(rowB), Session.getScriptTimeZone(), "dd/MM/yyyy");
Logger.log(rowBb);
  if(rowA == "Sheet2" && rowBb == toD) {
    count++;
  }
}
 return count;

}

这是在每张纸上写下计数的脚本......

function runScript() {
 function toDateFormat(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}

 var sheet1 = SpreadsheetApp
  .openById("id")
  .getSheetByName("Sheet1");
var sRange =  sheet1.getDataRange();
var values = sRange.getValues();
var newT = new Array();
var nr = 0;

 for (i = 0; i < values.length; i++){
  if (values[i][1]=='Total Number of Applications'){
  nr = i;
  newT.push(nr);
 }             
}
var client = newT[0];
var app = newT[1];
var today = toDateFormat(new Date());
var todaysColumn = values[3].map(toDateFormat).map(Number).indexOf(+today);

sheet1.getRange(client+1,todaysColumn+1,1,1).setValue(countSheet1());

 //Sheet2

var sheet2 = SpreadsheetApp
  .openById("ID")
  .getSheetByName("Sheet2");
var sRange =  sheet2.getDataRange();
var values = sRange.getValues();
var newT = new Array();
var nr = 0;
for (i = 0; i < values.length; i++){
if (values[i][1]=='Total Number of Applications'){
nr = i;
newT.push(nr);
 }             
}
var client = newT[0];
var app = newT[1];
var today = toDateFormat(new Date());
var todaysColumn = values[3].map(toDateFormat).map(Number).indexOf(+today);


sheet2.getRange(client+1,todaysColumn+1,1,1).setValue(countSheet2());
}

countSheet1函数扫描应用程序电子表格,计算Sheet1(A列)和今天日期(B列)的出现次数。然后,它会在“每日活动”中的“每日活动”中保存该计数“表1&#39;我必须不断为每个客户添加更多脚本。

我想知道是否有可能使用getSheets()数组来创建一个执行整个操作的脚本。

由于数据保护,我无法访问原始文件....

我仍然在努力改进我的JavaScript和GAS知识(特别是我努力争取的数组)....

非常感谢!!!

L.E。我添加了2个电子表格作为模板

Daily Activity

Applications

1 个答案:

答案 0 :(得分:2)

提供从申请表

提供的服务的数量

此版本可以正常使用

我创建了一个带有键/值对的对象,其中键是制表符或工作表名称(也是客户端ID)。我对代码做了一些更改。我认为它有效,但我会让你成为法官。我在代码中留下了一些调试屏幕。我喜欢他们,因为他们比记录器更容易让我看到。但这可能只是一个老家伙的问题。

function countSheets() 
{ 
  var ss=SpreadsheetApp.openById('ID');
  var sh=ss.getSheetByName('Applications');
  var rg=sh.getDataRange();
  var vA=rg.getValues();
  var td = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "dd/MM/yyyy");
  var mbs=myBullSheets();
  //var s='';
  for (var i=2;i<vA.length;i++)
  {
    var d = Utilities.formatDate(new Date(vA[i][1]), Session.getScriptTimeZone(), "dd/MM/yyyy");
    for(var key in mbs)
    {
      //Logger.log('\n%s==%s && %s==%s',vA[i][0],key,d,td);
      //s+=Utilities.formatString('<br />%s==%s && %s==%s',vA[i][0],key,d,td);
      if(vA[i][0]==key && d==td) 
      {
        mbs[key]+=1;
        //Logger.log('\nmbs[%s]=%s',key,mbs[key]);
        //s+=Utilities.formatString('\nmbs[%s]=%s',key,mbs[key]);
      }
    }
  }
  //var ui=HtmlService.createHtmlOutput(s);
  //SpreadsheetApp.getUi().showModelessDialog(ui, 'My Logs');
  return mbs;
}

function myBullSheets()
{
  var ss=SpreadsheetApp.openById('ID');
  var allshts=ss.getSheets();
  var mbs=[];
  for(var i=0;i<allshts.length;i++)
  {
    mbs[allshts[i].getName()]=0;
  }
  return mbs;
}

我希望这可以帮助你。

感谢您提供的数据。这帮了很多。

BTW ..你需要这样的东西来查看记录器中的输出。

function testcountSheets()
{
  var mbs=countSheets();
  for(var key in mbs)
  {
    Logger.log('\nmbs[%s]=%s',key,mbs[key]);
  }
}

这会将计数加载到Daily Activity Spreadsheet

的选项卡中

这可能是你想要的。我根本没有测试过这个。但是一旦我们能够将它运行起来,我怀疑它的运行速度会快得多。

function runScript() 
{
  var ss=SpreadsheetApp.openById('ID');
  var mbs=countSheets();
  for(var key in mbs)
  {
    var sh=ss.getSheetByName(key);
    var rg=sh.getDataRange();
    var vA=rg.getValues();
    for(var i=0;i<vA.length;i++)
    {
      if(vA[i][1]=='Total Number of Applications')
      {
        var nr=i;
        break;//by terminating as soon as we find a match we should get improved performance.  Which is something you cant do in a map.
      }             
    }
    if(typeof(nr)!='undefined')//If we don't find a match this is undefined
    {
      var today=new Date().setHours(0,0,0,0);
      for(var i=0;i<vA[3].length;i++)
      {
        if(vA[3][i])//Some cells in this range have no contents
        {
          if(today.valueOf()==new Date(vA[3][i]).valueOf())
          {
            sh.getRange(nr+1,i+1,1,1).setValue(Number(mbs[key]));
          }
        }
      }
    }
  }
}

哇!从超过最大执行时间到25秒......我喜欢