将日历上的日期与另一个字段匹配

Posted

技术标签:

【中文标题】将日历上的日期与另一个字段匹配【英文标题】:Matching a date on a calendar to another field 【发布时间】:2021-08-08 16:31:04 【问题描述】:

好的,我的页面上有一个日历,每天都是该日期的格式化版本,例如。

Jan 2021
1  2  3  4
5  6  7  8
etc..

因此 1 单元格将包含 2021 年 1 月 1 日(但格式化为仅显示“1”[d]) 我在该页面上还有一个单元格 (K5) 供用户输入日期,例如:[1/1/2021]

我想要一个脚本,如果它与用户输入单元格匹配,它会更改日历中当天的边框颜色。

代码:

function onEdit(e) 
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var date = sheet.getRange("K5").getValue();
if (e.range.getValue()== date) 
e.range.setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid); 
;

这行不通,我想不出一种方法让代码对日历的每个单元格都有效(有 2 年的价值,所以超过 1000 个单元格)。 它不需要 onEdit,我只是在测试实际的 setBorder 函数是否有效(它确实有效) 另外,我不能使用条件格式,因为我已经用它来更改 bg 和其他字体颜色(并且无论如何都没有更改边框颜色的选项)

如果你想看看你能做什么,我已经制作了一个只有 Jan 的迷你版本: https://docs.google.com/spreadsheets/d/1oV4lE8cQB-e2bVc_HgiGM31ivk3uHxPcqsSdLdCxsmQ/edit?usp=sharing

【问题讨论】:

您能否再添加至少一个月(可能是两个月),以便我了解日历在工作表上的位置是否有规律?确保它与实物相符。 哈哈,希望你已经准备好了,完成了! 【参考方案1】:

查找所有日期的另一种方法是使用公式在不同的工作表中显示日期及其地址。此公式将输出一系列日期及其假期地址。然后可以使用 onEdit() 脚本读取它以将边框放在正确的地址上:

公式:

=ARRAYFORMULA(IFERROR(QUERY(SPLIT(FLATTEN(N(Calendar!E9:AY)&"|"&ROW(Calendar!E9:AY)&"|"&COLUMN(Calendar!E9:AY)&"|"&LEN(TO_TEXT(Calendar!E9:AY))),"|",0,0),"select Col1,Col2,Col3 where Col4<3 and ("&TEXTJOIN(" or",TRUE," Col1="&FILTER(Calendar!BE28:BE100,Calendar!BE28:BE100<>""))&")")))

脚本:

function onEdit(e)
  holidayBorders(e);


function holidayBorders(e)
  var sheet = e.range.getSheet();
  if(e.value && sheet.getName()=='Calendar' && e.range.getColumn()==57 && e.range.getRow() >= 28)
    SpreadsheetApp.flush();
    Utilities.sleep(10000);
    var datasheet = e.source.getSheetByName('DATA');
    var rcs = datasheet.getRange('AQ3:AR').getValues().filter(e=> e[0]);

    for (let i=0;i<rcs.length;i++)
      sheet.getRange(rcs[i][0],rcs[i][1]).setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid);
    
  

【讨论】:

感谢@MattKing 出色的解决方案,它运行良好。我想知道将不在列表中的任何日期的颜色设置回黑色有多难。目前,一旦删除日期,日期就会保持红色边框。 @JoeW 我添加了一行代码,在循环假期并将它们标记为红色之前清除所有边界。我还取消了添加日期以便 onedit 运行的条件。这样清除日期也将运行该函数。 太棒了,你真是个天才!现在似乎工作得很好。非常感谢!【参考方案2】:

您可以执行以下操作:

使用getValues()获取范围内的所有值。 遍历生成的二维数组中的所有值。 对于每个值,检查 (1) 该值是否为Date(例如,使用instanceof)以及两个日期是否来自同一天(例如,使用this)。李> 如果两个条件都满足,设置边框。

代码sn-p:

function setBorders() 
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getActiveSheet();
  var date = sheet.getRange("K5").getValue();
  var firstRow = 7;
  var firstCol = 5;
  var data = sheet.getRange(firstRow, firstCol, sheet.getLastRow() - firstRow + 1, sheet.getLastColumn() - firstCol + 1).getValues();  
  data.forEach((row, i) => 
    row.forEach((value, j) => 
      if (value instanceof Date && sameDay(date, value)) 
        sheet.getRange(i + firstRow, j + firstCol).setBorder(true, true, true, true, true, true, "red", SpreadsheetApp.BorderStyle.solid);
      
    );
  )


function sameDay(date1, date2) 
  return date1.getFullYear() === date2.getFullYear() &&
  date1.getMonth() === date2.getMonth() &&
  date1.getDate() === date2.getDate();

【讨论】:

以上是关于将日历上的日期与另一个字段匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个字段中的日期与另一字段中的时间结合起来 - MS SQL Server

将具有两个日期列的一个数据框与另一个具有两个日期列的数据框合并

比较 MongoDB 中的两个日期字段

更改月份日历上的日期颜色

日期时间日历:在单个输入字段中选择日期范围

如何更改zabuto日历上的日期