簡體   English   中英

如何使用公式或腳本將序數添加到 Google 表格中水平非連續范圍內設置的值?

[英]How To Add The Ordinal Count To Values Set In Horizontal Non-Contiguous Ranges In Google Sheets With A Formula Or A Script?

問題:

我正在嘗試將每個序號引用添加到每個值正上方的每個單元格中的一組重復值。

這些值按水平和非連續順序組織。

我在下面展示的插圖示例對於測試目的很簡單,但最終用途應該是數百個值/范圍,因此最好使用腳本或我找到的公式的簡化版本。

插圖示例:

非連續范圍的序數

其他相關問題和解決方案:

我發現使用以下公式作為解決方案的問題和答案解決了相同的問題,但針對垂直和連續值:

=COUNTIF(A$1:A1,A1)

=COUNTIF(A$1:A1,A1)&MID("thstndrdth",MIN(9,2*RIGHT(COUNTIF(A$1:A1,A1))*(MOD(COUNTIF(A$1:A1,A1)-11,100)>2)+1),2)

計算復制的序數

到目前為止我的公式:

=TRANSPOSE(INDIRECT($P$21&(SUM(Q21))&":"&$P$21&(SUM(Q21,I22)-1)))

=TRANSPOSE(INDIRECT($P$21&(SUM(Q21,I22))&":"&$P$21&(SUM(Q21,I22,I26)-1)))

=TRANSPOSE(INDIRECT($P$21&(SUM(Q21,I22,I26))&":"&$P$21&(SUM(Q21,I22,I26,I30)-1)))

我使用上面的公式,需要將其復制粘貼到每個水平范圍的第一個單元格正上方的單元格中。

我需要引用SUM Functions 部分中的每個單元格,因為電子表格將充當模板,新數據集每次都會有所不同。

因此,單元格需要以某種動態方式返回 output(不能對其進行硬編碼)。

公式問題是當我們進入新范圍時,它需要越來越多的單元格引用。 由於要添加到SUM函數中的內聯單元越來越多,因此數百個水平范圍變得困難。 它也容易出錯。 如果之后添加行或列,它可能會中斷。

試驗:

我原本沒想過使用 INDIRECT Function(我以前從來不需要)。 但我不知道任何其他 Google 表格 function 能夠以更簡單的方式實現最終結果。

問題:

對於公式解決方案,您建議用什么方法來避免SUM Function 方法獲得相同的結果?

對於公式,有什么比INDIRECT和/或SUM更簡單的函數更有效?

我也想過用一個腳本來做這件事,但我不能把整個想法放到一個可管理的腳本概念過程中。 如果腳本更合適,您有什么建議?

非常感謝您的幫助!

樣品表:

樣品表

參考:

Excel 間接 Function

我能夠創建一個腳本來顯示復制的序數,但只對應一個范圍。 編輯:我已將其修改為也接受多個行范圍。 請參閱下面的更新答案:

腳本:

function showOrdinal(range) {
  var values, mode;
  if (typeof range == 'string') {
    values = SpreadsheetApp.getActiveSheet().getRange(range).getValues();
    mode = values.length;
  }
  else {
    values = range;
    mode = 1;
  }
  var fValues = values.flat();
  // horizontal
  if(mode == 1)
    return [fValues.map((x,i) => {
      return getNumberWithOrdinal(fValues.slice(0, i + 1).filter(e => e == x).length);
    })];
  // vertical
  else
    return fValues.map((x,i) => {
      return [getNumberWithOrdinal(fValues.slice(0, i + 1).filter(e => e == x).length)];
    });
}

function showOrdinal2(range) {
  var values = SpreadsheetApp.getActiveSheet().getRange(range).getValues();
  var output = [];
  var order, subTotal;
  values.forEach((x, i) => {
    if(x.flat().filter(String).length) {
      subTotal = values.slice(0, i + 1).flat().filter(String);
      order = x.filter(String);
      if(subTotal.length == order.length)
        output.push(showOrdinal(order).flat());
      else {
        output.pop();
        output.push(order.map(x => {
          var count = subTotal.filter(e => e == x).length;
          return getNumberWithOrdinal(count);
        }));
      }
      output.push(order)
    }
    else
      output.push(x);
  })
  Logger.log(output);
  return output;
}

// get ordinal number
// https://stackoverflow.com/a/31615643/14606045
function getNumberWithOrdinal(n) {
  var s = ["th", "st", "nd", "rd"],
      v = n % 100;
  return n + (s[(v - 20) % 10] || s[v] || s[0]);
}

Output:

輸出

筆記:

  • 我重用了我的舊 function 並讓另一個人使用它。 如果您需要單行/列, showOrdinal就足夠了。 如果您想要多行,則應使用showOrdinal2
  • 要傳遞的范圍假定第一行應該是第一個范圍,而不是空白的。 並且范圍的最后一行應該包含數據的最后一行。
  • 兩者之間不應有不相關的數據,只有空格,並且數據之間應至少有 1 個空格才能正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM