在 VBA 中用 (A->Z,AA->ZZ, AAA->ZZZ) 标记一组对象

Label a set of objects with (A->Z,AA->ZZ, AAA->ZZZ) in VBA

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

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

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

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

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

我正在使用 Mapbasic(类似于 VBA),但我似乎无法全神贯注于动态解决方案。我的解决方案假设集合可能会或可能不会超过最大数量的对象。

label = pos1 & pos2

一旦 pos2 达到 ASCII "Z",则 pos1 将是 "A",pos2 将是 "A"。但是,如果 "ZZ" 之后还有另一个对象,这将失败。

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

如果我们需要将数字转换为 "letter format" 其中:

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

...它需要在 Excel VBA 中,那么我们很幸运。 Excel 的列是 "numbered" 相同的方式!

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

向此函数传递一个介于 116384 之间的数字,它将 return 一个介于 AXFD 之间的字符串。


编辑:

我想我看错了;你 不是 使用 Excel。如果您正在使用 VBA,您应该仍然可以在对 Excel 对象库的引用的帮助下执行此操作。

基本上我需要的是一个 Base 26 计数器。该函数采用 "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

这应该让你在逻辑方面有所进展。尚未完全测试,但您应该可以从这里开始工作。

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