使用 Sheet 名称作为循环参数
Use Sheet Name as a Loop Parameter
描述:
我有一个价差 sheet,我称之为 'Applications',它是向客户提供的服务时间表以及提供这些服务的日期。我还有另一个名为 'Daily Activity' 的价差 sheet,我试图在其中创建为每个客户提供的成本和服务汇总。 Daily Activity Spreadsheet 每个客户都有一个标签,每个客户的标签名称是一个代码,用于在 Applications spreadsheet 中识别客户。我需要收集每天为每个客户提供的服务数量,以便我可以创建为每个客户提供的成本和服务的摘要,以便我可以更好地了解每个客户的盈利能力。
我的进步和问题:
我已经成功地利用 Google 脚本来收集所需的信息,但我一直 运行 陷入 最大执行时间问题 。我认为我的问题是我必须为每个客户端编写一个单独的脚本,因为我不知道如何将它们全部集成到一个脚本中。
我注意到我可以用这样的函数得到一个包含所有 sheet 的数组:
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;
}
但我不知道如何将其集成到我的脚本中,以便我可以只有 一个脚本来为所有客户端执行该过程。
以下是真正重要的脚本
此脚本扫描 Applications Spreadsheet,它是在给定时间段内为每个客户提供的服务时间表。此脚本需要每天 运行 以便所有需要的数据都可以记录到 Daily Activity spreadsheet.
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;
}
这是编写计数每个 sheet ...
的脚本
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 函数扫描 Applications spreadsheet 计算 Sheet1(A 列)和今天日期(B 列)的出现次数。然后它会将该计数保存在选项卡 'Sheet 1' 下的每日 Activity 中,我必须继续为每个客户端添加更多脚本。
我想知道是否有可能使用 getSheets() 数组来创建一个执行整个操作的脚本。
由于数据保护,我将无法提供对原始文件的访问....
我仍在努力提高我的 JavaScript 和 GAS 知识(尤其是我难以掌握的数组)....
非常感谢!!!
L.E. 我添加了 2 个 spreadsheet 作为模板
应用程序提供的服务数量 sheet
这个版本没问题
我用 key/value 对创建了一个对象,其中键是一个选项卡或 sheet 名称(也是一个客户端 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;
}
希望对您有所帮助。
感谢您提供数据。这帮了很多忙。
顺便说一句..您需要这样的东西才能在记录器中查看输出。
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 秒...我喜欢
描述: 我有一个价差 sheet,我称之为 'Applications',它是向客户提供的服务时间表以及提供这些服务的日期。我还有另一个名为 'Daily Activity' 的价差 sheet,我试图在其中创建为每个客户提供的成本和服务汇总。 Daily Activity Spreadsheet 每个客户都有一个标签,每个客户的标签名称是一个代码,用于在 Applications spreadsheet 中识别客户。我需要收集每天为每个客户提供的服务数量,以便我可以创建为每个客户提供的成本和服务的摘要,以便我可以更好地了解每个客户的盈利能力。
我的进步和问题: 我已经成功地利用 Google 脚本来收集所需的信息,但我一直 运行 陷入 最大执行时间问题 。我认为我的问题是我必须为每个客户端编写一个单独的脚本,因为我不知道如何将它们全部集成到一个脚本中。
我注意到我可以用这样的函数得到一个包含所有 sheet 的数组:
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;
}
但我不知道如何将其集成到我的脚本中,以便我可以只有 一个脚本来为所有客户端执行该过程。
以下是真正重要的脚本
此脚本扫描 Applications Spreadsheet,它是在给定时间段内为每个客户提供的服务时间表。此脚本需要每天 运行 以便所有需要的数据都可以记录到 Daily Activity spreadsheet.
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;
}
这是编写计数每个 sheet ...
的脚本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 函数扫描 Applications spreadsheet 计算 Sheet1(A 列)和今天日期(B 列)的出现次数。然后它会将该计数保存在选项卡 'Sheet 1' 下的每日 Activity 中,我必须继续为每个客户端添加更多脚本。
我想知道是否有可能使用 getSheets() 数组来创建一个执行整个操作的脚本。
由于数据保护,我将无法提供对原始文件的访问....
我仍在努力提高我的 JavaScript 和 GAS 知识(尤其是我难以掌握的数组)....
非常感谢!!!
L.E. 我添加了 2 个 spreadsheet 作为模板
应用程序提供的服务数量 sheet
这个版本没问题
我用 key/value 对创建了一个对象,其中键是一个选项卡或 sheet 名称(也是一个客户端 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;
}
希望对您有所帮助。
感谢您提供数据。这帮了很多忙。
顺便说一句..您需要这样的东西才能在记录器中查看输出。
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]));
}
}
}
}
}
}