Access 2000 help with Mid and InStr

B

Box 666

I have a string that I need to split out into its original components. The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract the rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to achieve this.

Can anybody help please

Thanks

Bob
 
S

Steve

Bob,

You can simlify this by making your field a Date/Time field. Then you can use:

MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)
 
B

Box 666

Steve,
You are correct in that the string represents either d:hh:mm:ss or
hh:mm:ss, but because it is in a string I have been unable to work on it
(min , max, avg etc.) The only way I could find to work on it was to convert
all fields to seconds and then manipulate the data.
My issue is that I am unable to format the string as date/time which was
why I was trying to find out how to extract the individual elements of the
string.

Bob


Steve said:
Bob,

You can simlify this by making your field a Date/Time field. Then you can use:

MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)


--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com


Box 666 said:
I have a string that I need to split out into its original components. The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract the rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to achieve this.

Can anybody help please

Thanks

Bob
 
D

Douglas J. Steele

CDate(Me!NameOfDateTimeField) should convert it to a time, although it'll
fail on times in d:hh:nn:ss format.

Assuming you're using Access 2000 or newer, you should be able to use the
VBA Split function.

If you've got a variable strTotalTime, containing either 0:11:22:33 or
11:22:33, the following code will split it into an array, with each element
contain one number:

Dim varElements As Variant

varElements = Split(strTotalTime, ":")

When strTotalTime is 0:11:22:33, you'll end up with an array of 4 values.
varElements(0) will contain 0, varElements(1) will contain 11,
varElements(2) will contain 22 and varElements(3) will contain 33.

When strTotalTime is 11:22:33, you'll end up with an array of 3 values.
varElements(0) will contain 11, varElements(1) will contain 22 and
varElements(2) will contain 33.

That means the following untested air-code should convert your string to
seconds:

Function ConvertTimeToSeconds(TimeAsText As String) As Long

Dim lngSeconds As Long
Dim varElements As Variant

varElements = Split(TimeAsText, ":")
If IsNull(varElements) = False Then
Select Case UBound(varElements)
Case 2 ' Time was in hh:nn:ss format
lngSeconds = varElements(2) _
+ (60 * varElements(1)) _
+ (3600 * varElements(0))
Case 3 ' Time was in d:hh:nn:ss format
lngSeconds = varElements(3) _
+ (60 * varElements(2)) _
+ (3600 * varElements(1)) _
+ (24 * 3600 * varElements(0))
Case Else ' Unrecognizable format
lngSeconds = 0
End Select
Else ' Something went wrong with Split (should never happen)
lngSeconds = 0
End If

ConvertTimeToSeconds = lngSeconds

End Function


--
Doug Steele, Microsoft Access MVP

(No private e-mails, please)


Box 666 said:
Steve,
You are correct in that the string represents either d:hh:mm:ss or
hh:mm:ss, but because it is in a string I have been unable to work on it
(min , max, avg etc.) The only way I could find to work on it was to convert
all fields to seconds and then manipulate the data.
My issue is that I am unable to format the string as date/time which was
why I was trying to find out how to extract the individual elements of the
string.

Bob


Steve said:
Bob,

You can simlify this by making your field a Date/Time field. Then you
can
use:

MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)


--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com


Box 666 said:
I have a string that I need to split out into its original components. The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract the rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to achieve this.

Can anybody help please

Thanks

Bob
 
P

PC Datasheet

Bob,

Since one form of the data includes days, I presume the data represents the
difference between two Date/Time fields. This is where you need to fix the
problem. First of all, if you are recording the difference in a table, that is
incorrect. You should only be recording the start and end. Then you should
calculate the difference where you need it in a query.

To calculate the difference and be able to work on it, you need to use the
DateDiff function to get the difference in seconds.. It looks like this:
DateDiff("s",Start,End)
So in your query you put the following expression in a field of your query:
MyDifference:DateDiff("s",Start,End)

You can now get the min , max, avg etc, by converting your query to a totals
query by clicking on the Sigma button in the toolbar at the top of the screen
and then changing Group By in the MyDifference field to min , max, avg or
whatever. Finally, you can get the final value in the format you want by using
the Format function.

--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com




Box 666 said:
Steve,
You are correct in that the string represents either d:hh:mm:ss or
hh:mm:ss, but because it is in a string I have been unable to work on it
(min , max, avg etc.) The only way I could find to work on it was to convert
all fields to seconds and then manipulate the data.
My issue is that I am unable to format the string as date/time which was
why I was trying to find out how to extract the individual elements of the
string.

Bob


Steve said:
Bob,

You can simlify this by making your field a Date/Time field. Then you can use:

MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)


--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com


Box 666 said:
I have a string that I need to split out into its original components. The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract the rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to achieve this.

Can anybody help please

Thanks

Bob
 
B

Box 666

Doug,

It may be untested air-code to you, it was a mircle to me... Needless to say
it works perfectly

I have been struggling with this item for a while, at last I can sleep at
night. Thank you very much indeed.

Kindest regards

Bob

Douglas J. Steele said:
CDate(Me!NameOfDateTimeField) should convert it to a time, although it'll
fail on times in d:hh:nn:ss format.

Assuming you're using Access 2000 or newer, you should be able to use the
VBA Split function.

If you've got a variable strTotalTime, containing either 0:11:22:33 or
11:22:33, the following code will split it into an array, with each element
contain one number:

Dim varElements As Variant

varElements = Split(strTotalTime, ":")

When strTotalTime is 0:11:22:33, you'll end up with an array of 4 values.
varElements(0) will contain 0, varElements(1) will contain 11,
varElements(2) will contain 22 and varElements(3) will contain 33.

When strTotalTime is 11:22:33, you'll end up with an array of 3 values.
varElements(0) will contain 11, varElements(1) will contain 22 and
varElements(2) will contain 33.

That means the following untested air-code should convert your string to
seconds:

Function ConvertTimeToSeconds(TimeAsText As String) As Long

Dim lngSeconds As Long
Dim varElements As Variant

varElements = Split(TimeAsText, ":")
If IsNull(varElements) = False Then
Select Case UBound(varElements)
Case 2 ' Time was in hh:nn:ss format
lngSeconds = varElements(2) _
+ (60 * varElements(1)) _
+ (3600 * varElements(0))
Case 3 ' Time was in d:hh:nn:ss format
lngSeconds = varElements(3) _
+ (60 * varElements(2)) _
+ (3600 * varElements(1)) _
+ (24 * 3600 * varElements(0))
Case Else ' Unrecognizable format
lngSeconds = 0
End Select
Else ' Something went wrong with Split (should never happen)
lngSeconds = 0
End If

ConvertTimeToSeconds = lngSeconds

End Function


--
Doug Steele, Microsoft Access MVP

(No private e-mails, please)


Box 666 said:
Steve,
You are correct in that the string represents either d:hh:mm:ss or
hh:mm:ss, but because it is in a string I have been unable to work on it
(min , max, avg etc.) The only way I could find to work on it was to convert
all fields to seconds and then manipulate the data.
My issue is that I am unable to format the string as date/time which was
why I was trying to find out how to extract the individual elements of the
string.

Bob


Steve said:
Bob,

You can simlify this by making your field a Date/Time field. Then you
can
use:

MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)


--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com


I have a string that I need to split out into its original
components.
The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract
the
rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to
achieve
this.
Can anybody help please

Thanks

Bob
 
B

Box 666

Steve,
Thank you for taking the time to assist with this issue.

It is my fault in not going into the full background / details. In my
ignorance I was trying to provide a brief summary of what I thought was the
main issue, in hindsight I see my error.

You are correct in that I do have a Start and End Date in a table and as
you suggest the difference is a calculated field. BUT the calculated
difference is in working days with the definition of a working day being
Mon - Fri and from 9:00am to 5:00pm. This calculation is in a module, but it
produces its result in a string ( I have attached a copy of the module
below.) Which brings us full circle to my first post

Function WorkingHours(ByVal SDate As Date, ByVal EDate As Date) As String

Const SDay As Integer = 8 '8am start
Const EDay As Integer = 18 '6pm finish
Dim lngDays As Long
Dim lngHours As Long
Dim lngMins As Single
Dim lngSecs As Single
Dim lngCount As Long

WorkingHours = "0"
If DatePart("h", SDate) < SDay Then
'Start time before SDay
'Move the time to the start of the working day
SDate = CVDate(Format$(SDate, "dd mmm yyyy") & " " & Format$(SDay,
"00") & ":00:00")
End If

If DatePart("w", SDate, vbMonday) > 5 Then
'Start day not weekday
'Move it to the start hour of monday
Do
If DatePart("w", SDate, vbMonday) = 1 Then Exit Do
SDate = DateAdd("d", 1, SDate)
Loop
SDate = CVDate(Format$(SDate, "dd mmm yyyy") & " " & Format$(SDay,
"00") & ":00:00")
End If

If SDate > EDate Then
Exit Function
End If

If DatePart("Y", SDate) = DatePart("Y", EDate) Then
'Same day
If DatePart("h", EDate) < EDay Then
'Straight subtraction
WorkingHours = "0:" & Format$(EDate - SDate, "hh:mm:ss")
Exit Function
Else
EDate = CVDate(Format$(SDate, "dd mmm yyyy") & " " & CStr(EDay) &
":00:00")
WorkingHours = Format$(EDate - SDate, "hh:mm:ss")
Exit Function
End If
End If

If DatePart("w", EDate, vbMonday) > 5 Then
'Ends on a weekend
lngHours = 0 'The number of hours on the last day
lngMins = 0 'The number of minutes on the last day
lngSecs = 0 'The number of minutes on the last day
Else
'Ends on a weekday
If DatePart("h", EDate) < SDay Then
'Finished before start time
lngHours = 0 'The number of hours on the last Day
lngMins = 0 'The number of minutes on the last Day
lngSecs = 0 'The number of minutes on the last Day
Else
'Finished after start time
lngHours = DatePart("h", EDate) - SDay 'The number of hours on
the last day
lngMins = DatePart("n", EDate) 'The number of minutes on the
last day
lngSecs = DatePart("s", EDate) 'The number of minutes on the
last day
End If
End If
Do
If Int(SDate) > Int(EDate) Then
'Ooops
WorkingHours = "0"
Exit Do
End If
'Step back to start day, stepping over weekends
EDate = DateAdd("d", -1, EDate)
If DatePart("w", EDate, vbMonday) < 6 Then
'This is a weekday
If Int(SDate) = Int(EDate) Then
'We are back to the start date
'Add it to the time from the start day
EDate = CVDate(Format$(EDate, "dd mmm yyyy") & " " &
CStr(EDay) & ":00:00")
lngHours = lngHours + DatePart("h", (EDate - SDate))
lngMins = lngMins + DatePart("n", (EDate - SDate))
lngSecs = lngSecs + DatePart("s", (EDate - SDate))
If lngSecs > 59 Then
lngSecs = lngSecs - 60
lngMins = lngMins + 1
End If
If lngMins > 59 Then
lngMins = lngMins - 60
lngHours = lngHours + 1
End If
WorkingHours = CStr(Int(lngHours \ 8) & ":" &
Format$(lngHours Mod 8, "00") & ":" & Format$(lngMins, "00") & ":" &
Format$(lngSecs, "00"))
Exit Do
Else
If Int(SDate) > Int(EDate) Then
WorkingHours = "0"
Exit Do
Else
'Add in a full day
lngHours = lngHours + EDay - SDay
End If
End If
End If
Loop
End Function


PC Datasheet said:
Bob,

Since one form of the data includes days, I presume the data represents the
difference between two Date/Time fields. This is where you need to fix the
problem. First of all, if you are recording the difference in a table, that is
incorrect. You should only be recording the start and end. Then you should
calculate the difference where you need it in a query.

To calculate the difference and be able to work on it, you need to use the
DateDiff function to get the difference in seconds.. It looks like this:
DateDiff("s",Start,End)
So in your query you put the following expression in a field of your query:
MyDifference:DateDiff("s",Start,End)

You can now get the min , max, avg etc, by converting your query to a totals
query by clicking on the Sigma button in the toolbar at the top of the screen
and then changing Group By in the MyDifference field to min , max, avg or
whatever. Finally, you can get the final value in the format you want by using
the Format function.

--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com




Box 666 said:
Steve,
You are correct in that the string represents either d:hh:mm:ss or
hh:mm:ss, but because it is in a string I have been unable to work on it
(min , max, avg etc.) The only way I could find to work on it was to convert
all fields to seconds and then manipulate the data.
My issue is that I am unable to format the string as date/time which was
why I was trying to find out how to extract the individual elements of the
string.

Bob


Steve said:
Bob,

You can simlify this by making your field a Date/Time field. Then you
can
use:
MyHour = Hour(Me!NameOfDateTimeField)
MyMinute = Minute(Me!NameOfDateTimeField)
MySecond = Second(Me!NameOfDateTimeField)


--
PC Datasheet
Your Resource For Help With Access, Excel And Word Applications
(e-mail address removed)
www.pcdatasheet.com


I have a string that I need to split out into its original
components.
The
string will appear in one of 2 formats either

0:11:22:33 or as 11:22:33

I now need to seperate out each segment, I can get the "33" out ok using
Right([seg],2)

I believe I need to use a combination of Mid and InStr to extract
the
rest,
but because the other items in the string are not always consistant
(sometimes with a "0:" sometimes with out) I am struggling to
achieve
this.
Can anybody help please

Thanks

Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top