在 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
向此函数传递一个介于 1
和 16384
之间的数字,它将 return 一个介于 A
和 XFD
之间的字符串。
编辑:
我想我看错了;你 不是 使用 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
我有一组物体数量未知。我想为这些对象中的每一个关联一个标签。我不想用数字标记每个对象,而是用字母标记它们。
例如,第一个对象标记为 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
向此函数传递一个介于 1
和 16384
之间的数字,它将 return 一个介于 A
和 XFD
之间的字符串。
编辑:
我想我看错了;你 不是 使用 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