1

我有一个包含未知数量的对象的集合。我想为这些对象中的每一个关联一个标签。我不想用数字标记每个对象,而是用字母标记它们。

例如,第一个对象将被标记为 A,第二个被标记为 B,依此类推。

当我到达 Z 时,下一个对象将被标记为 AA

阿兹?然后是BA,BB,BC。

Z Z?然后是AAA、AAB、AAC等。

我正在使用 Mapbasic(类似于 VBA),但我似乎无法围绕动态解决方案展开工作。我的解决方案假定集合可能会或可能不会超过的最大对象数。

label = pos1 & pos2

一旦 pos2 达到 ASCII“Z”,那么 pos1 将是“A”,而 pos2 将是“A”。但是,如果在“ZZ”之后还有另一个对象,这将失败。

如何克服这种静态解决方案?

4

3 回答 3

2

基本上我需要的是一个 Base 26 Counter。该函数采用“A”或“AAA”之类的参数并确定序列中的下一个字母。

Function IncrementAlpha(ByVal alpha As String) As String

Dim N As Integer
Dim num As Integer
Dim str As String

Do While Len(alpha)
    num = num * 26 + (Asc(alpha) - Asc("A") + 1)
    alpha = Mid$(alpha, 2,1)
Loop
N = num + 1

Do While N > 0
    str = Chr$(Asc("A") + (N - 1) Mod 26) & str
    N = (N - 1) \ 26
Loop
IncrementAlpha = str
End Function
于 2018-04-06T19:07:41.060 回答
1

如果我们需要将数字转换为“字母格式”,其中:

1 = A
26 = Z
27 = AA
702 = ZZ
703 = AAA  etc

...而且它需要在 Excel VBA 中,那么我们很幸运。Excel 的列以相同的方式“编号”!

Function numToLetters(num As Integer) As String
    numToLetters = Split(Cells(1, num).Address(, 0), "$")(0)
End Function

向这个函数传递一个介于1and之间的数字16384,它将返回一个介于Aand之间的字符串XFD


编辑:

我想我看错了;你没有使用 Excel。如果您使用 VBA,您应该仍然能够通过对 Excel 对象库的引用来执行此操作。

于 2018-04-06T17:33:56.100 回答
1

这应该让你在逻辑方面前进。还没有完全测试它,但你应该可以从这里开始工作。

Public Function GenerateLabel(ByVal Number As Long) As String
  Const TOKENS As String = "ZABCDEFGHIJKLMNOPQRSTUVWXY"
  Dim i As Long
  Dim j As Long
  Dim Prev As String
  j = 1
  Prev = ""
  Do While Number > 0
    i = (Number Mod 26) + 1
    GenerateLabel = Prev & Mid(TOKENS, i, 1)
    Number = Number - 26
    If j > 0 Then Prev = Mid(TOKENS, j + 1, 1)
    j = j + Abs(Number Mod 26 = 0)
  Loop
End Function
于 2018-04-06T19:17:15.777 回答