当区域设置为 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"

所以 dMY 之间。如您所见:

var getDayMonthYear = Utilities.formatDate(rowBlock, Session.getScriptTimeZone(), "M/d/YYYY");

因此,为了定义行块,我需要从列 A 中 find/filter 所有日期为 M/YYYY 的行。这对于 ex 来说很容易使用语言环境。 en_GB 其中日期格式为 dd/MM/YYYY。这里我只搜索MM/YYYY没有错误

但是因为在 en_USdMY 之间,即 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 或任何其他字符将 MY 分隔开的任何其他日期格式时,我如何做同样的事情之间?

虚拟文件:

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&& 到将 dmy 分开,这样过滤器将不会像 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(第一个)位置,找到组句柄所在的行号。