终极短自定义数字格式 - K、M、B、T 等、Q、D、Googol

pla*_*er0 20 string-formatting google-sheets number-formatting google-apps-script array-formulas

有没有办法在谷歌表格中自定义大数字的格式(两种方式至少最多 10^100):

thousands                > K
millions                 > M
billions                 > B
trillions                > T
etc...
negative quadrillions    > Q
decillions               > D
Run Code Online (Sandbox Code Playgroud)

可以通过:

  • 内部自定义数字格式
  • 公式(ofc的数组公式)
  • 与此类似的脚本只是扩展以涵盖更多内容

                                                            10000.1     10.0K
                                                                100    100.0 
                                                               1000      1.0K
                                                              10000     10.0K
                                                            -100000   -100.0K
                                                           45646454     45.6M
                                                      5654894844216      5.7T
                                                         4655454544      4.7B
                                                     46546465455511     46.5T
                                                    -46546465455511    -46.5T
4654646545551184854556546454454400000000000000000000000000010000000      4.7U
    
                                                         -1000.9999     -1.0K
                                                          -100.8989   -100.9 
                                                            -20.354    -20.4 
                                                               1.03      1.0 
                                                             22E+32      2.2D
Run Code Online (Sandbox Code Playgroud)

pla*_*er0 37

内部自定义数字格式解决方案:

遗憾的是,谷歌表格中的内部格式默认只能处理 3 种类型的数字:

  • 正数(1、2、5、10、...)
  • 负(-3、-9、-7、...)
  • 零 (0)

可以调整它以显示自定义格式,例如数千K,百万M和常规小数字:

[>999999]0.0,,"M";[>999]0.0,"K";0
Run Code Online (Sandbox Code Playgroud)

或者只有数千K、数百万M、数十亿B

[<999950]0.0,"K";[<999950000]0.0,,"M";0.0,,,"B"
Run Code Online (Sandbox Code Playgroud)

或者只有负千K、负数百万M、负数十亿B

[>-999950]0.0,"K";[>-999950000]0.0,,"M";0.0,,,"B"
Run Code Online (Sandbox Code Playgroud)

或者只有数百万M、数十亿B、数万亿T

[<999950000]0.0,,"M";[<999950000000]0.0,,,"B";0.0,,,,"T"
Run Code Online (Sandbox Code Playgroud)

或仅从负数百万M到正数百万的数字M

[>=999950]0.0,,"M";[<=-999950]0.0,,"M";0.0,"K"
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但你总是只有 3 个插槽可以使用,这意味着你不能拥有数万亿个插槽作为第四种类型/插槽。仅供参考,第四个插槽存在,但它是为文本保留的。要了解有关 Google 表格中内部格式的更多信息,请参阅:




公式(数组公式)解法:

公式方法更加通用...首先,您需要决定要使用的系统/标准(美国、欧洲、希腊、国际、非官方等...):

之后尝试:

=INDEX(REGEXREPLACE(IFNA(TEXT(A:A/10^(VLOOKUP(LEN(TEXT(INT(ABS(A:A)), "0"))-1, 
 SEQUENCE(35, 1,, 3), 1, 1)), "#.0")&VLOOKUP(ABS(A:A)*1, {{10^SEQUENCE(34, 1, 3, 3)}, 
 {"K  "; "M  "; "B  "; "T  "; "Qa "; "Qi "; "Sx "; "Sp "; "O  "; "N  "; "D  "; "Ud "; 
  "Dd "; "Td "; "Qad"; "Qid"; "Sxd"; "Spd"; "Od "; "Nd "; "V  "; "Uv "; "Dv "; "Tv "; 
  "Qav"; "Qiv"; "Sxv"; "Spv"; "Ov "; "Nv "; "Tr "; "Ut "; "Dt "; "Tt "}}, 2, 1), 
 IF(ISBLANK(A:A),, TEXT(A:A, "0.0   "))), "^0\.0   $", "0     "))
Run Code Online (Sandbox Code Playgroud)
  • 适用于正数
  • 适用于负数
  • 与零一起工作
  • 适用于十进制数
  • 使用数值
  • 适用于纯文本数字
  • 使用科学记数法
  • 适用于空白单元格
  • 两种方式都可以达到 googol 10^104

在此输入图像描述



如果您对它的工作原理感兴趣,可以加分......

让我们从虚拟数组开始{{},{}}SEQUENCE(34, 1, 3, 3)将为我们提供从 number 开始、步长为 number 的列中的34数字:133

在此输入图像描述

10这些将在幂上升时用作指数^

在此输入图像描述

所以我们的虚拟数组将是:

在此输入图像描述

接下来,我们将其插入作为VLOOKUP检查ABSA 列的绝对值(将负值转换为正值)乘以的第二个参数*1,以防 A 列的值不是数字。通过VLOOKUP我们返回第二2列,作为第四个参数,我们使用近似模式1

在此输入图像描述

从 -999 到 999 的数字此时会故意出错,因此我们稍后可以使用翻译IFNA来“修复”我们的错误IF(A:A=IF(,,),, TEXT(A:A, "#.0 ")):如果范围 A:A 确实为空,则不输出ISBLANK任何内容,否则使用提供的模式格式化 A 列,#.0例如。如果单元格 A5 = 空,则输出将为空白单元格...如果 -999 < A5=50 < 999,则输出将为 50.0

在此输入图像描述

最后一部分:

TEXT(A:A/10^(VLOOKUP(LEN(TEXT(INT(ABS(A:A)), "0"))-1, 
SEQUENCE(35, 1,, 3), 1, 1)), "#.0")
Run Code Online (Sandbox Code Playgroud)

ABS(A:A)将负数转换为正数。INT删除小数(如果有)。TEXT(, "0")将科学计数法转换3E+8为常规数字300000000LEN来数数字。-1纠正以 10 为基数的表示法。VLOOKUP上面构造的数字为SEQUENCE35中的数字1,这次从数字 0 开始,,,步长为3数字。以vlookup 的近似模式返回VLOOKUP第一1列(例如序列) 。当上升功率1时插入这个数字作为指数。并取 A 列中的值并将其除以上述构造的特定指数幂的数字。最后,将其格式化为10^10^TEXT#.0

在此输入图像描述

要将丑陋变为0.0美丽,0我们只需使用REGEXREPLACE. 使用andINDEX代替较长的ARRAYFORMULA.

旁注:要删除尾随空格(可以添加漂亮的对齐方式,哈哈),可以从公式中删除它们,也可以TRIMINDEX.




脚本解决方案:

感谢@TheMaster对此进行报道

这是它的一个模组:

/**
 * formats various numbers according to the provided short format
 * @customfunction
 * @param {A1:C100} range a 2D array
 * @param {[X1:Y10]} database [optional] a real/virtual 2D array 
 * where the odd column holds exponent of base 10 
 * and the even column contains format suffixes
 * @param {[5]} value [optional] fix suffix to fixed length 
 * by padding spaces (only if the second parameter exists)
 */
// examples:
// =CSF(A1:A)
// =CSF(2:2; X5:Y10)
// =CSF(A1:3; G10:J30)
// =CSF(C:C; X:Y; 2)                        to use custom alignment
// =CSF(C:C; X:Y; 0)                        to remove alignment
// =INDEX(TRIM(CSF(A:A)))                   to remove alignment
// =CSF(B10:D30; {3\ "K"; 4\ "TK"})         for non-english sheets
// =CSF(E5, {2, "deci"; 3, "kilo"})         for english sheets
// =INDEX(IF(ISERR(A:A*1); A:A; CSF(A:A)))  to return non-numbers
// =INDEX(IF((ISERR(A:A*1))+(ISBLANK(A:A)), A:A, CSF(A:A*1)))  enforce mode
function CSF(
  range,
  database = [
    [3,   'K'  ], //Thousand
    [6,   'M'  ], //Million
    [9,   'B'  ], //Billion
    [12,  'T'  ], //Trillion
    [15,  'Qa' ], //Quadrillion
    [18,  'Qi' ], //Quintillion
    [21,  'Sx' ], //Sextillion
    [24,  'Sp' ], //Septillion
    [27,  'O'  ], //Octillion
    [30,  'N'  ], //Nonillion
    [33,  'D'  ], //Decillion
    [36,  'Ud' ], //Undecillion
    [39,  'Dd' ], //Duodecillion
    [42,  'Td' ], //Tredecillion
    [45,  'Qad'], //Quattuordecillion
    [48,  'Qid'], //Quindecillion
    [51,  'Sxd'], //Sexdecillion
    [54,  'Spd'], //Septendecillion
    [57,  'Od' ], //Octodecillion
    [60,  'Nd' ], //Novemdecillion
    [63,  'V'  ], //Vigintillion
    [66,  'Uv' ], //Unvigintillion
    [69,  'Dv' ], //Duovigintillion
    [72,  'Tv' ], //Trevigintillion
    [75,  'Qav'], //Quattuorvigintillion
    [78,  'Qiv'], //Quinvigintillion
    [81,  'Sxv'], //Sexvigintillion
    [84,  'Spv'], //Septenvigintillion
    [87,  'Ov' ], //Octovigintillion
    [90,  'Nv' ], //Novemvigintillion
    [93,  'Tr' ], //Trigintillion
    [96,  'Ut' ], //Untrigintillion
    [99,  'Dt' ], //Duotrigintillion
    [100, 'G'  ], //Googol
    [102, 'Tt' ], //Tretrigintillion or One Hundred Googol
  ],
  value = 3
) {
  if (
    database[database.length - 1] &&
    database[database.length - 1][0] !== 0
  ) {
    database = database.reverse();
    database.push([0, '']);
  }
  const addSuffix = num => {
    const pad3 = (str = '') => str.padEnd(value, ' ');
    const decim = 1              // round to decimal places
    const separ = 0              // separate number and suffix
    const anum = Math.abs(num);
    if (num === 0) 
     return '0' + ' ' + ' '.repeat(separ) + ' '.repeat(decim) + pad3();
    if (anum > 0 && anum < 1) 
     return String(num.toFixed(decim)) + ' '.repeat(separ) + pad3();
    for (const [exp, suffix] of database) {
      if (anum >= Math.pow(10, exp))
        return `${(num / Math.pow(10, exp)).toFixed(decim)
         }${' '.repeat(separ) + pad3(suffix)}`;
    }
  };
  return customFunctionRecurse_(
    range, CSF, addSuffix, database, value, true
  );
}
function customFunctionRecurse_(
  array, mainFunc, subFunc, ...extraArgToMainFunc
) {
  if (Array.isArray(array))
    return array.map(e => mainFunc(e, ...extraArgToMainFunc));
  else return subFunc(array);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

旁注 1:此脚本不需要在使用前获得授权
旁注 2:单元格格式需要设置为“自动”或“数字”,否则使用强制模式




额外的: