当区域设置为 en_US 时,使用具有相同 M 和 Y 的日期的 A 列使用 createTextFinder() 获取行块
Get row block with createTextFinder() from column A with dates with same M and Y when locale is en_US
我有一个 sheet,其中 A 列有日期。我需要获取具有相同月份和年份的一组行的行号。
如果 SpreadSheet 的 Locale 是 en_US
那么日期格式是这样的:
"M/d/YYYY"
所以 d
在 M
和 Y
之间。如您所见:
var getDayMonthYear = Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "M/d/YYYY");
因此,为了定义行块,我需要从列 A 中 find/filter 所有日期为 M/YYYY
的行。这对于 ex 来说很容易使用语言环境。 en_GB
其中日期格式为 dd/MM/YYYY
。这里我只搜索MM/YYYY
没有错误
但是因为在 en_US
中 d
在 M
和 Y
之间,即 M/d/YYYY
,我总是得到一个错误:
Exception: The parameters (null,number) don't match the method signature for SpreadsheetApp.Sheet.getRowGroup.
我试过了:
Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "M,yyyy").split(",");
我得到同样的错误:
Exception: The parameters (null,number) don't match the method signature for SpreadsheetApp.Sheet.getRowGroup.
所以这是我得到的代码示例。如果将 SpreadSheet 语言环境设置为英国 en_GB
:
,它可以正常工作
function testTimeFormat() {
var logSheetNameYR = "LOG";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(logSheetNameYR);
var rowBlock = sheet.getRange(sheet.getLastRow() - 1, 1).getValue();
var getMonthYear = Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "MM/YYYY");
var cells = sheet.getRange("A5:A").createTextFinder(getMonthYear).findAll().map(x => x.getRowIndex());
var firstRowOfBlock = cells[0];
console.log(firstRowOfBlock);
}
但是当区域设置为 en_US 时它不起作用。
当区域设置为美国 en_US
或使用 d
或任何其他字符将 M
与 Y
分隔开的任何其他日期格式时,我如何做同样的事情之间?
虚拟文件:
https://docs.google.com/spreadsheets/d/1ExXtmQ8nyuV1o_UtabVJ-TifIbORItFMWjtN6ZlruWc/edit?usp=sharing
createTextFinder
对此并不理想,因为此方法仅适用于 sheet.[=17 上范围 A5:A
的每个单元格上显示的确切文本值=]
推荐
您可以使用数组的字符串操作尝试下面的示例脚本。这将 return 与范围 A5:A
:
上的 getMonthYear
匹配的所有单元格的行
示例脚本:
function test(){
var logSheetNameYR = "LOG";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(logSheetNameYR);
var rowBlock = sheet.getRange(sheet.getLastRow() - 1, 1).getValue();
var getMonthYear = Utilities.formatDate(rowBlock, "GMT+1", "MM/yyyy"); //using UK timezone
var range = sheet.getRange("A5:A");
var startRow = range.getRow();
var cells = range.getValues().map((x,i) => x.concat(i + startRow))
.filter(x => getMonthYear == ("0" + (new Date(x[0]).getMonth() + 1)).slice(-2) + "/" + new Date(x[0]).getFullYear())
.map(x => x[1]);
Logger.log(cells);
}
示例结果:
Sheet:
不需要指定格式,只需要分别获取明细(日、月、年)方便对比。
还有一点要注意,永远不要为了更短的代码而牺牲可读性。必要时使用变量。
// get all details of the date
var mmddyyyy = Utilities.formatDate(rowBlock, "GMT+1", "MM/dd/yyyy"); //using UK timezone
// split to each category for easier access
var [mm, dd, yyyy] = mmddyyyy.split('/');
var range = sheet.getRange("A5:A");
var startRow = range.getRow();
var cells = range.getValues().map((x,i) => x.concat(i + startRow))
.filter(x => {
var date = new Date(x[0]);
var month = ("0" + (date.getMonth() + 1)).slice(-2);
var year = date.getFullYear();
var day = date.getDate();
// date properties are always the same on different formats
// because these are outputs of date methods
// just create a combination of the variables
// e.g. you want to match the exact date
return (`${dd}${mm}${yyyy}` == `${day}${month}${year}`)
})
.map(x => x[1]);
所以我最终放弃了文本查找器技巧,并接受了@ASyntuBU 的建议,并使用他的代码对 return
部分进行了更改,使用 AND
即 &&
到将 d
与 m
与 y
分开,这样过滤器将不会像 dd/MM/YYYY
那样强制执行特定顺序,但会将 return 放入数组中,所有行号和单元格在满足条件的 A 列上,无论顺序、日期格式等如何。至少我认为这就是它的作用。谢谢@ASyntuBU!
// Used for getting the arrays with blocks of rows of `d`+ `m`+ `y`
let range = sheet.getRange("A5:A");
let startRow = range.getRow();
let [y, m, d] = Utilities.formatDate(new Date(), timeZone, "yyyy,MM,dd").split(",");
let cells = range.getValues().map((x, i) => x.concat(i + startRow)).filter(x => { // filter "dd"
let date = new Date(x[0]);
let day = date.getDate();
let month = ("0" + (date.getMonth() + 1)).slice(-2);
let year = date.getFullYear();
return (`${d}` === `${day}` && `${m}` === `${month}` && `${y}` === `${year}`)
}).map(x => x[1]);
当我不想按月分组时,return
将是:
return (`${m}` === `${month}` && `${y}` === `${year}`)
并按年份分组:
return (`${y}` === `${year}`)
将returns行号放入一个数组中,然后我们用cells[0]
得到0
(第一个)位置,找到组句柄所在的行号。
我有一个 sheet,其中 A 列有日期。我需要获取具有相同月份和年份的一组行的行号。
如果 SpreadSheet 的 Locale 是 en_US
那么日期格式是这样的:
"M/d/YYYY"
所以 d
在 M
和 Y
之间。如您所见:
var getDayMonthYear = Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "M/d/YYYY");
因此,为了定义行块,我需要从列 A 中 find/filter 所有日期为 M/YYYY
的行。这对于 ex 来说很容易使用语言环境。 en_GB
其中日期格式为 dd/MM/YYYY
。这里我只搜索MM/YYYY
没有错误
但是因为在 en_US
中 d
在 M
和 Y
之间,即 M/d/YYYY
,我总是得到一个错误:
Exception: The parameters (null,number) don't match the method signature for SpreadsheetApp.Sheet.getRowGroup.
我试过了:
Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "M,yyyy").split(",");
我得到同样的错误:
Exception: The parameters (null,number) don't match the method signature for SpreadsheetApp.Sheet.getRowGroup.
所以这是我得到的代码示例。如果将 SpreadSheet 语言环境设置为英国 en_GB
:
function testTimeFormat() {
var logSheetNameYR = "LOG";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(logSheetNameYR);
var rowBlock = sheet.getRange(sheet.getLastRow() - 1, 1).getValue();
var getMonthYear = Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "MM/YYYY");
var cells = sheet.getRange("A5:A").createTextFinder(getMonthYear).findAll().map(x => x.getRowIndex());
var firstRowOfBlock = cells[0];
console.log(firstRowOfBlock);
}
但是当区域设置为 en_US 时它不起作用。
当区域设置为美国 en_US
或使用 d
或任何其他字符将 M
与 Y
分隔开的任何其他日期格式时,我如何做同样的事情之间?
虚拟文件:
https://docs.google.com/spreadsheets/d/1ExXtmQ8nyuV1o_UtabVJ-TifIbORItFMWjtN6ZlruWc/edit?usp=sharing
createTextFinder
对此并不理想,因为此方法仅适用于 sheet.[=17 上范围 A5:A
的每个单元格上显示的确切文本值=]
推荐
您可以使用数组的字符串操作尝试下面的示例脚本。这将 return 与范围 A5:A
:
getMonthYear
匹配的所有单元格的行
示例脚本:
function test(){
var logSheetNameYR = "LOG";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(logSheetNameYR);
var rowBlock = sheet.getRange(sheet.getLastRow() - 1, 1).getValue();
var getMonthYear = Utilities.formatDate(rowBlock, "GMT+1", "MM/yyyy"); //using UK timezone
var range = sheet.getRange("A5:A");
var startRow = range.getRow();
var cells = range.getValues().map((x,i) => x.concat(i + startRow))
.filter(x => getMonthYear == ("0" + (new Date(x[0]).getMonth() + 1)).slice(-2) + "/" + new Date(x[0]).getFullYear())
.map(x => x[1]);
Logger.log(cells);
}
示例结果:
Sheet:
不需要指定格式,只需要分别获取明细(日、月、年)方便对比。
还有一点要注意,永远不要为了更短的代码而牺牲可读性。必要时使用变量。
// get all details of the date
var mmddyyyy = Utilities.formatDate(rowBlock, "GMT+1", "MM/dd/yyyy"); //using UK timezone
// split to each category for easier access
var [mm, dd, yyyy] = mmddyyyy.split('/');
var range = sheet.getRange("A5:A");
var startRow = range.getRow();
var cells = range.getValues().map((x,i) => x.concat(i + startRow))
.filter(x => {
var date = new Date(x[0]);
var month = ("0" + (date.getMonth() + 1)).slice(-2);
var year = date.getFullYear();
var day = date.getDate();
// date properties are always the same on different formats
// because these are outputs of date methods
// just create a combination of the variables
// e.g. you want to match the exact date
return (`${dd}${mm}${yyyy}` == `${day}${month}${year}`)
})
.map(x => x[1]);
所以我最终放弃了文本查找器技巧,并接受了@ASyntuBU 的建议,并使用他的代码对 return
部分进行了更改,使用 AND
即 &&
到将 d
与 m
与 y
分开,这样过滤器将不会像 dd/MM/YYYY
那样强制执行特定顺序,但会将 return 放入数组中,所有行号和单元格在满足条件的 A 列上,无论顺序、日期格式等如何。至少我认为这就是它的作用。谢谢@ASyntuBU!
// Used for getting the arrays with blocks of rows of `d`+ `m`+ `y`
let range = sheet.getRange("A5:A");
let startRow = range.getRow();
let [y, m, d] = Utilities.formatDate(new Date(), timeZone, "yyyy,MM,dd").split(",");
let cells = range.getValues().map((x, i) => x.concat(i + startRow)).filter(x => { // filter "dd"
let date = new Date(x[0]);
let day = date.getDate();
let month = ("0" + (date.getMonth() + 1)).slice(-2);
let year = date.getFullYear();
return (`${d}` === `${day}` && `${m}` === `${month}` && `${y}` === `${year}`)
}).map(x => x[1]);
当我不想按月分组时,return
将是:
return (`${m}` === `${month}` && `${y}` === `${year}`)
并按年份分组:
return (`${y}` === `${year}`)
将returns行号放入一个数组中,然后我们用cells[0]
得到0
(第一个)位置,找到组句柄所在的行号。