如何停止/冻结/暂停不稳定的 RAND / RANDBETWEEN / RANDARRAY?

pla*_*er0 1 random volatile spreadsheet google-sheets google-sheets-formula

有没有一种简单的方法(解决方法)如何禁用像=RAND() =RANDARRAY() =RANDBETWEEN()谷歌电子表格中那样的易失性函数的自动重新计算(?)

  • 没有脚本
  • 没有插件
  • 没有宏

在构建密钥生成器的情况下,我们需要处理多个RANDBETWEEN输出,每次单元格更改都会重新计算,并且这些RANDBETWEEN数字不能在我们不断编辑的工作表中停留更长的时间.

那里有一个有问题的冰柜插件和许多需要安装和一定程度的改装/知识的非通用脚本变体,那么如何以旧方式做到这一点?

pla*_*er0 7

首先,让我们看看狐狸怎么说

=WHATTHEFOXSAY()
Run Code Online (Sandbox Code Playgroud)

是一个独特的复活节彩蛋谷歌表函数(由@kishkin发现),它根据用户需求随机生成一个预设的文本字符串,这是一个很大的问题,因为虽然生成是随机的,但重新计算不受onEditonChangeonOpen 的影响事件,所以有一些调整,我们可以生成一个随机数,而无需使用类似挥发性功能RAND()RANDBETWEEN()ARRAYRAND()它不能冷冻/暂停

狐狸只会说这些话:

A-oo-oo-oo-ooo!
Hatee-hatee-hatee-ho!   
Wa-pa-pa-pa-pa-pa-pow!  
A-bubu-duh-bubu-dwee-dum    
Fraka-kaka-kaka-kaka-kow!   
Jacha-chacha-chacha-chow!   
Gering-ding-ding-ding-dingeringeding    
Joff-tchoff-tchoff-tchoffo-tchoffo-tchoff!  
    
Run Code Online (Sandbox Code Playgroud)

例如。我们用这个函数得到的是 8 次随机中的 1 次,这并不多,所以我们需要扩大它(假设按 9 条狐狸尾巴的顺序)。遗憾的是函数不支持ARRAYFORMULA,因此我们需要构造{}一个数组:

={WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}
Run Code Online (Sandbox Code Playgroud)

然后我们将这种狐狸语言转换为数字,例如:

=INDEX(LEN(
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}))
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要一个开关。没什么特别的,只是一个简单的IF语句和一个复选框:

=ARRAYFORMULA(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()})))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/qIpobyO.png

这将使我们能够通过切换复选框来完全控制重新计算。最后一步是通过将所有数字相乘来为我们的随机性添加更多变化来扩大我们最初的 1/8 机会PRODUCT,为了更有趣,我们将其乘以PI3 次幂:

=ARRAYFORMULA(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}))))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/MqkvTEN.png



无限刀片作品

到目前为止,我们似乎并没有创建一些有用的东西……一个带有一些随机数字来回循环的复选框(在这一点上根本不是随机的)……所以让我们进入下一个级别。我们的真正目标是创建一串数字,从中提取某些部分并将它们转换为最终输出。为此,我们需要利用SEQUENCE我们TRANSPOSE获得额外力量的力量:

=TRANSPOSE(SEQUENCE(5, 4, 3, 2))
Run Code Online (Sandbox Code Playgroud)

这转换为 5 列乘以 4 行的网格,其中第一个单元格以数字 3 开头,每个下一个单元格(按列)的值都大 2

https://i.imgur.com/TEARjgg.png

现在让我们定义我们的最终输出:

  • 3x 唯一字符串
  • 每个字符串有 16 个字符
  • 数字从09
  • 和小写字母从af

此时我们SEQUENCE将如下所示:

=TRANSPOSE(SEQUENCE(16, 3, 29, 73))
Run Code Online (Sandbox Code Playgroud)
16 = columns
3  = rows
29 = starting point
73 = stepping
Run Code Online (Sandbox Code Playgroud)

对于第 3 个和第 4 个参数 ( 29& 73),我们可以使用一些不错的素数,然后再乘以我们的整个序列PI()^3以增加混乱。我们还需要将我们的数字输出转换为纯文本字符串以避免 1.79769E+308符号,因此我们使用TEXT

=ARRAYFORMULA(TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()})))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/xZaf7F1.png

在这一点上,我们在整个网格中的数字分布非常好



终极十六进制/密码生成器

那里的每个角色都有自己的代码。您可以通过在工作表中运行此 AF 来检查它:

=ARRAYFORMULA({{"character", "code"};
 {CHAR(SEQUENCE(2500, 1, 33)), SEQUENCE(2500, 1, 33)}})
Run Code Online (Sandbox Code Playgroud)
ROW(48:57)     = 0-9
ROW(65:90)     = A-Z
ROW(97:122)    = a-z
ROW(1040:1071) = ?-?
ROW(1072:1103) = ?-?
ROW(913-937)   = ?-?
ROW(945-969)   = ?-?
Run Code Online (Sandbox Code Playgroud)

在我们的例子的目的,我们需要的字符代码0-9a-f

ROW(48:57)     = 0-9
ROW(97:102)    = a-f
Run Code Online (Sandbox Code Playgroud)

我们将它放入数组{}并按降序排序(这是因为我们不想锁定自己无法到达列表中位置较低的字符)。然后我们JOIN用或|分隔符准备好进行正则表达式:

=JOIN("|", SORT({ROW(48:57); ROW(97:102)}, 1, ))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/e2ryNfb.png

基本上,这个想法是REGEXEXTRACT首先在我们的数字网格中从上面连接的字符串中找到数字,以防万一没有匹配,我们从我们的范围中添加IFNA一些数字(102在这个例子中)的后备:

=ARRAYFORMULA(IFNA(REGEXEXTRACT(
 TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()})))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT({ROW(48:57); ROW(97:102)}, 1, ))), 102))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/Ug​​2UGEJ.png

并召唤CHAR角色:

=ARRAYFORMULA(CHAR(IFNA(REGEXEXTRACT(
 TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()})))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT({ROW(48:57); ROW(97:102)}, 1, ))), 102)))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/fssIdtC.png

现在最后一步是用查询粉碎它并删除残留的空格 - 更多关于查询粉碎的信息在这里

=ARRAYFORMULA(SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(
 CHAR(IFNA(REGEXEXTRACT(TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()}, 
 {WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()})))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT({ROW(48:57); ROW(97:102)}, 1, ))), 102))),,
 9^9)), " ", ))
Run Code Online (Sandbox Code Playgroud)

https://i.imgur.com/mI7jt0M.png


概括

  • 这些字符串真的是随机的吗?ofc 不是 - 它们只是“足够随机”,因为我们知道“熵”规则,但祝你好运用手破解它......
  • 主要的关键点是没有发生第 3 方重新计算,因此值保持暂停状态并在切换复选框时生成新值
  • 这些字符串会在一段时间内重复吗?- 是的,他们可以,就像常规RAND()功能一样
  • 有没有可能一次性生成两个相同的密钥?- 是的,它可能会发生,但可以通过多种方法来降低几率或引入UNIQUE()或添加更多狐狸尾巴
  • 请注意这个特殊场合:onOpen事件将WHATTHEFOXSAY()在每次复选框切换后重新计算一次!!因此,F5如果您需要使用冻结值,建议您在每次切换复选框后使用键刷新电子表格

如果您希望在某些时间段内拥有一个新的自动生成的字符串,您可以插入一个 volatile 函数TODAY()NOW()- 但请注意,每次编辑任何单元格时或每分钟/小时,当您不编辑任何内容时,都会进行重新计算
(取决于在..//文件>电子表格设置)

https://i.imgur.com/Gn4z6J5.png

如何不对每个单元格更改重新计算并在每个复选框开关或每 6 分钟重新计算一次?每周一次?每个奇数月?只有周一和周三吗?每 11 小时一次?可能的!我们需要一个更简单的IF语句放置在电子表格中的任何位置,该语句将承载我们的逻辑门并输出数组{}星座中的值,以便我们可以使用我们的 Fox 公式引用一个不包含具有易失性元素的公式的单元格。例子

在此处输入图片说明

  • 为了狐狸! (5认同)