Android Question Advanced Search - help needed

tsteward

Well-Known Member
Licensed User
Longtime User
I have a local database that I want to search. At the moment I have one column named series. I can change this to two columns if need be. EG Min & Max but I don't think its that straight forward. Some have no letters and others have letter only or a mix of both.
Below is a sample.

When I enter say H2312 I want to return all records where that might be possible.
And another for line 16 below 0L213

Any suggestions on how this might be done or the best way to do it?

Series
H0001-H3000
X8001-X9000
S0001-S2000
X0001-X8000
G0001-G2377
P0001-P2390
X0001-X2248
W0001-W2409
10001-15000
J0001-J1200
0001X-1706X
T0001-T1000
1-22185
3001-4481
E5001-E7700
0K001-0N718
8001-9554
V2001-V3200
70000-75928
J00-U39
E0001-E2500
G0001-G2500
HK0001-HK2500
J0001-J2500
K0001-K2500
KE0001-KE2500
L0001-L1037
P0001-P2500
T0001-T2500
V0001-V2500
LK0001-LK2500
40000-49999
O0001-O5000
D0001-D3000
M0001-M2618
VN0-VN1999
50000-69999
S4001-S5200
S5298-S6300
G8001-G9000
B8001-B9000
B8001-B9000
K0001-K1000
10100-12283
20100-23284
K0001-K1000
N225-N814
U1-U2000
FA0-FA1863
T1-3456
T1-26789
T5-3456
T1-T1200
Y2001-Y3000
7001-9000
E2001-E3000
E4001-E5000
E5000-E5999
E6001-E7000
E8000-E8999
L8001-L10000
NSP4000-NSP4999
NSP7001-NSP9000
G000-G3631
S000A-S999K
30010-32009
C8001-C9000
Y7001-Y8200
30001-37850
40001-41518
6001-7001
A6001-A7000
D0001-D2000
D4001-D5200
1HM1-99HM99
1NF1-99NF99
HM1-HM1200
HM2501-HM3500
HM4001-HM7350
HM6001-HM7110
NF1-NF1200
NM2501-NM3500
5001-8442
M0001-M1200
3001-4000
6001-7000
AB6001-AB6891
N6001-N7000
V1-V3056
V5001-V8058
W1-W9640
1V00001-5V12295
L000-L999
B1001-B2200 New
B1001-B2200 Old
B5001-B6200
B5001-B6200
HB1-HB2988
HB3001-HB5000
T1-T2330
HV1-HV854
HV1001-HV1918
HV2001-HV2830
 

William Lancee

Well-Known Member
Licensed User
Longtime User
P.S. I hope bitting tables are only available to certified Locksmiths.
P.S.S. The more general problem of looking up a number in a LONG list of overlapping ranges is interesting enough for me to experiment some more.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
@tsteward
You have to clean up the file a bit. Remove labels, "mixed", change any 5 digits to 00000-ffffff
Also for
T1-26789
T1-3456
T5-3456

The T needs to be repeated.
There might be others.

I notice that 1, 01, 001, 0001, and 00001 are not considered the same.
It may be better to divide the search into separate searches, based on lookup string length, it would also speed things up a bit.
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
Thank you William,
Yes I will need to look cleaning up the code series list - this was just a dump from a larger database.

There are a few false positives with this solution (still better than what I can do)
=========
H2312
(ArrayList) [H0001-H3988, H0001-H3000, H0001-H2500, H0001-H2500*]
=========
X1234
(ArrayList) [X1001-X3500, X0001-X8000, X0001-X2248, X0001-X2245]
=========
X7899
(ArrayList) [X0001-X8000]
=========
25AE579
(ArrayList) [25001-26200, 20001-32000, 1V00001-5V12295, 1NF1-99NF99, 1HM1-99HM99, 101A501-304E579, 1-8100, 1-6000, 1-3679, 1-3001, 0AAAA-9XXXX, 001-700, 0001-4000, 0001-3000, 0000-6999, 0-5928]
=========
60123
(ArrayList) [6001-8110, 6001-7001, 6001-7000, 60001-60400, 60000-62113, 5001-8442, 50000-69999, 4001-9001, 3501-6700, 1NF1-99NF99, 1HM1-99HM99, 1-8100, 0AAAA-9XXXX, 001-700, 0000-6999]
=========
7C22
(ArrayList) [701-900, 7001-9000, 6001-8110, 5001-8442, 4001-9001, 1NF1-99NF99, 1HM1-99HM99, 1-8100, 0AAAA-9XXXX]
 
Upvote 0

emexes

Expert
Licensed User
"J00-U39 includes J40-T99" Yes it does
"1V00001-5V12295 includes 1V12296 to 5V00000" Yes

I have had a couple of goes at this, and what I keep stubbing my toe on is that when eg the first character of the code (that is different to its corresponding characters of the upper and lower bounds) is in-between the corresponding characters of the upper and lower bounds, then nothing after that matters ie false positives galore.

Worked example:

Range is 1V00001-5V12295

Lower bound is 1V00001
Upper bound is 5V12296

will happily match with 2M99999 or 3FARKME or 4WHTEVR which I feel would be hard cases to argue that they match, eg, the second characters are not V.

There aren't many ranges (code series) like this in the supplied sample, but I am wondering how many more are in the how-much-bigger full list.

I am tending back towards comparing subfield-by-subfield, eg 1V00001-5V12295 means:

first subfield (character 1) of code must be between 1 and 5
second subfield (character 2) of code must be between V and V ie it must be V
third subfield (characters 3 to 7) of code must be between 00001 and 12296

and if you want that range to match codes like 2V44444 then you'd have to specify it as 3 ranges:

1V00001-1V99999 and 2V00000-4V99999 and 5V00000-5V12295

Thoughts? šŸ»
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
There aren't many ranges (code series) like this in the supplied sample, but I am wondering how many more are in the how-much-bigger full list.
I can't help with the search problem but you have the full list in the attached txt file. There are no more surprises.
I thank you for your persistance
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
Is this lookup project because sometimes people give you keycodes but don't know what lock brand/model it is for?
Yes and also sometimes some off the wall brand will use someone elses codes or locks.
So when investigating you need all your options so to speak.
Sometimes staff book in a job and don't get any details LoL
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
G0001-G2377 and G0001-G2500" Two different code series so searching for G0122 should return both
What about this one: G000-G3631
It should also be returned along with the other two. I am trying to take a stab at this using a SQLite with search. I am just trying to get a feel of this complex search algorithm.
Can you also mention a few that you consider false positive in your estimate, so it gives me a better picture.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I marvel at the patterns that we can recognize.
1HM1-99HM99 "obviously" is an infix of HM and a prefix of 1 to 99 and a suffix of 1 to 99
So the only way to recognize this series is to look for an infix and how do you do that in general?
What is it and where should it be?

In the complete list provided (from #17), the human (me) can see that there a variety of patterns like that.
Since it is a limited list, we have enumerate them and look for these patterns in the lookup value.

In the example by @emexes (1V00001-5V12295) the infix is V and lives in the second position of a 7 character code.
If the OP receives the 4WHTEVR code (by a noisy channel) the lookup should warn him that no such code exists so he can double
check with the source.

@Sandman in post #2 had the right idea, looking for prefix, infix, suffix values.

Letters could be used to do this, but there several case where the letters are really extensions of numbers, so these would be special cases.
 
Last edited:
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Here's an idea. I transformed the range specification into the attached file.
There are 4 groupings in each limit of the range, alternating between numeric and alphabetic caps.
a group could be empty. To transform the file back, just remove . and blanks.

When I squinted at the data (it wasn't my first thought), I saw regular expressions.

If someone (@emexes?) could create a regular expression from each range, the lookup could cycle through
the set of 243 regular expressions and add matches to the result list.
 

Attachments

  • CodeRanges.txt
    4.7 KB · Views: 90
Upvote 0

emexes

Expert
Licensed User
When I squinted at the data (it wasn't my first thought), I saw regular expressions.

If someone (@emexes?) could create a regular expression from each range

Regular expressions are a pain for doing multi-digit numeric comparisons, even when both limits are the same length, eg 123-456 no problem with the first digit 1-4, but the other digits can be 0-9.

Admittedly they'd be great for doing a quick first check that a match is plausible, but I'm not sure that the requiring users adding new code series to be able to speak regex is a good long-term plan.

It might be simpler to add a flag to the relatively-few ranges that use non-standard comparisons, eg:

AA00-7T51~1 where the ~1 means use alternate comparison type 1 (2 x base-36 digits A-Z0-9 + 2 x base-10 digits 0-9)
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
The attached project uses yet another approach. The series file was processes to create four sets of specs - one for each
alternating numeric/alpha grouping.

Each spec has 4 parameters min/max # of characters and min/max value.
The project reads that file and checks each code range item for validity.

And yet, as @emexes pointed out the max value should not be checked in third group.
Therefore invalid numeric values after a alpha group could pass as valid. This might not be a problem in this use-case.

I found this an very interesting puzzle, thanks to the OP for posting and for @emexes, @Sandman, and @Mahares for participating.

I will move on now to something else. The spec file is in assets below.
 

Attachments

  • xseriesV2.zip
    12.2 KB · Views: 87
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
WOW you guys are talking stuff so above me.
I thank you all for your time & teaching.šŸ™
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
What about this one: G000-G3631
It should also be returned along with the other two. I am trying to take a stab at this using a SQLite with search. I am just trying to get a feel of this complex search algorithm.
Can you also mention a few that you consider false positive in your estimate, so it gives me a better picture.
I've tried many bits of code so not sure where your coming from to show you false positives. Obviously different depending on coding used. Wil came up with a few options all having different issues.
While adding this feature to my app would be nice I feel time vs reward just might not be worth it. Unless someone just wants a challenge :)
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
While difficult, it might be worth it. Test my last submission. Try different lookups.
I think the whole thing was a great idea.
 
Upvote 0

tsteward

Well-Known Member
Licensed User
Longtime User
While difficult, it might be worth it. Test my last submission. Try different lookups.
I think the whole thing was a great idea.
This is the result (I really don't want to sound ungrateful)
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
H2345 H0001-H2500
H2345 H0001-H2500 revised
H2345 H0001-H3000
H2345 H0001-H3988
H2345 H5001-H7000 ******Wrong
2V12345 1V00001-5V12295
01f3b 00000-fffff
60123 00000-fffff
60123 50000-69999
60123 60000-62113
60123 60001-60400
X7999 X0001-X1000 ******Wrong
X7999 X0001-X2245 ******Wrong
X7999 X0001-X2248 ******Wrong

X7999 X0001-X8000
X7999 X1001-X3500 ******Wrong
X7999 X8001-X9000 ******Wrong

7h12 NO MATCH
B2122 B0001-B2608
B2122 B0001-B3000
B2122 B1001-B2200
B2122 B1001-B2200 revised
B2122 B5001-B6200 ******Wrong
B2122 B5001-B6200 revised ******Wrong
B2122 B8001-B9000 ******Wrong

B2122 B8001-B9000 revised
*** mainpage: B4XPage_Appear
** Activity (main) Resume **
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
At some point you might want to consider updating your database design so this can be solved with just a basic database query.
 
Upvote 0

emexes

Expert
Licensed User
This is the result (I really don't want to sound ungrateful)

Righto, third time's the charm, and giving it a break over the weekend didn't hurt either:

Log Output:
Waiting for debugger to connect...
Program started.
Code "H2345" is in ranges {"H0001-H2500", "H0001-H2500", "H0001-H3000", "H0001-H3988"}
Code "2V12345" is in ranges {"1V00001-5V12295"}
Code "01f3b" is in ranges {"00000-FFFFF"}
Code "60123" is in ranges {"00000-FFFFF", "50000-69999", "60000-62113", "60001-60400"}
Code "X7999" is in ranges {"X0001-X8000"}
Code "7h12" is in ranges {"AA00-7T51"}
Code "B2122" is in ranges {"00000-FFFFF", "B0001-B2608", "B0001-B3000", "B1001-B2200 New", "B1001-B2200 Old"}
Code "B3210" is in ranges {"00000-FFFFF"}
Code "F2122" is in ranges {"00000-FFFFF", "F0001-F2500", "F0001-F2500"}
Code "F9999" is in ranges {"00000-FFFFF"}
Code "FADED" is in ranges {"00000-FFFFF"}
Code "DECAF" is in ranges {"00000-FFFFF"}
Code "17HM12" is in ranges {"1HM1-99HM99"}
Code "14HM987" is in ranges {}
Code "12HM7" is in ranges {"1HM1-99HM99"}
Code "12HM777" is in ranges {}
Code "4FOUR" is in ranges {"0AAAA-9XXXX"}
Code "4ZZZZ" is in ranges {"0AAAA-9XXXX"}
Code "9ZZZZ" is in ranges {}
Code "A103" is in ranges {"A101-A800", "AA00-7T51"}
Code "NS2600" is in ranges {"NS2001-NS3500"}
Code "5443" is in ranges {"0-5928", "0000-6999", "1-17850", "1-22185", "1-6000", "1-8100", "3501-6700", "4001-9001", "5001-8442", "AA00-7T51"}
Code "P2022" is in ranges {"P0001-P2390", "P0001-P2500", "P0001-P2500"}
Code "7R85" is in ranges {"AA00-7T51"}
Code "7T85" is in ranges {}
25 matchings took a total of 410 milliseconds (including log output)
Program terminated (StartMessageLoop was not called).

B4X:
'Non-UI application (console / server application)
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
   
End Sub


Sub AppStart (Args() As String)
   
    Dim TestCodes() As String = Array As String( _
        "H2345", "2V12345", "01f3b", "60123", "X7999", "7h12", "B2122", _
        "B3210", "F2122", "F9999", "FADED", "DECAF", _
        "17HM12", "14HM987", "12HM7", "12HM777", _
        "4FOUR", "4ZZZZ", "9ZZZZ", _
        "A103", "NS2600", "5443", "P2022", _
        "7R85", "7T85" _
    )
       
    Dim StartTime As Long = DateTime.Now
   
    For Each TestCode In TestCodes
        Log("Code """ & TestCode & """ is in ranges " & StringListToNiceString(CodeIsInRanges(TestCode)))
    Next

    Dim EndTime As Long = DateTime.Now
   
    Log(TestCodes.Length & " matchings took a total of " & (EndTime - StartTime) & " milliseconds (including log output)")
   
End Sub


Sub PadLeft(S As String, L As Int, PadChar As String) As String

    Dim SB As StringBuilder
    SB.Initialize
   
    For I = S.Length + 1 To L
        SB.Append(PadChar)
    Next
   
    Return SB.Append(S).ToString
   
End Sub


Sub StringListToArray(L As List) As String()
   
    Dim A(L.Size) As String
   
    For I = 0 To L.Size - 1
        A(I) = L.Get(I)
    Next
   
    Return A
   
End Sub


Sub StringArrayToNiceString(A() As String) As String
   
    Return StringArrayToNiceString2(A, "[", """",", ", "]")
   
End Sub


Sub StringArrayToNiceString2(A() As String, BeforeChar As String, QuoteChar As String, CommaChar As String, AfterChar As String) As String
   
    Dim SB As StringBuilder
    SB.Initialize
   
    SB.Append(BeforeChar)
    For I = 0 To A.Length - 1
        If I > 0 Then
            SB.Append(CommaChar)
        End If
       
        SB.Append(QuoteChar)
        SB.Append(A(I))
        SB.Append(QuoteChar)
    Next
    SB.Append(AfterChar)

    Return SB.ToString
   
End Sub


Sub StringListToNiceString(L As List) As String
   
    Return StringListToNiceString2(L, "{", """", ", ", "}")
   
End Sub


Sub StringListToNiceString2(L As List, BeforeChar As String, QuoteChar As String, CommaChar As String, AfterChar As String) As String
   
    Dim SB As StringBuilder
    SB.Initialize
   
    SB.Append(BeforeChar)
    For I = 0 To L.Size - 1
        If I > 0 Then
            SB.Append(CommaChar)
        End If

        SB.Append(QuoteChar)
        SB.Append(L.Get(I))
        SB.Append(QuoteChar)
    Next
    SB.Append(AfterChar)

    Return SB.ToString
   
End Sub


Sub CodeToFields(Code As String) As String()

    Dim FieldList As List
    FieldList.Initialize
   
    Dim M As Matcher = Regex.Matcher("([A-Z]*)([0-9]*)", Code.ToUpperCase)
   
    Do While M.Find
        If M.Group(0).Length > 0 Then
            FieldList.Add(M.Group(1))
            FieldList.Add(M.Group(2))
        End If
    Loop

    '''Log(Code & " ==> " & StringListToNiceString(FieldList))
   
    Return StringListToArray(FieldList)
   
End Sub


Sub CodeIsInRanges(Code As String) As List
   
    Dim CodeSeriesList As List = GetCodeSeriesList
   
    Dim L As List
    L.Initialize
   
    For Each Range As String In CodeSeriesList
        If CodeIsInRange(Code, Range) Then
            L.Add(Range)
        End If
    Next
   
    Return L
           
End Sub


Sub CodeIsInRange(Code As String, Range As String) As Boolean
   
    If Code.Length = 0 Then
        Return False    'not really an error, could reasonably also return True
    Else If Range.Length = 0 Then
        Log("error 131 on range """ & Range & """")
        Return False
    End If
   
    Dim RangeWithoutClarifier As String = Regex.Split("\ ", Range)(0)
   
    If RangeWithoutClarifier.Length < 3 Then    'should be at least three characters eg a-b
        Log("error 171 on range """ & Range & """")
        Return False
    End If
   
    Dim LowerUpper() As String = Regex.Split("\-", RangeWithoutClarifier)

    If LowerUpper.Length <> 2 Then
        Log("error 49")
        Return False
    End If
   
    If LowerUpper(0).Length = 0 Then
        Log("error 134 on range """ & Range & """")
        Return False
    else if LowerUpper(1).Length = 0 Then
        Log("error 136 on range """ & Range & """")
        Return False
    else if LowerUpper(0).Length > LowerUpper(1).Length Then
        Log("error 138 on range """ & Range & """")
        Return False
    End If
   
    If Code.Length < LowerUpper(0).Length Then    'code should be at least as long as the lower bound
        Return False
    else if Code.Length > LowerUpper(1).Length Then    'and no longer than the upper bound
        Return False
    End If

    If Range.ToUpperCase.CompareTo("AA00-7T51") = 0 Then
        Return CodeIsInRangeXXN(Code, LowerUpper(0), LowerUpper(1))
    else if Range.ToUpperCase.CompareTo("00000-FFFFF") = 0 Then
        Return CodeIsInRangeHex(Code, LowerUpper(0), LowerUpper(1))
    Else    'default
        Return CodeIsInRangeAlphaNumeric(Code, LowerUpper(0), LowerUpper(1), 0)
    End If

End Sub


Sub CodeIsInRangeAlphaNumeric(Code As String, LowerBound As String, UpperBound As String, FieldGroupingType As Int) As Boolean
   
    'already know that:
    '   code, lowerbound and upperbound are non-blank
    '   upperbound longer than lowerbound
    '   code length is lowerbound length .. upperbound length

    Dim CodeFields() As String = CodeToFields(Code)  
    Dim LowerFields() As String = CodeToFields(LowerBound)
    Dim UpperFields() As String = CodeToFields(UpperBound)
   
    If CodeFields.Length = 0 Or LowerFields.Length = 0 Or UpperFields.Length = 0 Then    'should never happen, but just in case...
        Return False
    Else If LowerFields.Length <> CodeFields.Length Or UpperFields.Length <> CodeFields.Length Then
        Return False
    End If
   
    'check range field lengths
       
    For I = 0 To CodeFields.Length - 1 Step 2    'even fields are alphabetic, and their...
        If LowerFields(I).Length <> UpperFields(I).Length Then    'lower and upper bounds must be same length
            Log(StringArrayToNiceString(CodeFields))
            Log(StringArrayToNiceString(LowerFields))
            Log(StringArrayToNiceString(UpperFields))
   
            Log("error 188 on """ & LowerFields(I) & """-""" & UpperFields(I) & """")
            Return False
        End If
    Next

    For I = 1 To CodeFields.Length - 1 Step 2    'odd fields are numeric, and their...
        If LowerFields(I).Length > UpperFields(I).Length Then    'lower bound can't be longer than upper bound
            Log("error 195 on """ & LowerFields(I) & """-""" & UpperFields(I) & """")
            Return False
        End If
    Next
   
    'check code field lengths
   
    For I = 0 To CodeFields.Length - 1
        If CodeFields(I).Length < LowerFields(I).Length Then
            Return False
        else if CodeFields(I).Length > UpperFields(I).Length Then
            Return False
        End If
    Next
   
    'special case for fixed letter fields
   
    For I = 0 To CodeFields.Length - 1 Step 2
        If LowerFields(I).CompareTo(UpperFields(I)) = 0 Then
            If CodeFields(I).CompareTo(LowerFields(I)) <> 0 Then
                Return False
            End If
        End If
    Next

    'pad numbers to be same length so that string comparisons work for numbers
       
    For I = 1 To CodeFields.Length - 1 Step 2    'only numeric fields need padding
        LowerFields(I) = PadLeft(LowerFields(I), UpperFields(I).Length, "0")
        CodeFields(I) = PadLeft(CodeFields(I), UpperFields(I).Length, "0")
    Next
   
    Dim CheckLowerFlag As Boolean = True
    Dim CheckUpperFlag As Boolean = True
   
    For I = 0 To CodeFields.Length - 1
        If (FieldGroupingType = 1) Or (FieldGroupingType = 2 And Bit.And(I, 1) = 0) Then
            CheckLowerFlag = True
            CheckUpperFlag = True
        End If

        If CheckLowerFlag Then
            Dim TempCompareResult As Int = CodeFields(I).CompareTo(LowerFields(I))
            If TempCompareResult < 0 Then
                Return False
            else if TempCompareResult > 0 Then
                CheckLowerFlag = False
            End If
        End If
       
        If CheckUpperFlag Then
            Dim TempCompareResult As Int = CodeFields(I).CompareTo(UpperFields(I))
            If TempCompareResult > 0 Then
                Return False
            else if TempCompareResult < 0 Then
                CheckUpperFlag = False
            End If
        End If
    Next
       
    Return True    'if not knocked out above, then must be in range
   
End Sub


'code format XXN:
'  first two characters are base-36 A..Z 0..9
'  remaining characters are base-10 0..9

Sub CodeToValueXXN(Code As String) As Int
   
    If Code.Length < 1 Or Code.Length > 8 Then
        Log("Error 220 for code """ & Code & """")
        Return -1
    End If
   
    Dim V As Int = 0
   
    For I = 0 To Code.Length - 1
        If I = 0 Or I = 1 Then
            Dim DigitBase As Int = 36
            Dim DigitValue As Int = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".IndexOf(Code.SubString2(I, I + 1).ToUpperCase)
        Else
            Dim DigitBase As Int = 10
            Dim DigitValue As Int = "0123456789".IndexOf(Code.SubString2(I, I + 1))
        End If
       
        If DigitValue = -1 Then
            Return -1
        End If
       
        V = V * DigitBase + DigitValue
    Next

    Return V

End Sub


Sub CodeIsInRangeXXN(Code As String, LowerBound As String, UpperBound As String) As Boolean

    If LowerBound.Length <> Code.Length Or UpperBound.Length <> Code.Length Then
        Log("error 359 for """ & Code & """ / """ & LowerBound & """ / """ & UpperBound & """")
    End If

    Dim CodeValue As Int = CodeToValueXXN(Code)
    Dim LowerValue As Int = CodeToValueXXN(LowerBound)
    Dim UpperValue As Int = CodeToValueXXN(UpperBound)
   
    If CodeValue = -1 Or LowerValue = -1 Or UpperValue = -1 Then
        Return False
    End If
       
    Return (CodeValue >= LowerValue And CodeValue <= UpperValue)
   
End Sub


'code format hexadecimal:

Sub CodeToValueHex(Code As String) As Int
   
    If Code.Length < 1 Or Code.Length > 7 Then
        Log("Error 377 for code """ & Code & """")
        Return -1
    End If
   
    Dim V As Int = 0
   
    For I = 0 To Code.Length - 1
        Dim DigitValue As Int = "0123456789ABCDEF".IndexOf(Code.SubString2(I, I + 1).ToUpperCase)
       
        If DigitValue = -1 Then
            Return -1
        End If
       
        V = V * 16 + DigitValue
    Next

    Return V

End Sub


Sub CodeIsInRangeHex(Code As String, LowerBound As String, UpperBound As String) As Boolean

    If LowerBound.Length <> Code.Length Or UpperBound.Length <> Code.Length Then
        Log("error 359 for """ & Code & """ / """ & LowerBound & """ / """ & UpperBound & """")
    End If

    Dim CodeValue As Int = CodeToValueHex(Code)
    Dim LowerValue As Int = CodeToValueHex(LowerBound)
    Dim UpperValue As Int = CodeToValueHex(UpperBound)
   
    If CodeValue = -1 Or LowerValue = -1 Or UpperValue = -1 Then
        'error already notified by CodeToValueXXNN()
        Return False
    End If
       
    Return (CodeValue >= LowerValue And CodeValue <= UpperValue)
   
End Sub


Sub GetCodeSeriesList() As List
   
    Dim L As List
    L.Initialize
   
    '''L.Add("Series")
    L.Add("0-5928")
    L.Add("0000-6999")
    L.Add("00001-13284")
    L.Add("0001-0355")
    L.Add("0001-2000")
    L.Add("0001-2000")
    L.Add("0001-2300")
    L.Add("0001-3000")
    L.Add("0001-4000")
    L.Add("0001X-1706X")
    L.Add("001-200")
    L.Add("001-700")
    L.Add("001R-200R")
    L.Add("0AAAA-9XXXX")
    L.Add("0K001-0N718")
    L.Add("1-17850")
    L.Add("1-1988")
    L.Add("1-2000")
    L.Add("1-22185")
    L.Add("1-3001")
    L.Add("1-3679")
    L.Add("1-6000")
    L.Add("1-8100")
    L.Add("10001-11500")
    L.Add("10001-15000")
    L.Add("1001-2174")
    L.Add("1001-2252")
    L.Add("1003591-1006700")
    L.Add("10100-12283")
    L.Add("101A501-304E579")
    L.Add("00000-FFFFF")    'was "1234567890abcdef - Any 5 digits"
    L.Add("14515-15014")
    L.Add("18100-19617")
    L.Add("19001-19420")
    L.Add("1HM1-99HM99")
    L.Add("1NF1-99NF99")
    L.Add("1V00001-5V12295")
    L.Add("20001-32000")
    L.Add("2002001-2003500")
    L.Add("20100-23284")
    L.Add("25001-26200")
    L.Add("2S0001-2S2675")
    L.Add("30001-31200")
    L.Add("30001-37850")
    L.Add("3001-4000")
    L.Add("3001-4481")
    L.Add("30010-32009")
    L.Add("3501-6700")
    L.Add("40000-49999")
    L.Add("40001-41518")
    L.Add("4001-9001")
    L.Add("50000-69999")
    L.Add("50001-51308")
    L.Add("5001-8442")
    L.Add("60000-62113")
    L.Add("60001-60400")
    L.Add("6001-7000")
    L.Add("6001-7001")
    L.Add("6001-8110")
    L.Add("6500-7733")
    L.Add("65001-67012")
    L.Add("70000-75928")
    L.Add("700001-703000")
    L.Add("7001-9000")
    L.Add("701-900")
    L.Add("73000-73999")
    L.Add("80000-80999")
    L.Add("80000-89999")
    L.Add("80001-81500")
    L.Add("8001-9000")
    L.Add("8001-9554")
    L.Add("8100-9113")
    L.Add("A0001-A1000")
    L.Add("A101-A800")
    L.Add("A6001-A7000")
    L.Add("A7001-A8500")
    L.Add("AA00-7T51")
    L.Add("AB6001-AB6891")
    L.Add("B0001-B2608")
    L.Add("B0001-B3000")
    L.Add("B1001-B2200 New")
    L.Add("B1001-B2200 Old")
    L.Add("B101-B800")
    L.Add("B5001-B6200")
    L.Add("B5001-B6200")
    L.Add("B8001-B9000")
    L.Add("B8001-B9000")
    L.Add("BC0001-BC2865")
    L.Add("BH010001-BH241450")
    L.Add("C0001-C2900")
    L.Add("C1001-C3500")
    L.Add("C1001-C3500")
    L.Add("C7001-C8000")
    L.Add("C8001-C9000")
    L.Add("CB0001-CB0709")
    L.Add("CC0001-CC1000")
    L.Add("CC4001-CC4650")
    L.Add("CD0001-CD1000")
    L.Add("CD4001-CD4650")
    L.Add("D00-D99")
    L.Add("D0001-D2000")
    L.Add("D0001-D3000")
    L.Add("D1001-D3500")
    L.Add("D4001-D5200")
    L.Add("D4501-D4542")
    L.Add("DE1-DE11210")
    L.Add("DH0001-DH4000")
    L.Add("DH6001-DH8000")
    L.Add("E0001-E2500")
    L.Add("E2001-E3000")
    L.Add("E4001-E5000")
    L.Add("E5000-E5999")
    L.Add("E5001-E7700")
    L.Add("E6001-E7000")
    L.Add("E8000-E8999")
    L.Add("E8001-E9000")
    L.Add("F0001-F1619")
    L.Add("F0001-F1691")
    L.Add("F0001-F2500")
    L.Add("F0001-F2500")
    L.Add("FA0-FA1863")
    L.Add("G000-G3631")
    L.Add("G0001-G2377")
    L.Add("G0001-G2500")
    L.Add("G101-G598")
    L.Add("G8001-G9000")
    L.Add("H0001-H2500")
    L.Add("H0001-H2500")
    L.Add("H0001-H3000")
    L.Add("H0001-H3988")
    L.Add("H5001-H7000")
    L.Add("HA00000001-HA00008100")
    L.Add("HA00000010-HA00081009")
    L.Add("HB1-HB2988")
    L.Add("HB3001-HB5000")
    L.Add("HK0001-HK2500")
    L.Add("HM1-HM1200")
    L.Add("HM2501-HM3500")
    L.Add("HM4001-HM7350")
    L.Add("HM6001-HM7110")
    L.Add("HS2001-HS3500")
    L.Add("HV1-HV854")
    L.Add("HV1001-HV1918")
    L.Add("HV2001-HV2830")
    L.Add("HV3001-HV3890")
    L.Add("HV4001-HV5151")
    L.Add("HV6001-HV7086")
    L.Add("HV7101-HV8154")
    L.Add("HV8201-HV9282")
    L.Add("HY6001-HY8130")
    L.Add("I0001-I2608")
    L.Add("J00-U39")
    L.Add("J0001-J1200")
    L.Add("J0001-J2500")
    L.Add("JA1001-JA3500")
    L.Add("K0001-K1000")
    L.Add("K0001-K1000")
    L.Add("K0001-K1000")
    L.Add("K0001-K2500")
    L.Add("K5001-K8276")
    L.Add("KE0001-KE2500")
    L.Add("KG0001-KG2500")
    L.Add("KH0001-KH1000")
    L.Add("KU0001-KU2608")
    L.Add("L000-L999")
    L.Add("L0001-L1037")
    L.Add("L0001-L1200")
    L.Add("L1-L3580")
    L.Add("L8001-L10000")
    L.Add("LK0001-LK2500")
    L.Add("M0001-M1200")
    L.Add("M0001-M2500")
    L.Add("M0001-M2500")
    L.Add("M0001-M2618")
    L.Add("M1001-M3500")
    '''L.Add("Mixed")
    '''L.Add("Mixed")
    L.Add("N0001-N2500")
    L.Add("N001-N200")
    L.Add("N001R-N200R")
    L.Add("N225-N814")
    L.Add("N5001-N7000")
    L.Add("N6001-N7000")
    L.Add("NC1001-NC3040")
    L.Add("NF1-NF1200")
    L.Add("NM2501-NM3500")
    L.Add("NS2001-NS3500")
    L.Add("NSP4000-NSP4999")
    L.Add("NSP7001-NSP9000")
    L.Add("O0001-O5000")
    L.Add("O5000-O6999")
    L.Add("P0001-P2390")
    L.Add("P0001-P2500")
    L.Add("P0001-P2500")
    L.Add("R0001-R1000")
    L.Add("S0001-S2500")    'was "S0001-2500"
    L.Add("S0001-S1000")
    L.Add("S0001-S1000")
    L.Add("S0001-S2000")
    L.Add("S0001-S2878")
    L.Add("S000A-S999K")
    L.Add("S4001-S5200")
    L.Add("S5298-S6300")
    L.Add("S8001-S9000")
    L.Add("SC0001-SC2500")
    L.Add("SK0001-SK1000")
    L.Add("T0001-T1000")
    L.Add("T0001-T1000")
    L.Add("T0001-T2500")
    L.Add("T0001-T2500")
    L.Add("T0001-T3000")
    L.Add("T1-T26789")    'was "T1-26789"
    L.Add("T1-T3456")    'was "T1-3456"
    L.Add("T1-T1200")
    L.Add("T1-T1200")
    L.Add("T1-T1200")
    L.Add("T1-T2330")
    L.Add("T1001-T3500")
    L.Add("T5-T3456")    'was "T5-3456"
    L.Add("T5001-T7000")
    L.Add("U0001-U2608")
    L.Add("U1-U2000")
    L.Add("V0000-V1999")
    L.Add("V0001-V2500")
    L.Add("V0001-V5718")
    L.Add("V1-V1200")
    L.Add("V1-V3056")
    L.Add("V2001-V3200")
    L.Add("V5001-V8058")
    L.Add("VN0-VN1999")
    L.Add("W0001-W2409")
    L.Add("W1-W9640")
    L.Add("WC1001-WC3500")
    L.Add("WD1001-WD3500")
    L.Add("X0001-X1000")
    L.Add("X0001-X2245")
    L.Add("X0001-X2248")
    L.Add("X0001-X8000")
    L.Add("X1001-X3500")
    L.Add("X8001-X9000")
    L.Add("Y2001-Y3000")
    L.Add("Y7001-Y8200")
    L.Add("Z0001-Z6314")
    L.Add("Z2001-Z9416")
    L.Add("Z5001-Z6000")

    Return L
   
End Sub
 
Last edited:
Upvote 0
Top