Solved Syntax question

Pat Hartman

Super Moderator
Staff member
Local time
Today, 09:28
Joined
Feb 19, 2002
Messages
45,438
I have a bunch of arrays I want to populate from queries. Rather than writing a lot of code, I'd like to just call them Array1, Array2, Array3. What is the syntax I need to reference the instance? I'm using the code to generate a license key and rather than using a fixed array for each digit, I want to be able to have several substitutes to ensure that all characters change, year over year so the client can't figure out what digit in the license controls what option.

eval("Array" & rs!ArraySeq & "(" & rs!SeqNum) & ")") = rs!FldVal

so it ends up like:

Array8(22) = "N"

That's what I'm going to start with but I don't have much faith in it working so this is a preemptive question. In the last version, I just hard coded the arrays but I have three times as many now and it's a PITA to make sure that there are no duplicate values using the hardcoded method. With a table, I can define an index to ensure that "N" only occurs once for Array8
 
Pat, does this give you at least a place to start?


 
Pat, this seems to be a follow up to your posts from a few weeks ago regarding some protection of your software against unpaid use. Are you dead-set on doing it this way, or open to other suggestions?
If the latter, we should take this offline since it involves sensitive matters. I could talk this weekend. tom 7744 at cox dot net
 
Arrays can be nested, collections too.
Code:
Sub test_array()
    Dim arrAll(9) As Variant
    Dim arr11(60) As String
    Dim arr12(60) As String
    Dim i As Long
    
    arr11(0) = "1"
    arr11(1) = "2"
    arr12(0) = "a"
    arr12(1) = "b"
    arrAll(0) = arr11
    arrAll(1) = arr12
    
    Debug.Print arrAll(1)(0)
    
End Sub

The generation of license keys can be equated with the generation of passwords. There should be some suggestions.
 
to ensure that all characters change
SQL:
SELECT
   A.Char & B.Char & C.Char & D.Char & E.Char
FROM
   Tab AS A,
   Tab AS B,
   Tab AS C,
   Tab AS D,
   Tab AS E
ORDER BY
   Rnd(Asc(A.Char))
This way you could generate random strings.
These can then be compared using a query against already assigned (saved) character strings.
 
Last edited:
Thanks but I didn't ask for an SQL Solution. I was looking for a specific VBA syntax answer, I thought that would be clear based on the code sample and where I posted the question. I also know how to load an array from a table. This is one table with multiple arrays so the GetRows won't help. I should get to the point of being able to try this later today so I may have my own answer. I know there is a way to concatenate variables to come up with an actual variable name that gets used and I think the technique involves using eval. THAT is what I am looking for. This is not your normal VBA.
eval("Array" & rs!ArraySeq & "(" & rs!SeqNum) & ")") = rs!FldVal
So --- rs!ArraySeq finishes the Array name
rs!SeqNum is the index value
rs!FldVal is the value being placed into the array.

Will this syntax work? If it doesn't, then I end up with a case statement and 16 statements that look like this:

Array1(rs!SeqNum) = rs!fldVal

Not a big deal.

I have 16 arrays with 3 variations each and ONE table with ALL the data. I know how to get the data. I know how to put it all into ONE array. I know how to hard code it to put it in 16 arrays and 16 is not so many that I won't just write a case statement so I can fix the name of the array. The other two pieces of data, the index and the value are normal table field references. The query will pull one variation for all the arrays and that is the data that gets loaded. Next time, I'll pick a different variation. I'm looking for code to take ONE table and using the values in the record put the row in a specific array by making the variable names vary based on data from the table. The table contains a number to use as the array suffix and a sequence number which can be used as the index to load the specific value. I have already changed the definition so that the arrays are 1 base instead of 0 base so the index = the value from the sequence number in the table.

@tvanstiphout , if you have an alternative, I'm always ready to listen but I need to get this done this week. I don't have a website so I can't use the "phone home" method and I've looked at a number of paid services but none is quite what I want and I don't want to change the app. The solution has been working fine for years. I am just trying to make it a little harder to identify what each character in the Token controls by ensuring that every character changes each time a new token is issued. This is more of a problem this renewal cycle because I am issuing more Tokens to control the seats also. They get one for the product and one for each seat.
 
Last edited:
The question is: why do they have to be arrays with independent variable names?
Nested arrays (as shown by Eberhard) or nested collections (tip: dictionaries in collection) would allow Arrays(8)(22) = "N".
 
Last edited:
Or even just use one array, but with two dimensions.
Code:
Dim myArray(8, 22)    ' set your bounds appropriately

myArray(rs!ArraySeq, rs!SeqNum) = rs!fldVal
 
Will this syntax work?
No. You can't use variable names through composition. If the variable contains a collection, you can calculate the index or the name of the collection element using other variables.

Actually, one would also ask what major role arrays should play here. Typically, arrays are easily replaceable in database environments and are rarely the first choice.
 
The generation of license keys can be equated with the generation of passwords. There should be some suggestions.
This is a syntax question. It has nothing to do with the composition of the license key.
 
Eval() won't return an object, only a result (AFAIK!).

You can't s compose the actual array object in the same way as you can a key of a collection, eg Me.Controls("txt" & i)

You could create a wrapper function like:
Code:
Function SetArrayVal(iArray As Integer, idx As Integer, value As Integer) as Boolean

  Select Case iArray
  Case 1
      Array1(idx) = value
  Case 2
    ' ... etc
and use:
Code:
Eval("SetArrayVal(" & rs!ArraySeq & ", " & rs!SeqNum & ", " rs!fldVal)")

' or just call the function durectly without Eval()

Call SetArrayVal(rs!ArraySeq, rs!SeqNum, rs!fldVal)

But all of the other suggestions are simpler.

The easiest solution is just to use tables as your array, and perhaps SQL directly to load and retrieve the values as Eberhard originally suggested.
 
How am I trying to return an object with the posted code?

As I said. A case statement solves the problem. No wrapper is necessary. A "wrapper" simply obfuscates the code and moves it to a different procedure. The in line case is clear and simple.
 
Your Eval() expression is trying to assign a value to an array element (object) rather than retrieve a scalar value
 
If the code won't work that way, then I'll just use the case statement.

Thanks.
 
If you put those in functions, you could:
Java:
Function fn1()
    Debug.Print 1
End Function

Function fn2()
    Debug.Print 2
End Function

Function fn3()
    Debug.Print 3
End Function

Sub test()
    Dim i As Long: For i = 1 To 3
        Eval "fn" & i & "()"
    Next
End Sub

result:
Code:
 1
 2
 3
 
Last edited:
this is a simple Generator i used in License.accdb, you can extend it as to how many characters you want.
Code:
' arnelgp
' generate Validation code in format XXXX-XXXX
'
Public Function GenCode() As String
Dim AN As Variant, s As String, i As Integer
AN = Array("1", "B", "2", "D", "E", _
        "F", "G", "3", "I", "J", "K", "4", "M", "N", _
        "5", "P", "Q", "6", "S", "T", "9", "V", "W", _
        "X", "Y", "Z", "0", "A", "C", "H", "L", "O", _
        "R", "7", "8", "U")
For i = 1 To 4
    s = s & AN(RandBetween(1, 36) - 1)
Next
s = s & "-"
For i = 1 To 4
    s = s & AN(RandBetween(1, 36) - 1)
Next
GenCode = s
End Function

' arnelgp
' random number generator
Public Function RandBetween(Optional Lowest As Long = 1, Optional Highest As Long = 9999)
' Generates a random whole number within a given range
   Randomize (Timer)
   RandBetween = Int(Rnd * (Highest + 1 - Lowest)) + Lowest
End Function
 
Eval can only process functions or constant expressions. It has no direct access to VBA variables.
Writing 16 functions to change the array values is useless, you can just use a select case.

The starting point would have to be changed (replace the individual arrays), then the problem would not occur at all.
 
I have 16 arrays with 3 variations each ...
What irritates me a little: an array can have up to around 60 dimensions. Which arrays with how many dimensions are spoken of here without question in the believed unison?
16 one-dimensional arrays can be packed into a two-dimensional array.

I'll put it this way: one or two more dimensions make the array much more powerful in terms of content. The indexes of additional dimensions can easily be found in a table field.
The head is round so that thinking can change direction.
But I'm probably not meeting Pat's wishes here either.
 
Last edited:

Users who are viewing this thread

Back
Top Bottom