Jump past special character once 2 characters entered VBA userform - vba

Not sure if it is possible but is there a piece of code that states when you enter 2 characters then it jumps past the : or / symbol (one for date & one for time that needs manually entering.
I'm guessing it needs to be in the change event of the textbox but not sure on the type of code for setting focus to 3 digits in once 2 have been entered.
Thanks
Al

Say you have a sample UserForm1 with 2 TextBoxes (TextBox1 for the date, TextBox2 for the time)
You can constantly check the length of the string typed in the textboxes and if it is equal to 8 for the date or 4 for the time you manipulate the value ie.
Private Sub TextBox1_Change()
Dim current As String
current = TextBox1.Value
If Len(TextBox1) = 8 Then
current = Left(TextBox1, 2) & "/" & Mid(TextBox1, 3, 2) & "/" & Right(TextBox1, 4)
TextBox1 = current
End If
End Sub
Private Sub TextBox2_Change()
Dim current As String
current = TextBox2.Value
If Len(TextBox2) = 4 Then
current = Left(TextBox2, 2) & ":" & Right(TextBox2, 2)
TextBox2 = current
End If
End Sub
so now if you start the UserForm1 and type for example 10102014 the code will automatically convert it to a date format adding the forward slashes in between the characters. Same goes for the time

Related

Printing a different value in a text box on multiple copies

I have a button that prints a form on the current record.
The form contains a combobox with something like: 123005TEST
This combobox is a lookup to another textbox which is a combination of three text boxes(on a different form):
=([OrderNr] & (""+[Aantal]) & "" & [SapArtNr])
OrderNr is 12300 and Aantal is 5 and SapArtNr is TEST, creating: 123005TEST
My question is, when I click print, is it possible to print a certain amount of copies based on Aantal 5, so printing 5 copies.
And here comes the tricky part.
To have each printed copy a different value in the combobox, so the first copy would have this written in the combobox on the printed paper: 123001TEST and copy two would be 123002TEST and so on, until 5.
I didn't understand which textbox will receive the sequential text. So I put a dummy in the example code:
Option Explicit
Private Sub cmdPrintIt_Click()
Dim strOrderNr As String
Dim strAantal As String
Dim strSapArtNr As String
Dim intHowManyCopies As Integer
Dim intCopy As Integer
Dim strToTextBox As String
strOrderNr = Me.OrderNr.Text
strAantal = Me.Aantal.Text
strSapArtNr = Me.SapArtNr.Text
On Error Resume Next
intHowManyCopies = CInt(strAantal)
On Error GoTo 0
If intHowManyCopies <> 0 Then
For intCopy = 1 To intHowManyCopies
strToTextBox = strOrderNr & CStr(intCopy) & strSapArtNr
Me.TheTextBoxToReceiveText.Text = strToTextBox
'put your code to print here
Next
Else
MsgBox "Nothing to print! Check it."
End If
End Sub

Extracting Date/Time from comment cell

I have a comment field with cells containing text like this:
Cancelled by user at 2018-01-03 03:11:57 without charge
I want to get the date and time information, but it may not always be in the 3rd/4th from last spaces, otherwise I might try to do some sort of complicated split of the cell. Is there an "in cell" way extract the date time information? Or will this need a VBA script? I prefer the former, but I'm trying to make a macro to simplify my life anyway, so VBA would work too.
I'd propose the following formula:
=MID(A1,FIND("at 20",A1)+3,19)
This would require that the date is always preceded by the word 'at' and the date string starts with 20.
You can try this function. It splits the string checking for items that have the first letter numeric, and builds a result string of just the date information.
Public Function ParseForDate(sCell As String) As String
Dim vSplit As Variant
Dim nIndex As Integer
Dim sResult As String
vSplit = Split(sCell, " ")
For nIndex = 0 To UBound(vSplit)
If IsNumeric(Left$(vSplit(nIndex), 1)) Then
sResult = sResult & vSplit(nIndex) & " "
End If
Next
ParseForDate = Trim$(sResult)
End Function
If you wanted to use it in a formula it would look something like this:
=ParseForDate(A1)
To use it in a VBA routine:
Dim s as String
s = ParseForDate(Range("A1"))
Non-VBA solution: (this is assuming the date format is always the same for all cells)
= MAX(IFERROR(DATEVALUE(MID(A1,ROW(INDEX($A:$A,1):INDEX($A:$A,LEN(A1)-19)),20)),0))
+MAX(IFERROR(TIMEVALUE(MID(A1,ROW(INDEX($A:$A,1):INDEX($A:$A,LEN(A1)-19)),20)),0))
Note this is an array formula, so you must press Ctrl+Shift+Enter instead of just Enter when typing this formula.
You will obviously then need to format the cell as a date and time, but this formula gets the numerical value that Excel uses for its internal date and time system.
Using a regex will enable you to fetch the date and time, irrespective of its placement in the string. The following solution will work if the date and time are of the same format as shown in the example string.
Code:
Sub getDateTime()
Dim objReg, matches, str
str = Sheet1.Cells(1, 1).Value 'Change this as per your requirements
Set objReg = CreateObject("vbscript.regexp")
objReg.Global = True
objReg.Pattern = "\d{4}(?:-\d{2}){2}\s*\d{2}(?::\d{2}){2}"
If objReg.test(str) Then
Set matches = objReg.Execute(str)
strResult = matches.Item(0)
MsgBox strResult
End If
End Sub
Click for Regex Demo
Regex Explanation:
\d{4} - matches 4 digits representing the year
(?:-\d{2}){2} - matches - followed by 2 digits. {2} in the end repeats this match 2 times. Once for getting MM and the next time for DD
\s* - matches 0+ whitespaces to match the space between the Date and Time
\d{2} - matches 2 digits representing the HH
(?::\d{2}){2} - matches : followed by 2 digits. The {2} in the end repeats this match 2 times. First time for matching the :MM and the next time for matching the :SS
Screenshots:
Output:
This will be good for about 90 years (using cell C3 for example):
Sub GetDate()
Dim s As String
s = Range("C3").Comment.Text
arr = Split(s, " ")
For i = LBound(arr) To UBound(arr)
If Left(arr(i), 2) = "20" Then
msg = arr(i) & " " & arr(i + 1)
MsgBox msg
Exit Sub
End If
Next i
End Sub

Something is amiss in my timespan code

My code is as follows:
Private Sub tbRcvrDepartTime_textchanged(sender As Object, e As EventArgs) Handles tbRcvrDepartTime.TextChanged
'Converts the 90 Receiver Arrival & Departures Date & Times to a string for comparison
Dim raTime As String = tbRcvrArriveTime.Text 'Takes the Time only String and converts to string
Dim raDate As String = dpRcvrArriveDate.Text 'Takes the DateTimePicker and converts date to string
Dim raDateString = String.Concat(raDate, " ", raTime) 'Puts together the Date & Time into one continuous string
'Dim raDateFormat As String = "MM-dd-yyyy HH:mm" 'Sets the String to Date style Format
Dim raResultDate As Date = CDate(raDateString) 'Finalizes the String for use in below comparison
Dim rdTime As String = tbRcvrDepartTime.Text 'Takes the Time only String and converts to string
Dim rdDate As String = dpRcvrDepartDate.Text 'Takes the DateTimePicker and converts date to string
Dim rdDateString = String.Concat(rdDate, " ", rdTime) 'Puts together the Date & Time into one continuous string
'Dim rdDateFormat As String = "MM-dd-yyyy HH:mm" 'Sets the String to Date Format
Dim rdResultDate As Date = CDate(rdDateString) 'Finalizes the String for use in below comparison
'Checks to see if 2 or more hours have elapsed since Receiver Arrival/Departure Date & Time
Dim elapsedR As TimeSpan = rdResultDate.Subtract(raResultDate)
tbRcvrDepartTime.BackColor = If(elapsedR.TotalMinutes > 120, Color.LightPink, Color.White)
End Sub
Both raTime & rdTime are separate textboxes.
Both raDate & rdDate are datetimepickers.
When I run the code "live" initially the first record I look at is displayed correctly. Once I move to another record, this goes out the window... I get random results where it will not change the backcolor to the proper color if >120 minutes has elapsed. Other times it changes the backcolor when there is <120 minutes elapsed. Sometimes no change in backcolor when it should or it will change color when it should not. I attempted to originally do this using TotalHours but met with the same results. It is random and is not consistent. I have worked on this for 2 days now with no difference in results. My thinking is there needs to be a way to "refresh" the rdResultDate & raResultDate info when each new record is loaded but I am unable to do that with my code knowledge.
The code must be able to take into account if a new date is present - ie raDate: 11/01/2016 and raTime: 23:46 and
rdDate: 11/02/2016 and rdTime: 03:00 - this would exceed 2 hours (or 120 minutes) and should read "True" and change the backcolor as it is over 2 hours (or 120 minutes).
However if the following were true:
raDate: 11/01/2016 and raTime: 23:46 and
rdDate: 11/02/2016 and rdTime: 01:00 this would not exceed 2 hours (or 120 minutes) and should read "False" and would not change the backcolor.
All of this code:
Dim Detention90 As String
Try
If elapsedR.TotalMinutes > 120 Then
Detention90 = "True"
Else
Detention90 = "False"
End If
Select Case Detention90.ToString
Case = "True" : tbRcvrDepartTime.BackColor = Color.LightPink
Case Else : tbRcvrDepartTime.BackColor = Color.White
End Select
Catch ex As Exception
'If a problem occurs, show Error message box
MessageBox.Show("Receiver Arrive Time & Depart Time Elapsed error" & vbCrLf & "Lines 1424-1434")
End Try
condenses down to just this:
Dim elapsedR As TimeSpan = rdResultDate.Subtract(raResultDate)
tbRcvrDepartTime.BackColor = If(elapsedR.TotalMinutes > 120, Color.LightPink, Color.White)
Not sure if it will directly address your issue, but it was a bit too much for a comment and I've found compacting code in this way is often extremely beneficial for tracking down difficult bugs.
But in this case, I suspect the main issue is parsing the datetime values... that you're not always parsing the DateTime value you expect from a given input string. Specifically, you have format string variables raDateFormat and rdDateFormat, but then call Date.Parse() such that these format variables are never used, and you are left at the mercy of whatever the default date format is for your thread, process, or system. If you're on a system that uses a d/m/y order as in the UK instead of the US-style m/d/y, you'll end up with some strange results. You probably want DateTime.ParseExact() instead.

VBA code multiple if condition and put complete datein respective column

I am creating macro and I am stuck in creating the main page of VBA code. we have a sheet named "Renewal" in which all the customer information we dump. Column C we have customer number, Column D We have product type Dental, LIFE & Dis. Column A we have to put complete data, and Column B we have to put annual premium. Now I want the main page where I can one input box1 in which I put customer number, combo box1 in which 3 option I will get "DENTAL, LIFE, DIS., input box2 Date of completion, and input box3 annual premium. If input box1 and combo box1 condition satisfy then date will put on same row of column A and annual premium in column B respectively.
The wording of your question was very interesting, maybe a screenshot might be better. Ok this is what I have crafted. I am sorry I am not sure this code will work 100% as I have not got Word installed on this machine so had to write it in notepad, so may not be the best solution. As suggested in one of the comments - you have to add add() in the button1_click event. Hopefully this has been of some use.
Private Sub add() 'Add the add sub routine to the button1_click
Sheets("Renewal").Activate() 'makes the sheet activate
if textbox1.text <> "" and textbox2.text <> "" and textbox3.text <> "" and combobox1.text <> "" then 'condition
dim pos as integer 'used to find next position
pos = findNext() 'adds next position value
activesheet.cells(1,pos).value = textbox2.text 'adds Date of completion
activesheet.cells(2,pos).value = textbox3.text 'adds annual premium
activesheet.cells(3,pos).value = textbox1.text 'adds customer number
activesheet.cells(4,pos).value = combobox1.text 'adds product type
'unsure if combobox1.text is correct.
end if 'end of the condition
End sub 'end of sub routine
Private function findNext() 'this function finds the next position in sheet
dim x as integer 'used as a counter
x = 1 'counter = 1
do 'start of iteration
x = x + 1 'counting
loop until activesheet.cells(1,x).value = "" 'end when cell (A, counter) has no value
return x 'returns the counter value
End function 'end of function
P.S. If you are a complete begin beginner - This video may help you with the ui: https://www.youtube.com/watch?v=hCIpMwdKCgE

Run message box when cell value time is exceed system time

I have a excel file.
I wish to write a Excel vba to compare the system time and the cell value time.
If system time is exceed the cell value time, it will show a pop out message to inform user that, the time is exceed.
My file will look like this:
I have been research a while but seem like only vba code will able to complete this requirement.
Sub TimeCheck()
Dim ValueTime As Date
Dim SysTime As Date
SysTime = Now()
Finalrow = Cells(Rows.Count, 14).End(xlUp).Row
'Column 14 stands for N, change as required
For I = 6 To Finalrow
'6 stands for first row filled with value, change as required
ValueTime = Cells(I, 14).Value
If TimeValue(ValueTime) < TimeValue(SysTime) Then
Cells(I, 14).Offset(, 1).Value = "Time is exceeeded" '1 is offsetting to column O. Use 2 for column P, 3 for Q and so on, as you prefer.
MsgBox ("Time is exceeeded for user entry in N" & I)
'To store the time error in adjacent O column cells, and to popup for each error
'Remove either as required - esp MsgBox, it is very annoying - put only because you asked in original question
End If
Next I
End Sub
If you want only advise the guest that the time input does not exceed the current, you don't need a vba (intersect will be one way) you can use the validate date
and you can customize the input msg and also the error msg if the value isn't correct.
Example
Sub TimeNow()
Dim cValue As Date '// Cell Value
Dim sTime As Date '// System
cValue = Sheets("Sheet1").Range("B2").Value
sTime = TimeValue(Now)
If sTime > cValue Then
MsgBox "TiMe iS Up. STOP " & TimeValue(Now)
Else: Exit Sub
'or do something
End If
End Sub
You can use the function TimeValue, which returns the value of time as a number between 0 and 1. Posting a simple code to check on cell N6 alone.
/// You may, of course, use loops to check for a range of cells, or use the excel events, or keyboard shortcuts to run the macro.///
Sub TimeCheck()
Dim ValueTime As Date
Dim SysTime As Date
ValueTime = Range("N6").Value
SysTime = Now()
If TimeValue(ValueTime) < TimeValue(SysTime) Then
MsgBox ("Time is exceeeded")
End If
End Sub