Apps 脚本单元格对齐基于部分字符串/日期

问题描述 投票:0回答:1

我试图根据单元格的值确定范围内每个单元格的字体对齐方式。每个单元格包含一个开始时间和结束时间(即上午 9:30-下午 5:30),我尝试根据开始时间设置对齐方式:

  • 从凌晨 4:00 到上午 10:59 之间开始轮班:左对齐--------(>凌晨 4 点 <11am)
  • 从上午 11:00 到下午 2:00 之间开始班次:居中对齐-----(>=11am <=2pm)
  • 从下午 2:01 到凌晨 3:59 之间开始轮班:右对齐--------(>下午 2 点 <4am)
  • 其他一切居中对齐

看起来像这样:

enter image description here

我已经阅读了许多帖子来完成我正在尝试做的部分事情,但我无法创建一个有效的解决方案,到目前为止我的脚本可能值得忽略。这是一个示例表

至于剧本...

function Test1() {
  const wb = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = wb.getActiveSheet();
  const values = sheet.getRange(1,1,26,8).getValues();

然后我尝试使用以下方法,但没有成功,但是我无法弄清楚如何按字符串的一部分进行搜索或拼接范围内的所有值或拼接并将值处理为时间值。以下是我尝试合并的其他帖子:

对齐范围内的所有数字 - 无法弄清楚如何搜索部分字符串。

文本包含值无法找出在“执行某事部分”中设置格式的正确方法

基于值只能让它使用完整字符串,并且只能在第一列中使用。

google-sheets google-apps-script
1个回答
0
投票

问题中显示的网格中的值不是一天中的时间,而是看起来像一天中的时间的文本字符串。要提取开始时间,请使用

String.match()
,要决定应用哪种对齐方式,请使用
Array.find()
,如下所示:

'use strict';

/**
* Simple trigger that runs each time the user opens
* the spreadsheet.
*
* @param {Object} e The onOpen() event object.
*/
function onOpen(e) {
  SpreadsheetApp.getUi()
    .createMenu('Align')
    .addItem('Align selected cells by start time', 'alignByValue')
    .addToUi();
}


/**
* Aligns cells by the time of day extracted from their contents.
*
* @param {Range} range The range to align. Defaults to the active range.
* @param {String[][]} values Optional. The display values in the range.
*/
function alignByValue(range = SpreadsheetApp.getActiveRange(), values = range.getDisplayValues()) {
  // version 1.0, written by --Hyde, 4 May 2024
  //  - see https://stackoverflow.com/q/78427740/13045193
  const settings = {

    ////////////////////////////////
    // [START modifiable parameters]
    keyPattern: /(\d\d:\d\d)\s*(am|pm)/,
    _getKey: (s) => `${s[2]}${s[1]}`,
    alignUpperLimits: [
      ['am11:00', 'left'],
      ['pm02:01', 'center'],
      ['pm11:59', 'right'],
    ],
    // [END modifiable parameters]
    ////////////////////////////////

  };
  if (!Array.isArray(values)) values = [[values]];
  const alignments = values.map(row => row.map(value => {
    const keyValue = `0${value.trim().toLowerCase()}`.match(settings.keyPattern); // add leading zero
    if (!keyValue) return;
    const alignment = settings.alignUpperLimits.find(limit => settings._getKey(keyValue) < limit[0]);
    if (!alignment) return;
    return alignment[1];
  }));
  range.setHorizontalAlignments(alignments);
}


/**
* Simple trigger that runs each time the user manually edits the spreadsheet.
*
* @param {Object} e The onEdit() event object.
*/
function onEdit(e) {
  if (!e) {
    throw new Error(
      'Please do not run the onEdit(e) function in the script editor window. '
      + 'It runs automatically when you hand edit the spreadsheet. '
      + 'See https://stackoverflow.com/a/63851123/13045193.'
    );
  }
  alignByValue_(e);
}


/**
* Aligns cells when they are manually edited.
*
* @param {Object} e The onEdit() event object.
*/
function alignByValue_(e) {
  try {
    const parameters = [

      ////////////////////////////////
      // [START modifiable parameters]
      {
        sheetsToWatch: /^(Wk)/i,
        sheetsToExclude: /^(Master)$/i,
        columnStart: 3,
        columnEnd: 9,
        rowStart: 5,
        rowEnd: Infinity,
      },
      // [END modifiable parameters]
      ////////////////////////////////

    ];
    let sheet, sheetName;
    const settings = parameters.find(p =>
      (p.columnStart <= e.range.columnStart && e.range.columnEnd <= p.columnEnd)
      && (p.rowStart <= e.range.rowStart && e.range.rowEnd <= p.rowEnd)
      && (sheetName = sheetName || (sheet = sheet || e.range.getSheet()).getName()).match(p.sheetsToWatch)
      && (!p.sheetsToExclude || !sheetName.match(p.sheetsToExclude))
    );
    if (!settings) return;
    alignByValue(e.range, e.value); // relying on callee to get displayValues when e.value === undefined
  } catch (error) {
    e.source.toast(`${error.message} ${error.stack}`, 'Error in alignByValue_()', 30);
    throw error;
  }
}

参见 String.match()Array.find()

© www.soinside.com 2019 - 2024. All rights reserved.