简体   繁体   English

从一系列单元格中按特定顺序选择值

[英]pick value in a specific order from a range of cells

I have a bunch of numbers or text in different cells eg: 我在不同的单元格中有一堆数字或文本,例如:

2   50  900 1000    6   10  10     30

or 要么

a   b   c   d   e

I need to sort them according to a starter number and a divider. 我需要根据起始编号和分隔符对它们进行排序。 For example, if the starter is 3, I will start with the third value, which in the numbers above will be be 900 and in alphabet will be "c" 例如,如果起动器是3,我将从第三个值开始,在上面的数字中将是900,在字母表中将是“c”

Then from starter I need to skip a fixed number each time, which is the divider. 然后从初学者我需要每次跳过一个固定的数字,这是分频器。 For example, if the divider is 3 then I will need every third value. 例如,如果分频器为3,那么我将需要每三个值。 In the numbers the next number to pick is 10, and in the alphabet the next value to pick is "a". 在数字中,下一个要挑选的数字是10,而在字母表中,下一个要挑选的数字是“a”。

When the search reaches the end of the range, it needs to start from start and again from the beginning. 当搜索到达范围的末尾时,它需要从头开始,从头开始。 If the value has been picked before, then I have to select the next one that has not been used. 如果之前已经选择了该值,那么我必须选择下一个尚未使用的值。

Here are more examples, using the number or letter sequences above: 以下是更多示例,使用上面的数字或字母序列:

starter:3 - divider:3 起动器:3 - 分频器:3

  • 900 10 2 1000 10 50 6 30 900 10 2 1000 10 50 6 30
  • cadbe cadbe

starter:2 - divider:2 起动器:2 - 分频器:2

  • 50 1000 10 30 900 6 10 2 50 1000 10 30 900 6 10 2
  • bdace bdace

Note that here, after 30 I would select 50, but because I've already selected it, I select the next unused number, in this case 900. Sometimes it may happen that two or three numbers are used before, so the selecting algorithm should jump to first unused one! 请注意,在30之后,我会选择50,但因为我已经选择了它,我选择下一个未使用的数字,在本例中为900.有时可能会发生之前使用过两个或三个数字,因此选择算法应该跳到第一个未使用的!

starter : 4 - divider :2 起动器:4 - 分频器:2

  • 1000 10 30 50 6 10 2 900 1000 10 30 50 6 10 2 900
  • daceb daceb

Anyway I'm not totally sure how to do it in Excel. 无论如何,我不完全确定如何在Excel中执行此操作。 I tried to use offset, index, lookup but failed. 我试图使用偏移量,索引,查找但失败了。

The data type doesn't matter, I just wanted to give two examples, so I chose to give one in numbers and one in text, since the rules for any type of data should be same. 数据类型并不重要,我只是想给出两个例子,所以我选择给一个数字和一个文本,因为任何类型数据的规则应该相同。

Is there any simple way to solve this or do I have to get my hands dirty and write a macro? 有没有简单的方法来解决这个问题,还是我必须弄脏手写宏?

Fun little mathematical exercise :-) 有趣的小数学练习:-)

For an example, I put the range of values in the top row A1:E1 : 举个例子,我将值范围放在顶行A1:E1

    A   B   C   D   E
1   aa  bb  cc  dd  ee
2   bb  dd  aa  cc  ee

In A2 I put: A2我放:

=INDEX($A$1:$E$1,MOD((COLUMNS($A2:A2)-1)*divider+starter+INT((COLUMNS($A2:A2)-1)*GCD(COLUMNS($A$1:$E$1),divider)/COLUMNS($A$1:$E$1))-1,COLUMNS($A$1:$E$1))+1)

and then just dragged the formula to the right. 然后将公式拖到右边。 The example shows a "starter" of 2 and a "divider" of 2. 该示例显示2的“启动器”和2的“分隔器”。

A few key points 几个关键点

We're using index to choose one member of the range: 我们使用索引来选择范围中的一个成员:

=INDEX($A$1:$E$1, ... )

Which column we are in (starting with zero): 我们在哪一列(从零开始):

COLUMNS($A2:A2)-1)

Number of columns in the range (the array-length): 范围内的列数(数组长度):

COLUMNS($A$1:$E$1)

The index is modulo the number of columns, but then we switch to 1-based indexes for the INDEX function, hence the subtracting and adding: 索引是以列数为模的,但是我们切换到INDEX函数的基于1的索引,因此减去并添加:

MOD( ... -1,COLUMNS($A$1:$E$1))+1

This is the portion of the index that tells us where we'd be if we weren't worried about repeating numbers (or, more precisely, it's a number congruent to the desired index modulo the array-length): 这是索引的一部分,告诉我们如果我们不担心重复数字(或者更准确地说,它是一个与数组长度模拟的所需索引一致的数字),我们将在哪里:

(COLUMNS($A2:A2)-1)*divider+starter

And this portion adds 1 every time we repeat: 每次重复时,这部分加1:

INT((COLUMNS($A2:A2)-1)*GCD(COLUMNS($A$1:$E$1),divider)/COLUMNS($A$1:$E$1))

This last part works because the GCD of the array-length and the "divider", as you call it, is equal to the number of non-overlapping, repeating sequences that exist as you add multiples of the divider mod the array-length. 最后一部分是有效的,因为数组长度的GCD和“分频器”(如你所说)等于在你添加分频器的多个数组长度时存在的非重叠的重复序列的数量。 (You can only be on one of these repeating sequences at a time.) So, the array-length / the GCD is the length of such a sequence, and once you've used that number of values you'll need to skip 1 to get to the next repeating sequence. (你一次只能在其中一个重复序列上。)所以,数组长度/ GCD是这样一个序列的长度,一旦你使用了这个数量的值,你就需要跳过1到达下一个重复序列。 We just divide our position in the output by the number of values in a repeating sequence current position / (array-length / GCD) = current position * GCD / array-length , rounding down (using INT), to see how much of an offset we need. 我们只是将输出中的位置除以重复序列current position / (array-length / GCD)的值数current position / (array-length / GCD) = current position * GCD / array-length ,向下舍入(使用INT),以查看多少抵消我们需要。

See Also: 也可以看看:

Modular Arithmetic 模数运算

GCD GCD

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM