I have a function I am trying to do for a database I am working on for my job. I'm not the most proficient with Access so I apologize if I am not wording this in the best way.
What I am trying to do is create a query/macro that will mimic the behavior as shown
and result into this:
The logic is as follows
1) for each record - take the LEN of the string in StdName. Take that number of characters and UPDATE that to the Name field. The remaining characters after the LEN is moved to the 'SuffixString' Field
2)for each record - count the number of occurrences of the string in the 'StdName' field for any records ON OR BEFORE the index number and UPDATE the 'Name' field with whatever is in there already and concatenate with "_n" where n is the occurence
example: index 1 - has one occurrence of 'Car1' in the StdName Field between record 1 and record 1. index 1 'Name' is changed to Car1_1
example: index 2 - has two occurrences of 'Car1' in the StdName Field between record 1 and record 2. index 2 'Name' is changed to Car1_2
example: index 6 - has one occurrence of 'Car3" in the StdName Field between record 1 and record 6. index 6 'Name' is changed to Car3_1
Can something like this be done with an access query? I've never developed in Access before and my boss really wants to see this function kept inside access instead of being moved in an out of excel.
(I have step 1 setup this way to later put in logic where StdName does not match Name. example: "Car1_1" for Name and StdName "Car2". I realize I could just Concatenate StdName with the function in step 2 in this example i described, but I have a real world purpose of doing it this way)
This will be done on an MDB format
Thank you
You can use my RowCounter function:
SELECT RowCounter(CStr([Index]),False,[StdName])) AS RowID, *
FROM YourTable
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
or:
SELECT [StdName] & "_" & CStr(RowCounter(CStr([Index]),False,[StdName]))) AS RankedName, *
FROM YourTable
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
Edit - to update:
UPDATE s_before
SET [Name] = [StdName] & "_" & CStr(RowCounter(CStr([Index]),False,[StdName]))
WHERE (RowCounter(CStr([Index]),False) <> RowCounter("",True));
Code:
Public Function RowCounter( _
ByVal strKey As String, _
ByVal booReset As Boolean, _
Optional ByVal strGroupKey As String) _
As Long
' Builds consecutive RowIDs in select, append or create query
' with the possibility of automatic reset.
' Optionally a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query):
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' Usage (with group key):
' SELECT RowCounter(CStr([ID]),False,CStr[GroupID])) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowCounter(vbNullString, False)
' 2. Run query:
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter("",True)=0);
'
' 2002-04-13. Cactus Data ApS. CPH
' 2002-09-09. Str() sometimes fails. Replaced with CStr().
' 2005-10-21. Str(col.Count + 1) reduced to col.Count + 1.
' 2008-02-27. Optional group parameter added.
' 2010-08-04. Corrected that group key missed first row in group.
Static col As New Collection
Static strGroup As String
On Error GoTo Err_RowCounter
If booReset = True Then
Set col = Nothing
ElseIf strGroup <> strGroupKey Then
Set col = Nothing
strGroup = strGroupKey
col.Add 1, strKey
Else
col.Add col.Count + 1, strKey
End If
RowCounter = col(strKey)
Exit_RowCounter:
Exit Function
Err_RowCounter:
Select Case Err
Case 457
' Key is present.
Resume Next
Case Else
' Some other error.
Resume Exit_RowCounter
End Select
End Function
Related
I’m using this code and I’m trying to get it so that the row number resets whenever a certain field changes in a qry. I have the below to functions and then I use it in the qry. I export the query to use elsewhere.
Any Ideas and or samples?
For example, if field A is orange, orange, orange, banana, apple, apple, grapefruit.
Then I’m looking to have this in field B: 001, 002, 003, 001, 001, 002, 001
This is what I need | This is what I get
Field A Field B | Field A Field B
orange 001 | orange 1
orange 002 | orange 2
orange 003 | orange 3
banana 001 | banana 4
apple 001 | apple 5
apple 002 | apple 6
grapefruit 001 | grapefruit 7
Option Compare Database
Private lngRowNumber As Long
Public Function RowNumber(UniqueKeyVariant As Variant) As Long
lngRowNumber = lngRowNumber + 1
RowNumber = lngRowNumber
End Function
Public Function ResetRowNumber() As Boolean
lngRowNumber = 0
ResetRowNumber = True
End Function
Query
SELECT
TBL_Test.RowID,
TBL_Test.Cust_Number,
TBL_Test.Loan_Number,
RowNumber(TBL_Test.RowID) AS RowNum
FROM TBL_Test
WHERE (((ResetRowNumber())<>False))
ORDER BY TBL_Test.Cust_Number, TBL_Test.Loan_Number;
First, you miss is a unique ID, then an expanded function that takes a group key.
So, add an AutoNumber field to table as the first step.
Next, at my project VBA.RowNumbers you can find my function RowNumber which has the option for a group key:
' Builds consecutive row numbers in a select, append, or create query
' with the option of a initial automatic reset.
' Optionally, a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query having an ID with an index):
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' Usage (typical select query having an ID without an index):
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber("","",True)=0);
'
' Usage (with group key):
' SELECT RowNumber(CStr([ID]), CStr[GroupID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowNumber(vbNullString, True)
' 2. Run query:
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber("","",True)=0);
'
' 2020-05-29. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RowNumber( _
ByVal Key As String, _
Optional ByVal GroupKey As String, _
Optional ByVal Reset As Boolean) _
As Long
' Uncommon character string to assemble GroupKey and Key as a compound key.
Const KeySeparator As String = "¤§¤"
' Expected error codes to accept.
Const CannotAddKey As Long = 457
Const CannotRemoveKey As Long = 5
Static Keys As New Collection
Static GroupKeys As New Collection
Dim Count As Long
Dim CompoundKey As String
On Error GoTo Err_RowNumber
If Reset = True Then
' Erase the collection of keys and group key counts.
Set Keys = Nothing
Set GroupKeys = Nothing
Else
' Create a compound key to uniquely identify GroupKey and its Key.
' Note: If GroupKey is not used, only one element will be added.
CompoundKey = GroupKey & KeySeparator & Key
Count = Keys(CompoundKey)
If Count = 0 Then
' This record has not been enumerated.
'
' Will either fail if the group key is new, leaving Count as zero,
' or retrieve the count of already enumerated records with this group key.
Count = GroupKeys(GroupKey) + 1
If Count > 0 Then
' The group key has been recorded.
' Remove it to allow it to be recreated holding the new count.
GroupKeys.Remove (GroupKey)
Else
' This record is the first having this group key.
' Thus, the count is 1.
Count = 1
End If
' (Re)create the group key item with the value of the count of keys.
GroupKeys.Add Count, GroupKey
End If
' Add the key and its enumeration.
' This will be:
' Using no group key: Relative to the full recordset.
' Using a group key: Relative to the group key.
' Will fail if the key already has been created.
Keys.Add Count, CompoundKey
End If
' Return the key value as this is the row counter.
RowNumber = Count
Exit_RowNumber:
Exit Function
Err_RowNumber:
Select Case Err
Case CannotAddKey
' Key is present, thus cannot be added again.
Resume Next
Case CannotRemoveKey
' GroupKey is not present, thus cannot be removed.
Resume Next
Case Else
' Some other error. Ignore.
Resume Exit_RowNumber
End Select
End Function
Then you can build this query:
SELECT
Fruit.[Field A],
Format(RowNumber(CStr([Id]),[Field A]),"000") AS [Field B]
FROM
Fruit
WHERE
RowNumber(CStr([Id]))<>RowNumber("","",True);
which will output:
I would like to add a auto sequential number under STOP # field. I have fields as Route, Direction, Stop #, & location. So for example M1 going North has 10 stops (1-10) and vice versa for South bound.
You can use the RowNumber function from my article:
Sequential Rows in Microsoft Access
' Builds consecutive row numbers in a select, append, or create query
' with the option of a initial automatic reset.
' Optionally, a grouping key can be passed to reset the row count
' for every group key.
'
' 2018-08-23. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RowNumber( _
ByVal Key As String, _
Optional ByVal GroupKey As String, _
Optional ByVal Reset As Boolean) _
As Long
' Uncommon character string to assemble GroupKey and Key as a compound key.
Const KeySeparator As String = "¤§¤"
' Expected error codes to accept.
Const CannotAddKey As Long = 457
Const CannotRemoveKey As Long = 5
Static Keys As New Collection
Static GroupKeys As New Collection
Dim Count As Long
Dim CompoundKey As String
On Error GoTo Err_RowNumber
If Reset = True Then
' Erase the collection of keys and group key counts.
Set Keys = Nothing
Set GroupKeys = Nothing
Else
' Create a compound key to uniquely identify GroupKey and its Key.
' Note: If GroupKey is not used, only one element will be added.
CompoundKey = GroupKey & KeySeparator & Key
Count = Keys(CompoundKey)
If Count = 0 Then
' This record has not been enumerated.
'
' Will either fail if the group key is new, leaving Count as zero,
' or retrieve the count of already enumerated records with this group key.
Count = GroupKeys(GroupKey) + 1
If Count > 0 Then
' The group key has been recorded.
' Remove it to allow it to be recreated holding the new count.
GroupKeys.Remove (GroupKey)
Else
' This record is the first having this group key.
' Thus, the count is 1.
Count = 1
End If
' (Re)create the group key item with the value of the count of keys.
GroupKeys.Add Count, GroupKey
End If
' Add the key and its enumeration.
' This will be:
' Using no group key: Relative to the full recordset.
' Using a group key: Relative to the group key.
' Will fail if the key already has been created.
Keys.Add Count, CompoundKey
End If
' Return the key value as this is the row counter.
RowNumber = Count
Exit_RowNumber:
Exit Function
Err_RowNumber:
Select Case Err
Case CannotAddKey
' Key is present, thus cannot be added again.
Resume Next
Case CannotRemoveKey
' GroupKey is not present, thus cannot be removed.
Resume Next
Case Else
' Some other error. Ignore.
Resume Exit_RowNumber
End Select
End Function
I have generated unique pseudorandom numbers for each row which are subject to a particular field (Field1) in a query in Access. They have been successfully generated and I would like to fix them (kind of like copy and pasting as values). I guess my question would be, is this the best way to do this or will they always change as they are being recalculated on the query? I am open to any other suggestions, but once they have been calculated for the first time, I want them to stay as they are and not change again. Thanks!
Here is the current query's SQL:
SELECT [qry_1].*, Rnd([Field1]) AS Random
FROM qry_1;
You don't need a table. You can use a collection:
' Builds random row numbers in a select, append, or create query
' with the option of a initial automatic reset.
'
' Usage (typical select query with random ordering):
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' WHERE (RandomRowNumber(CStr([ID])) <> RandomRowNumber("",True))
' ORDER BY RandomRowNumber(CStr([ID]));
'
' The Where statement shuffles the sequence when the query is run.
'
' Usage (typical select query for a form with random ordering):
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' ORDER BY RandomRowNumber(CStr([ID]));
'
' The RandomRowID values will resist reordering and refiltering of the form.
' The sequence can be shuffled at will from, for example, a button click:
'
' Private Sub ResetRandomButton_Click()
' RandomRowNumber vbNullString, True
' Me.Requery
' End Sub
'
' and erased each time the form is closed:
'
' Private Sub Form_Close()
' RandomRowNumber vbNullString, True
' End Sub
'
' Usage (typical append query, manual reset):
' 1. Reset random counter manually:
' Call RandomRowNumber(vbNullString, True)
' 2. Run query:
' INSERT INTO TempTable ( [RandomRowID] )
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO TempTable ( [RandomRowID] )
' SELECT RandomRowNumber(CStr([ID])) AS RandomRowID, *
' FROM SomeTable
' WHERE (RandomRowNumber("",True)=0);
'
' 2018-09-11. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RandomRowNumber( _
ByVal Key As String, _
Optional Reset As Boolean) _
As Single
' Error codes.
' This key is already associated with an element of this collection.
Const KeyIsInUse As Long = 457
Static Keys As New Collection
On Error GoTo Err_RandomRowNumber
If Reset = True Then
Set Keys = Nothing
Else
Keys.Add Rnd(-Timer * Keys.Count), Key
End If
RandomRowNumber = Keys(Key)
Exit_RandomRowNumber:
Exit Function
Err_RandomRowNumber:
Select Case Err
Case KeyIsInUse
' Key is present.
Resume Next
Case Else
' Some other error.
Resume Exit_RandomRowNumber
End Select
End Function
It is explained in detail in my article Random Rows in Microsoft Access
(If you have no account, browse to the link: Read the full article).
Full code including a demo is on GitHub: VBA.RowNumbers
I have query in MS ACCESS 2016 that I need to add autonumber to. Basically, the query output results in one column of data and I want to add a new column to this output with numbers starting from 1 to whatever the row count of the query output will be. I dont want to create a new table from my query output though. Is there a way to do this in a query? I managed to add a new ID column that just has a scalar value, however what I need is auto increment here. Any thoughts?
SELECT qry.ColA, 1 AS ID
FROM qry;
Yes, use the RowNumber function from my article:
Sequential Rows in Microsoft Access
Full code at GitHub: VBA.RowNumbers
' Builds consecutive row numbers in a select, append, or create query
' with the option of a initial automatic reset.
' Optionally, a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query):
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' Usage (with group key):
' SELECT RowNumber(CStr([ID]), CStr[GroupID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowNumber(vbNullString, True)
' 2. Run query:
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber("","",True)=0);
'
' 2018-08-23. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RowNumber( _
ByVal Key As String, _
Optional ByVal GroupKey As String, _
Optional ByVal Reset As Boolean) _
As Long
' Uncommon character string to assemble GroupKey and Key as a compound key.
Const KeySeparator As String = "¤§¤"
' Expected error codes to accept.
Const CannotAddKey As Long = 457
Const CannotRemoveKey As Long = 5
Static Keys As New Collection
Static GroupKeys As New Collection
Dim Count As Long
Dim CompoundKey As String
On Error GoTo Err_RowNumber
If Reset = True Then
' Erase the collection of keys and group key counts.
Set Keys = Nothing
Set GroupKeys = Nothing
Else
' Create a compound key to uniquely identify GroupKey and its Key.
' Note: If GroupKey is not used, only one element will be added.
CompoundKey = GroupKey & KeySeparator & Key
Count = Keys(CompoundKey)
If Count = 0 Then
' This record has not been enumerated.
'
' Will either fail if the group key is new, leaving Count as zero,
' or retrieve the count of already enumerated records with this group key.
Count = GroupKeys(GroupKey) + 1
If Count > 0 Then
' The group key has been recorded.
' Remove it to allow it to be recreated holding the new count.
GroupKeys.Remove (GroupKey)
Else
' This record is the first having this group key.
' Thus, the count is 1.
Count = 1
End If
' (Re)create the group key item with the value of the count of keys.
GroupKeys.Add Count, GroupKey
End If
' Add the key and its enumeration.
' This will be:
' Using no group key: Relative to the full recordset.
' Using a group key: Relative to the group key.
' Will fail if the key already has been created.
Keys.Add Count, CompoundKey
End If
' Return the key value as this is the row counter.
RowNumber = Count
Exit_RowNumber:
Exit Function
Err_RowNumber:
Select Case Err
Case CannotAddKey
' Key is present, thus cannot be added again.
Resume Next
Case CannotRemoveKey
' GroupKey is not present, thus cannot be removed.
Resume Next
Case Else
' Some other error. Ignore.
Resume Exit_RowNumber
End Select
End Function
I want to append an alphabet incrementally like for variable say
I pass JohnBox then it should be JohnBox_a then the next time it would be:
JohnBox_b
.
.
JohnBox_z
JohnBox_aa
.
.
JohnBox_zz
Can someone please help regarding solving this issue? This is what I have tried so far but Case 2 is where I am having problems:
Public Function fCalcNextID(strID As String) As Variant
Dim strName As String
'Extract Numeric Component
strName = Left(strID, InStr(strID, "_"))
If Len(Nz(strName, "")) = 0 Then
strName = strID
Else
strName = strName
End If
Select Case Len(Right(strID, (Len(strID) - (InStr(strID, "_")))))
Case 1 'single alpha (a)
If Right$(strID, 1) = "z" Then
fCalcNextID = strName & "aa"
Else
fCalcNextID = strName & Chr$(Asc(Right$(strID, 1)) + 1)
End If
Case 2 'double alpha (bd)
If Right$(strID, 1) = "z" Then
If Mid$(strID, 4, 1) = "z" Then
fCalcNextID = CStr(strName + 1) & "a"
Else
fCalcNextID = CStr(strName) & Chr$(Asc(Mid$(strID, 4)) + 1) & "a"
End If
Else '101bd, 102tx, etc.
'Increment last character, 101bd ==> 101be
fCalcNextID = Left$(strName, 4) & Chr$(Asc(Right$(strID, 1)) + 1)
End If
Case Else
fCalcNextID = strName & "_a"
End Select
End Function
The solution to your problem can be found in this LINK already. Credits to UtterAccess Wiki
The link presents 2 functions: Base10ToBaseLetter and BaseLetterToBase10. The functions are shown below just in case the link changes or become unavailable.
Public Function Base10ToBaseLetter(ByVal lngNumber As Long) As String
' Code courtesy of UtterAccess Wiki
' http://www.utteraccess.com/wiki/index.php/Category:FunctionLibrary
' Licensed under Creative Commons License
' http://creativecommons.org/licenses/by-sa/3.0/
'
' You are free to use this code in any application,
' provided this notice is left unchanged.
' ================================================================================
' Concept:
' Base10: Decimal 123 => (1 * 10 ^ 2) + (2 * 10 ^ 1) + (3 * 10 ^ 0)
' Base26: Decimal 123 => ( 4 * 26 ^ 1) + (19 * 26 ^ 0)
' Representing 4 and 19 with letters: "DS"
' MSD = Most Significant Digit
' LSD = Least Significant Digit
' ================================================================================
' Returns ZLS for input values less than 1
' Error handling not critical. Input limited to Long so should not normally fail.
' ================================================================================
Dim intBase26() As Integer 'Array of Base26 digits LSD (Index = 0) to MSD
Dim intMSD As Integer 'Most Significant Digit Index
Dim n As Integer 'Counter
If lngNumber > 0 Then
' Calculate MSD position (Integer part of Log to Base26 of lngNumber)
' Log of X to Base Y = Log(X) / Log(Y) for any Base used in calculation.
' (VBA Log function uses the Natural Number as the Base)
intMSD = Int(Log(lngNumber) / Log(26))
ReDim intBase26(0 To intMSD)
For n = intMSD To 0 Step -1
' Calculate value of nth digit in Base26
intBase26(n) = Int(lngNumber / 26 ^ n)
' Reduce lngNumber by value of nth digit
lngNumber = lngNumber - ((26 ^ n) * intBase26(n))
Next
' Base Letter doesn't have a zero equivalent.
' Rescale 0 to 26 (digital representation of "Z")
' and "borrow" by decrementing next higher MSD.
' Digit can be -1 from previous borrow onto an already zero digit
' Rescale to 25 (digital representation of "Y")
' Looping from LSD toward MSD
' MSD not processed because it cannot be zero and
' avoids potential out of range intBase26(n + 1)
For n = 0 To intMSD - 1
If intBase26(n) < 1 Then
intBase26(n) = 26 + intBase26(n) ' Rescale value
intBase26(n + 1) = intBase26(n + 1) - 1 ' Decrement next higher MSD
End If
Next
' Ignore MSD if reduced to zero by "borrow"
If intBase26(intMSD) = 0 Then intMSD = intMSD - 1
' Convert Base26 array to string
For n = intMSD To 0 Step -1
Base10ToBaseLetter = Base10ToBaseLetter & Chr((intBase26(n) + 64))
Next
End If
End Function
Public Function BaseLetterToBase10(ByVal strInput As String) As Long
' Upper or lower case characters accepted as input
' ZLS returns 0
' Negative return value indicates error:
' Unaceptable character or Overflow (string value exceeds "FXSHRXW")
' Digit indicates character position where error encountered
' MSD = Most Significant Digit
Dim intMSD As Integer 'MSD Position
Dim intChar As Integer 'Character Position in String
Dim intValue As Integer 'Value from single character
Dim n As Integer 'Counter
On Error GoTo ErrorHandler
' Convert String to UpperCase
strInput = UCase(strInput)
' Calculate Base26 magnitude of MSD
intMSD = Len(strInput) - 1
For n = intMSD To 0 Step -1
intChar = intMSD - n + 1
intValue = Asc(Mid(strInput, intChar, 1)) - 64
' Test for character A to Z
If intValue < 0 Or intValue > 26 Then
BaseLetterToBase10 = -intChar
Exit For
Else
' Add Base26 value to output
BaseLetterToBase10 = BaseLetterToBase10 + intValue * 26 ^ n
End If
Next
Exit Function
ErrorHandler:
BaseLetterToBase10 = -intChar: Exit Function
End Function
Now to apply it to your needs, you simple call those functions:
Public Function fCalcNextID(strID As String) As String
Dim CurIdx As String, n As Integer, x As Long
On Error Resume Next
CurIdx = UCase(Split(strID, "_")(1))
On Error GoTo 0
If CurIdx <> "" Then
x = BaseLetterToBase10(CurIdx) + 1
fCalcNextID = Split(strID, "_")(0) & "_" & LCase(Base10ToBaseLetter(x))
Else
fCalcNextID = strID & "_a"
End If
End Function
This is not me. It is them. What I did is just ask Google to find it for me.
Nonetheless hope this helps and is actually what you need.
Important: Don't remove the comments. That is the only request of the author.
What you have is essentially a base26 count. You can implement that with a modulus function instead of your current code. You will have to create the VBA code yourself, just getting you the algoritm:
For example:
Create an array with a-z
Input a value:
cde
Convert to numeric: 3*26*26+4*26+5
Add 1: 3*26*26+4*26+5+1
input=3*26*26+4*26+6
LOOP until input equals 0:
Mod(input,26) returns remnant (first loop:6, 2nd loop: 4, 3rd loop: 3) => look up in array => f (first loop) (2nd loop d, third loop c).
returnval=lookup value+returnval;
input=Divide (input - mod output (input))/26
END LOOP