Help with string parsing/manipulation (Brain Teaser). (1 Viewer)

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
I have strings that can be any combination of the following:

HHHHHHHD
HHHXHHHD
HHHHDDDD

I need to be able to parse them into meaniful messages to the user. This is very complicated so I am going to post the rules along with this (It's a brain teaser).

Overtime is represented as a eight character code. Each character represents a certain period of time after the first 8 hours Monday thru Friday.



Overtime for Monday thru Friday after 8 hours:

the 1st character is for time worked in the 9th hour (8.1 - 9 hours)

the 2nd character is for time worked in the 10th hour (9.1 - 10 hours)

the 3rd character is for time worked beyond the 10th hour (10.1 and beyond)

Overtime on Saturday:

the 4th character is for time worked in the first 8 hours on Saturday (0-8 hours)

the 5th character is for time worked in the 9th hour on Saturday (8.1 - 9 hours)

the 6th character is for time worked in the 10th hour (9.1 - 10 hours)

the 7th character is for time worked beyond the 10th hour (10.01 and beyond)

Overtime on Sundays & Holidays

The 8th character is for time worked on Sunday or on a holiday

The last character indicates if an optional 4 day 10 hour per day work week can worked without paying overtime after 8 hours worked.

2. OVERTIME INDICATORS USED IN THE OVERTIME PROVISION.

H - means TIME AND ONE HALF due

X - means TIME AND ONE HALF due after 40 HOURS worked

D - means DOUBLE PAY due

Y - means YES

N - means NO

This is an example of what I have to get to:

HHHHHHHDN- this example shows the 1½ rate must be used for time worked after 8 hours Monday thru Friday (characters 1-3); 1½ is also due for all hours worked on Saturday (characters 4-7). Work done on Sundays or Holidays must be paid double time (character 8 (not shown)).

What is the best way to go about this? I am not really looking for some one to write my code I am more interested in the logic that should be put in place. Although I wouldn't mind if some one could show me how to parse the string one character at a time.







[This message has been edited by Talismanic (edited 08-03-2001).]
 
K

Ken Grubb

Guest
To parse the string one character at a time:

Dim i As Integer
Dim OneCharacter As String
For i = 1 To Len(strText)
OneCharacter = Mid$(strText, i, 1)
' Use a Select Case ... End Select block
' here to examine OneCharacter
Next i

Ken Grubb
Burlington, NC, USA
 

pcs

Registered User.
Local time
Yesterday, 19:24
Joined
May 19, 2001
Messages
398
tal,
brain teaser!!!??? what an understatement!

congrats on a very clear explanation of your problem. (wish all questions on this board were so clear!) hope Ken's post was enough to get you started. i would help, but i'm late for my mensa meeting. (i'm being excommunicated tonight


al
 

Fornatian

Dim Person
Local time
Today, 01:24
Joined
Sep 1, 2000
Messages
1,396
Excellant explanation - and only one edit - very impressive.

If I'm getting you right you are wanting to examine each character and determine what payment methods are required.

My suggestion(and it is a suggestion only):

To make the code more readable and understandable I would use constants suchas:

Const WeekDaysTo9Hrs= 1
Const WeekDaysTo10Hrs = 2
Const WeekDays10HrsPlus = 3
Const SatTo8Hrs = 4
Const SatTo9Hrs = 5
Const SatTo10Hrs = 6
Const Sat10HrsPlus = 7
Const SunOrBankHol = 8
Const CanEarnOverTime = 9

You could then examine each item with a bit more readability:

The first thing I would do is examine the 9th Character to determine whether o/t can be paid:

Dim TheTimeCodes as string
Dim blnPayOverTime as Boolean

TheTimeCodes = Me!YourField

If Mid(TheTimeCodes,CanEarnOverTime ,1) = "N" Then
blnPayOverTime = False
Else
blnPayOverTime = True
End if
'having resolved this you can then refer to the boolean varible throughout your code to determine if payment is accessible.

Dim TheTimeCodes as string
TheTimeCodes = Me!YourField


Select Case Mid(TheTimeCodes,WeekDaysTo9Hrs,1)
Case "H"
If blnPayOverTime = True Then
'do H calculation time and half stuff for
weekdays if it's false don't do anything because they aren't entitled
End if

Obviously this code would be a bit longer than Ken's however it might be better for error trapping etc...

Just an idea.

Ian
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Thanks everyone, it's the weekend now so I won't be working on this again until Monday morning. I will either be back for more questions or I will post what I come up with using the recomendations above.
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
i would help, but i'm late for my mensa meeting. (i'm being excommunicated tonight)

I loved that!

I think I am going to start with Ken's explanation and work my way toward Fornations. As of yet, I am still not sure how I am going to get the end results I need.

I think I should break this problem down in steps. The first step is to get the code letter of each position in the string. I tried this:

Dim i As Integer
Dim OC As String
Dim strEval As Integer
For i = 1 To Len(CodePick)
OC = Mid$(CodePick, i, 1)

strEval = MsgBox("Position " & i & " is " & CodePick, vbOKOnly, _
"Answer Message")

I thought this would tell me that Position 1 is H, Position 2 is H and so on. But I was wrong, I got Position 1 is HHHHDDDD, Position 2 is HHHHDDDD and so on. In hind site that makes sence, since that is what I asked it to do. How do I get the letter that is in position 1,2,3,4,5,6,7,8?
 

DALeffler

Registered Perpetrator
Local time
Yesterday, 18:24
Joined
Dec 5, 2000
Messages
263
Try:

strEval = MsgBox("Position " & i & " is " & OC, vbOKOnly, _
"Answer Message")

You might want to stuff everything into an array:

Dim I as Integer
Dim OC(8) as String
For I = 1 To 8
OC(I) = Mid(CodePick,I,1)
Next I

Then everytime you need to reference the third char position, your code would be something like:

strEval = MsgBox("Position 3 = " & OC(3) & (Chr(13) & Chr(10)) & "Position 4 = " & OC(4),vbOkOnly, "Position 3 & 4")

DOug.

[This message has been edited by DALeffler (edited 08-06-2001).]
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Ok this is what I have so far:

Dim I As Integer
Dim strEval As Integer
Dim OC(8) As String
For I = 1 To 8
OC(I) = Mid(CodePick, I, 1)
Next I

strEval = MsgBox("Position 1 = " & OC(1) & vbCrLf _
& "Position 2 = " & OC(2) & vbCrLf _
& "Position 3 = " & OC(3) & vbCrLf _
& "Position 4 = " & OC(4) & vbCrLf _
& "Position 5 = " & OC(5) & vbCrLf _
& "Position 6 = " & OC(6) & vbCrLf _
& "Position 7 = " & OC(7) & vbCrLf _
& "Position 8 = " & OC(8) & vbCrLf _
, vbOKOnly, "Code Positions")

Which gives me this:



Now I want to work the messages from the first post in, should I put them in a array also and then display them like the OC(1)?

If yes, how do I make an array with sentances? Is it:

Dim myArray(8) as String
myArray(1) = "Message 1"
myArray(2) = "Message 2"
and so on?
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Ok I think I have it now. I just need to modify the following and I think I have this problem solved. I will be back if I have more questions. Thanks to all of you for the help!

Dim myArray(8) As String
myArray(1) = "Number 1"
myArray(2) = "Number 2"
myArray(3) = "Number 3"
myArray(4) = "Number 4"
myArray(5) = "Number 5"
myArray(6) = "Number 6"
myArray(7) = "Number 7"
myArray(8) = "Number 8"

Dim I As Integer
Dim strEval As Integer
Dim OC(8) As String
For I = 1 To 8
OC(I) = Mid(CodePick, I, 1)
Next I

strEval = MsgBox("Position 1 = " & OC(1) & " " & myArray(1) & vbCrLf _
& "Position 2 = " & OC(2) & " " & myArray(2) & vbCrLf _
& "Position 3 = " & OC(3) & " " & myArray(3) & vbCrLf _
& "Position 4 = " & OC(4) & " " & myArray(4) & vbCrLf _
& "Position 5 = " & OC(5) & " " & myArray(5) & vbCrLf _
& "Position 6 = " & OC(6) & " " & myArray(6) & vbCrLf _
& "Position 7 = " & OC(7) & " " & myArray(7) & vbCrLf _
& "Position 8 = " & OC(8) & " " & myArray(8) & vbCrLf _
, vbOKOnly, "Code Positions")
 

DALeffler

Registered Perpetrator
Local time
Yesterday, 18:24
Joined
Dec 5, 2000
Messages
263
This code should do the same message box as above - without the array -

Dim I As Integer
Dim strEval, MssgStr

MssgStr = ""
For I = 1 To 8
MssgStr = MssgStr & "Position " & I & "= " & Mid(CodePick, I, 1) & vbCrLf
Next I

strEval = MsgBox(MssgStr, vbOkOnly, "Code Positions")

I wasn't sure what you needed.

Keep Pluggin - you're doin' great!

Doug.

[This message has been edited by DALeffler (edited 08-06-2001).]
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
I am stuck on the last step. Along with the message I need to add one more part. Here it is:

B = Basic HR Rate
H = Time & 1/2
X = Time & 1/2 Over 40
D = Double Time
T = Triple Time

By altering my arrays to this: myArray(1) = " - 9th Hour Mon-Fri". Then say the first chacter is a H, I would get a message like this:

Position 1 = H - 9th Hour Mon-Fri - Time & 1/2

I know that this requires Select Case but I am not sure how to work it into what I have so far. Can one of you help me get started?


[This message has been edited by Talismanic (edited 08-06-2001).]
 

DALeffler

Registered Perpetrator
Local time
Yesterday, 18:24
Joined
Dec 5, 2000
Messages
263
Add one character to the string that you're trying to parse.

The table at the top shows a 4 rows x 2 column array that's represented with a 7 character string. You're missing one element in the character string that should point to an array element - the first one...

The first character of the string you're trying to parse into a message should be from row, "First 8 hours", and from column, "Monday thru Friday".

How much does one get paid for just showing up? (grin!).

Once you do that, looping through an array to get at the pay codes, while maybe no less complicated, will be much easier code to write.

Doug.
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Doug,

I am not sure I understand. At this point I need to take the code and list what the letter stands for so in a case of a HHHHDDDD I would get this:


H - Poisition 1 - 9th Hour Mon-Fri - Time & 1/2
H - Poisition 2 - 10th Hour Mon-Fri - Time & 1/2
H - Poisition 3 - Over 10 Hours Sat - Time & 1/2
H - Poisition 4 - First 8 Hours Sat - Time & 1/2
D - Poisition 5 - 9th Hour Saturday - Double Time
D - Poisition 6 - 10th Hour Saturday - Double Time
D - Poisition 7 - Over 10 Hour Sat - Double Time
D - Poisition 8 - Any Hours Sun or Hol - Double Time


Since these, B = Basic HR Rate, H = Time & 1/2, X = Time & 1/2 Over 40, D = Double Time and T = Triple Time are all constants should the be declared and then evaluated with a Select Case?

Hopefully I haven't tried your patience to awfully far yet!

How much does one get paid for just showing up? (grin!).

You would be surprised. The most amazing thing about this is that this is only about 1/5 of what we have to go through just to work on a State Government job.
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Ok I am a little embarrassed to post this. My method is pretty barbaric, and I think it shows how much I have to learn about programming technique. Anyway here is what I come up with:

Dim myArray(8) As String
myArray(1) = " - 9th Hour Mon-Fri"
myArray(2) = " - 10th Hour Mon-Fri"
myArray(3) = " - Over 10 Hours"
myArray(4) = " - First 8 Hours Saturday"
myArray(5) = " - 9th hour Saturday"
myArray(6) = " - 10th Hour Saturday"
myArray(7) = " - Over 10 Hour Saturday"
myArray(8) = " - Any Hrs Sunday or Holiday"

Dim I As Integer
Dim strEval As Integer
Dim OC(8) As String
For I = 1 To 8
OC(I) = Mid(CodePick, I, 1)
Next I

Dim H As String
Dim B As String
Dim X As String
Dim D As String
Dim T As String
Dim OCletter1
Dim OCletter2
Dim OCletter3
Dim OCletter4
Dim OCletter5
Dim OCletter6
Dim OCletter7
Dim OCletter8

H = "Time & 1/2"
B = "Basic Hour Rate"
X = "Time & 1/2 Over 40"
D = "Double Time"
T = "Triple Time"

If OC(1) = "H" Then
OCletter1 = H
ElseIf OC(1) = "B" Then
OCletter1 = B
ElseIf OC(1) = "X" Then
OCletter1 = X
ElseIf OC(1) = "D" Then
OCletter1 = D
ElseIf OC(1) = "T" Then
OCletter1 = T
End If
If OC(2) = "H" Then
OCletter2 = H
ElseIf OC(2) = "B" Then
OCletter2 = B
ElseIf OC(2) = "X" Then
OCletter2 = X
ElseIf OC(2) = "D" Then
OCletter2 = D
ElseIf OC(2) = "T" Then
OCletter2 = T
End If
If OC(3) = "H" Then
OCletter3 = H
ElseIf OC(3) = "B" Then
OCletter3 = B
ElseIf OC(3) = "X" Then
OCletter3 = X
ElseIf OC(3) = "D" Then
OCletter3 = D
ElseIf OC(3) = "T" Then
OCletter3 = T
End If
If OC(4) = "H" Then
OCletter4 = H
ElseIf OC(4) = "B" Then
OCletter4 = B
ElseIf OC(4) = "X" Then
OCletter4 = X
ElseIf OC(4) = "D" Then
OCletter4 = D
ElseIf OC(4) = "T" Then
OCletter4 = T
End If
If OC(5) = "H" Then
OCletter5 = H
ElseIf OC(5) = "B" Then
OCletter5 = B
ElseIf OC(5) = "X" Then
OCletter5 = X
ElseIf OC(5) = "D" Then
OCletter5 = D
ElseIf OC(5) = "T" Then
OCletter5 = T
End If
If OC(6) = "H" Then
OCletter6 = H
ElseIf OC(6) = "B" Then
OCletter6 = B
ElseIf OC(6) = "X" Then
OCletter6 = X
ElseIf OC(6) = "D" Then
OCletter6 = D
ElseIf OC(6) = "T" Then
OCletter6 = T
End If
If OC(7) = "H" Then
OCletter7 = H
ElseIf OC(7) = "B" Then
OCletter7 = B
ElseIf OC(7) = "X" Then
OCletter7 = X
ElseIf OC(7) = "D" Then
OCletter7 = D
ElseIf OC(7) = "T" Then
OCletter7 = T
End If
If OC(8) = "H" Then
OCletter8 = H
ElseIf OC(8) = "B" Then
OCletter8 = B
ElseIf OC(8) = "X" Then
OCletter8 = X
ElseIf OC(8) = "D" Then
OCletter8 = D
ElseIf OC(8) = "T" Then
OCletter8 = T
End If

strEval = MsgBox _
("Position 1 = " & OC(1) & " " & myArray(1) & " - " & OCletter1 & vbCrLf _
& "Position 2 = " & OC(2) & " " & myArray(2) & " - " & OCletter2 & vbCrLf _
& "Position 3 = " & OC(3) & " " & myArray(3) & " - " & OCletter3 & vbCrLf _
& "Position 4 = " & OC(4) & " " & myArray(4) & " - " & OCletter4 & vbCrLf _
& "Position 5 = " & OC(5) & " " & myArray(5) & " - " & OCletter5 & vbCrLf _
& "Position 6 = " & OC(6) & " " & myArray(6) & " - " & OCletter6 & vbCrLf _
& "Position 7 = " & OC(7) & " " & myArray(7) & " - " & OCletter7 & vbCrLf _
& "Position 8 = " & OC(8) & " " & myArray(8) & " - " & OCletter8 & vbCrLf _
, vbOKOnly, "Code Positions")

It works for now but if anybody has some suggestions I would love to hear them. If I get hit by a red truck tomorrow I wouldn't want this to be a part of my legacy
 

Fornatian

Dim Person
Local time
Today, 01:24
Joined
Sep 1, 2000
Messages
1,396
To build your string there is no need to reference each item individually you include this in For..Next loop as follows by referencing the counter.

Dim TempString as string

For I = 1 To 8
'set a temporary string value first to be used in the string array

Select Case OC(I)
Case "H"
TempString = "Time & 1/2"
Case "B"
TempString = "Basic Hour Rate"
Case "X"
TempString = ""Time & 1/2 Over 40"
Case "D"
TempString = "Double Time"
Case "T"
TempString = "Triple Time"
End Select

OC(I) = "Position "& I & " = "& Mid(CodePick, I, 1) & myArray(I) & TempString
Next I

The above should dynamically set the OC(I) to the entire line, you should then be able to reference them in the message as:

Msgbox = OC(1) & vbcrlf & OC(2) & vbcrlf & etc...

HTH

Ian

Ps.Phew - lots of scrolling involved on that one!
 

Talismanic

Registered User.
Local time
Today, 01:24
Joined
May 25, 2000
Messages
377
Thanks Fornation, this is much better:

Dim myArray(8) As String
myArray(1) = " - 9th Hour Mon-Fri"
myArray(2) = " - 10th Hour Mon-Fri"
myArray(3) = " - Over 10 Hours"
myArray(4) = " - First 8 Hours Saturday"
myArray(5) = " - 9th hour Saturday"
myArray(6) = " - 10th Hour Saturday"
myArray(7) = " - Over 10 Hour Saturday"
myArray(8) = " - Any Hrs Sunday or Holiday"

Dim I As Integer
Dim strEval As Integer
Dim OC(8) As String
Dim TempString As String

For I = 1 To 8
OC(I) = Mid(CodePick, I, 1)
Next I

For I = 1 To 8
Select Case OC(I)
Case "H"
TempString = "Time & 1/2"
Case "B"
TempString = "Basic Hour Rate"
Case "X"
TempString = "Time & 1/2 Over 40"
Case "D"
TempString = "Double Time"
Case "T"
TempString = "Triple Time"
End Select

OC(I) = I & " = " & Mid(CodePick, I, 1) & myArray(I) & " - " & TempString
Next I

strEval = MsgBox(OC(1) & vbCrLf & OC(2) & vbCrLf & OC(3) & _
vbCrLf & OC(4) & vbCrLf & OC(5) & vbCrLf & OC(6) & vbCrLf & _
OC(7) & vbCrLf & OC(8), vbOKOnly, "Code Positions")
 

charityg

Registered User.
Local time
Today, 01:24
Joined
Apr 17, 2001
Messages
634
Okay, this was the most clear, concise, and easy-to-follow post I've read on this forum.

So, Tal, give! How did you do the cool formatting of your posts?

Way savvy, I'm impressed!

~Charity
 

DALeffler

Registered Perpetrator
Local time
Yesterday, 18:24
Joined
Dec 5, 2000
Messages
263
All I’m saying is that it seems to me you have an array like this:
Code:
              Mon thru Fri  Sat  Sun/Hol
First 8 hrs         B        H      D
9th hr              H        H      D
10th hr             H        H      D
over 10 hrs         H        H      D
And CodePick should have the elements of the above array all concatenated together into a 12 character string.

Then you could code the procedure to read like so:
Code:
Dim Mssg, EvalMssg
Dim Count, I, J, K, PayCodePntr As Integer
Dim Hrs(4), DayWrkd(3), PayCode(5, 2), OC As String

Hrs(1) = " - First 8 Hrs"
Hrs(2) = " - 9th hr"
Hrs(3) = " - 10th hr"
Hrs(4) = " - Over 10 Hrs"
DayWrkd(1) = " - Mon thru Fri"
DayWrkd(2) = " - Saturday"
DayWrkd(3) = " - Sun/Hol"
PayCode(1, 1) = "B"
PayCode(1, 2) = " - Basic Pay"
PayCode(2, 1) = "H"
PayCode(2, 2) = " - Time and One-half"
PayCode(3, 1) = "X"
PayCode(3, 2) = " - Time and One-Half after 40 hrs"
PayCode(4, 1) = "D"
PayCode(4, 2) = " - Double Time"
PayCode(5, 1) = "T"
PayCode(5, 2) = " - Triple Time"

Count = 1
Mssg = ""
For I = 1 To UBound(DayWrkd)
   For J = 1 To UBound(Hrs)
      OC = Mid(CodePick, Count, 1)
         For K = 1 To UBound(PayCode, 1)
            If OC = PayCode(K, 1) Then
               PayCodePntr = K
            End If
         Next K
      Mssg = Mssg & "Char " & Count & " = " & OC & Hrs(J) & DayWrkd(I) & _
             PayCode(PayCodePntr, 2) & vbCrLf
      Count = Count + 1
   Next J
Next I

EvalMssg = MsgBox(Mssg, vbOKOnly, "Code Positions")

The reason for doing it this way is to save you time later if things change. Say a new contract gets signed and now the pay rates for working a holiday are no longer the same as for Sundays, there’s a new pay rate for an 11th hour worked, and there’s a new pay rate after 12 hrs worked on any day - Quadruple time (or some such thing).

Now you’d need an array that looks like this:
Code:
              Mon thru Fri  Saturday  Sunday  Holiday
First 8 hrs         B          X         D       T
9th hr              H          D         D       T
10th hr             H          D         D       T
11th hr             D          T         D       T
Over 12 hrs         Q          Q         Q       Q
The only code you’d have to change above is the Dimensioned array elements (provided CodePick goes to 20 characters in length). Like So:
Code:
Dim Hrs(5), DayWrkd(4), PayCode(6, 2), OC As String
Hrs(1) = " - First 8 Hrs"
Hrs(2) = " - 9th hr"
Hrs(3) = " - 10th hr"
Hrs(4) = " - 11th hr"
Hrs(5) = " – Over 12 hrs"
DayWrkd(1) = " - Mon thru Fri"
DayWrkd(2) = " - Saturday"
DayWrkd(3) = " - Sunday"
DayWrkd(4) = “ – Holiday”
PayCode(1, 1) = "B"
PayCode(1, 2) = " - Basic Pay"
PayCode(2, 1) = "H"
PayCode(2, 2) = " - Time and One-half"
PayCode(3, 1) = "X"
PayCode(3, 2) = " - Time and One-Half after 40 hrs"
PayCode(4, 1) = "D"
PayCode(4, 2) = " - Double Time"
PayCode(5, 1) = "T"
PayCode(5, 2) = " - Triple Time"
PayCode(6, 1) = "Q"
PayCode(6, 2) = " - Quadruple Time"
And the rest of the code needs no change; it’ll automatically give you a bigger message box that shows 20 parsed characters rather than 12. I really don’t know that it’s any better than what you’re doing now, other than keeping any necessary changes to one fairly readable section of the code.

Doug.
 

Atomic Shrimp

Humanoid lifeform
Local time
Today, 01:24
Joined
Jun 16, 2000
Messages
1,954
Are these strings stored in a table? - if so, I'd be tempted to parse/split and interpret them within a query (possibly using a few custom VBA functions)
 

Users who are viewing this thread

Top Bottom