【发布时间】:2021-10-07 03:52:46
【问题描述】:
这是场景: 我有一个多标签(工作表)工作表。工作表 A(回合)收集数据,工作表 B-D 以不同方式对数据进行格式化。我正在尝试创建一个脚本,将当前工作表设置为工作表 D(Transfer-Stats),然后在那里创建一个二维数据数组。然后我想扫描该数组并选择非空白行并将它们放在另一个二维数组中,然后将其添加(附加)到不同的工作表中。我是 Apps 脚本的初学者,超出了我的技术能力。我想要一些基本的指导。我已经得到了一些初步的代码(如下所示),但到目前为止我唯一完成的是找到 Transfer-Stats 表的最后一行和最后一列。当涉及到尝试创建第一个 2D 数组的语句时,它会出现“找不到方法 getRange(number,number).”的错误。任何有关如何编码此问题的帮助将不胜感激。
function saveStats() {
ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssName = SpreadsheetApp.getActiveSpreadsheet().getName();
var ssRounds = ss.getSheetByName('Rounds').getName();
var ssStats = ss.getSheetByName('Transfer-Stats').getName();
ui.alert("ssRounds " + ssRounds + " ssStats " + ssStats + " " + ssName) /** names are correct */
SpreadsheetApp.setActiveSheet(ss.getSheetByName(ssStats), true); /** set to Transfer-Stats */
var lastStatsRow = ss.getLastRow() /** find last row of stats sheet */
var lastStatsCol = ss.getLastColumn() /** find last column of stats sheet */
var statsArray = [ss.getRange(1, lastStatsCol).getValues()]
ui.alert("Stop at Stats Last row is " + lastStatsRow + " Last Row is " + lastStatsCol + " " + ssStats + " " + ss)
/** data shown above is: Stop at Stats Last row is 25 Last Col is 19 Transfer-Stats Spreadsheet which is correct for last row and column but not sure about "Spreadsheet" */
var statsArray = [ss.getRange(1, lastStatsCol).getValues()] /** this statement fails */
// SpreadsheetApp.setActiveSheet(ss.getSheetByName(ssRounds),true);
// ssStats.activate()
}
更多细节:我的主工作表(Rounds)包含用户提供的数据。 Transfer-Stats 表使用 Rounds 表中的等价单元格收集其中一些数据(没有数据输入到 Transfer-Stats)。正在开发的脚本将从 Rounds 表启动,但我想从 Transfer-Stats 收集行并创建一个过滤数组以附加到不在此电子表格中的第三张表中。如果我知道怎么做,我会在这个论坛上分享这些表格 - 上面没有敏感数据。我尝试了建议代码的修改版本,如下所示:
function saveStats() {
// ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssName = SpreadsheetApp.getActiveSpreadsheet().getName();
var ssRounds = ss.getSheetByName('Rounds').getName();
var ssStats = ss.getSheetByName('Transfer_Stats').getName(); /** my code */
ssStats = SpreadsheetApp.setActiveSheet(ss.getSheetByName(ssStats),true); /** set to Transfer_Stats */
var lastStatsRow = ss.getLastRow() /** find last row of Transfer_Stats sheet */
var lastStatsCol = ss.getLastColumn() /** find last column of Transfer_Stats sheet */
var nameCol = 2 /** this column contains player name (checked for blank) */
var rowNum = 2 /** starting row */
var filterArray = [] /** temporary array for filtered rows */
var timeStamp = Utilities.formatDate(new Date(), "MST", "yyyy-MM-dd'/'HH:mm:ss") ; /** stamp each new row */
var filterSheet = ss.getSheetByName("Filtered_Stats") /** see if filtered sheet exists in the spreadsheet */
if (filterSheet != null) ss.deleteSheet(filterSheet) ; /** if it does, delete it so next statement will work */
filterSheet = ss.insertSheet("Filtered_Stats") /** create a new Filtered_Stats sheet */
var filterSheet = ss.getSheetByName('Filtered_Stats').getName(); /** get the name */
/** Ignore these statements - they will become a question for later ? */
// statsDB = SpreadsheetApp.openById("SVE_Stats_Fall_2021"); /** get the stats database */
// statsDB = DriveApp.getFile /** ById("SVE_Stats_Fall_2021") ; /** get the stats database */
// while (statsDB.hasNext()) {
// var file = statsDB.next();
// Logger.log(file.getName());
// }
// Logger.log(statsDB)
// var myID = sheet.getRange(lastRow, myIDCol).getValue(); /** sample from web */
// ui.alert("Stop at Stats Last row is " + lastStatsRow + " Last Col is " + lastStatsCol + " ssStats " + ssStats + " ss " + ss)
// var statsArray = ssStats.getRange(2, 1 ,lastStatsRow, lastStatsCol).getValues() /** .filter(r >= r.join("")) */
/** Resume here with executable code */
for (var rowNum=2; rowNum < lastStatsRow+1; rowNum++ ) /** start selecting rows from the 2D array */
{
var statsName1 = ssStats.getRange(rowNum, nameCol).getValues() ; /** get player 1 name for this row to check if empty */
var statsName2 = ssStats.getRange(rowNum, nameCol+1).getValues() ; /** get player 2 name for this row to check if empty */
var statsArray = ssStats.getRange(rowNum, 1, 1, lastStatsCol).getValues() ; /** get the complete row of data in new array */
statsArray.unshift(timeStamp) ; /** add a time stamp as the first cell of the array */
Logger.log(statsArray)
/** here's a sample from the above Logger.log (the first row of the 2D array with timestamp added):
(the second date & time in the sample is actually a date in the original row)
7:30:34 AM Info [2021-10-10/04:30:33, [R1M1-A, Ann Anderson, Kathy Biccum, 1.5, None, , Mon Jan 01 01:00:00 GMT-07:00 2001, 6.0, 4.0, 0.0, 6.0, 1.0, 5.0, 10.0, 0.0, 0.0, 17.0, 6.0, 35.294117647058826]] */
/** do I see a 2D array here because of the 2 sets of brackets [] ? */
if (statsName1 != "" && statsName2 != "") {
filterArray.push(statsArray) /** attempt to create a row in the 1D array from the 2D array */
Logger.log(filterArray) /** show what the new array looks like */
/** here's a sample of what the new array looks like:
7:39:50 AM Info [[2021-10-10/04:39:49, [R1M1-A, Ann Anderson, Kathy Biccum, 1.5, None, , Mon Jan 01 01:00:00 GMT-07:00 2001, 6.0, 4.0, 0.0, 6.0, 1.0, 5.0, 10.0, 0.0, 0.0, 17.0, 6.0, 35.294117647058826]]] */
/** the new array now has another set of brackets around it */
Logger.log(filterArray.length) /** show how long it is */
/** here's the length at this point which is correct for the first iteration of the for loop:
7:44:02 AM Info 1.0 */
/** the for loop executes correctly, selecting all the rows with non-blank names and placing them in the new array */
/** problem is the end result appended to the new sheet (see below) contains only 2 data elements not 20 as expected */
/** this code attempts to switch to the Filter_Stats sheet and populate a row from the filterArray */
/** it somewhat works, the first cell of each row in the sheet is filled with the timestamp */
/** but the second cell of each row in the sheet contains [Ljava.lang.Object;@39e47f39 */
ssFiltr = SpreadsheetApp.setActiveSheet(ss.getSheetByName(filterSheet),true); /** set to Filter_Stats */
ssFiltr.appendRow(statsArray) ;
ssStats = ss.getSheetByName('Transfer_Stats').getName();
ssStats = SpreadsheetApp.setActiveSheet(ss.getSheetByName(ssStats),true); /** reset to Transfer_Stats */
}
}
// SpreadsheetApp.setActiveSheet(ss.getSheetByName(ssRounds),true); /** return to primary sheet Rounds */
}
我知道这篇文章会变得令人困惑,但这是我迄今为止所处的位置。我有一些代码在一定程度上可以工作,虽然相当粗糙,但它并不能完全满足我的要求。我已经包含了嵌入了许多 cmets 的代码,在我运行代码时显示了详细的数据样本。我认为主要问题是我没有正确处理数组,因此在新工作表中创建的行不包含我所期望的。任何帮助将不胜感激。
【问题讨论】:
-
您能否提供一份电子表格副本(不含敏感信息),以便直观地阐明预期结果?
-
我明白了!经过数小时的反复试验和研究其他示例,我终于想出了一些有效的代码。它看起来更像 COBOL 代码而不是 Apps 脚本,但它确实有效。如果有人有兴趣,我可以发布它。现在讨论 DriveApp 问题。
-
您好,Tanaike 编辑的答案没有解决您的问题?在这种情况下,您能否发布一个答案来解释问题是什么以及您是如何解决的?
标签: arrays google-apps-script google-sheets