excelperfect 导语:继续研究来自于excelxor.com的案例。建议结合本文阅读原文,会了解更多的细节,会有更大的收获。 本次的练习是:在单元格A2中给定一个字符串值,仅由大写字母组成且字符长度至少为2。在单元格B2中输入公式:如果A2中字符串的各个字符按字母升序排列(从左到右),则返回TRUE;否则返回FALSE。如图1所示。 图1 先不看答案,自已动手试一试。 公式 在单元格B2中的公式为: =AND(GESTEP(MMULT(CODE(MID(A2,ROW(INDEX(A:A,1):INDEX(A:A,LEN(A2)-1))+{0,1},1)),{-1;1}),0)) 向下拖拉即可。 公式解析 首先,让我们看一下公式中的用于生成要传递给MID函数的参数的数组的结构: ROW(INDEX(A:A,1):INDEX(A:A,LEN(A2)-1)) 该构造与下面的标准结构返回相同的数组: ROW(INDIRECT('1:'&LEN(A2)-1)) 两者比较,后者更具有易失性。 如果单元格A2中的字符串为“AABBCCCC”,很显然有8个字符,可以得到: ROW(INDEX(A:A,1):INDEX(A:A,7)) 转换为: ROW(A1:A7) 得到: {1;2;3;4;5;6;7} 现在,大多数解决方案在这里所做的就是首先将此数组传递给MID函数作为其参数start_num的值: MID(A2,{1;2;3;4;5;6;7},1) 转换为: {'A';'A';'B';'B';'C';'C';'C'} 然后,使用下面的数组执行类似运算: {2;3;4;5;6;7;8} 代入MID函数: MID(A2,{2;3;4;5;6;7;8},1) 转换为: {'A';'B';'B';'C';'C';'C';'C'} 最后,对这两个数组进行比较。没错!这是针对本问题的一种合理的解决方案。 实际上我们可以一步生成这两个数组,而不是用这种方式生成两个单独的数组。只需要确保能够对所得到的单个数组执行我们所需的比较。这里的技术是,将数组: {1;2;3;4;5;6;7} 与下面的数组相加: {0,1} 注意,该数组必须与前面的数组正交。由于第一个是单列数组,因此需要确保第二个是单行数组。因此: {1;2;3;4;5;6;7}+{0,1} 由第二个数组中的两个值与第一个数组中的每个值相加,得到: {1,2;2,3;3,4;4,5;5,6;6,7;7,8} 此时,公式转换为: =AND(GESTEP(MMULT(CODE(MID(A2,{1,2;2,3;3,4;4,5;5,6;6,7;7,8},1)),{-1;1}),0)) 先看这部分: MID(A2,{1,2;2,3;3,4;4,5;5,6;6,7;7,8},1) 转换为: {'A','A';'A','B';'B','B';'B','C';'C','C';'C','C';'C','C'} 可以看到,包含与先前两个独立数组完全相同的元素,尽管它们组合成一个7行2列的数组。 现在,获取每个字符的ASCⅡ编码: CODE({'A','A';'A','B';'B','B';'B','C';'C','C';'C','C';'C','C'}) 得到: {65,65;65,66;66,66;66,67;67,67;67,67;67,67} 现在必须确保可以相应地操纵上述数组,将每行中的两个元素彼此相减。仍然使用矩阵运算,很容易解决: MMULT({65,65;65,66;66,66;66,67;67,67;67,67;67,67},{-1;1}) 结果为: {0;1;0;1;0;0;0} 这类似于在两个单独的数组之间进行比较: {'A';'A';'B';'B';'C';'C';'C'}<{'A';'B';'B';'C';'C';'C';'C'} 然后将得到的TRUE/FALSE值转换成等价的数值。 最后,简单地查询该数组的哪个元素大于或等于0(这实际上意味着一个元素的ASCII码与上一个元素的ASCII码之差大于或等于0,即等效于前面的字符等于或小于后面的字符): =AND(GESTEP({0;1;0;1;0;0;0},0)) 转换为: =AND({1;1;1;1;1;1;1}) 结果为: TRUE 小结 1.学习Excel怎么处理两个正交且元素数量不同的数组的运算。 2.学习如何通过数组运算比较两组值的大小。
|
|
来自: hercules028 > 《excel》