How to use UserForm Values for multiple things - vba

I have UserForm1 which is a multipage userform and I am trying to access the information that was gathered through the form in a sub located in Module1. This sub will need to access several different values and do different things with those values so this is going to be a multipart question.
I have the below code in which I attempt to use one of the values as the upper limit of a For Next Loop. However the current problem is that when the code reaches this line it jumps to the Userform_Initialize routine.
For X = 1 To UserForm1.LocalOffer.Value
Second part of this question comes from inside the For Next loop from above. Where I have the below code. Which would ideally allow me to cycle through a series of similarly named Textboxes from the userform. Not even sure if that will work as the code keeps breaking before getting to that part.
Range("B" & X).Value = UserForm1.Controls("LocalTier" & Tier).Value
Last Part of this question if I have a Textbox in the userform that contains a date in the format 1/18/2015 is there a way for me to grab just a portion of that date say for instance just the Day or just the last digit of the year?
I am using Excel 2013 but the file will be ran on Excel 2007
Edit:
Turns out that problem 1 was fixed by not closing the userform with the X button but instead adding a line to hide the userform when you hit the last button. As it turns out my code for the second question worked just fine once i got past that. Only question left is the last one which I have no ideas on.

As from the comments, I see you don't need anymore to know about points 1 and 2, I will hence limit my answer to the point 3.
Last Part of this question if I have a Textbox in the userform that contains a date in the format 1/18/2015 is there a way for me to grab just a portion of that date say for instance just the Day or just the last digit of the year?
You can use either string manipulation, or date conversion.
Let's assume the Textbox is called myDateTextbox
String manipulation
Among the string manipulators that VBA provides, I would cite Left() and Right().
For example:
last_digit_of_the_year = Right(myDateTextbox.Text, 1)
will return you the last character of the string. On the other hand:
first_digit = Left(myDateTextBox.Text,1)
will return you the first digit of the string.
You can use the Len(myDateTextBox.Text) built-in to return the current length of the string.
Date conversion
You can simply convert your string into date using the CDate() function. Please note this function will return an error if you pass an invalid string. If your textbox contains 24/01/1990, you can first convert the string into a date:
myDate = CDate(myDateTextBox.Text)
Hence, you can retrieve day, month or year like this:
myYear = Year(myDate)
myMonth = Month(myDate)
myDay = Day(myDate)
Please note that CDate recognizes date formats according to the locale setting of your system.. Hence, if the format in the TextBox is not the same than the one of your system, then consider manipulating the string before to adapt it to the proper format. For example, if your system has settings DD/MM/YYYY and your textbox shows a MM/DD/YYYY type, you can "adjust it" as follows:
wrongFormat = myDateTextBox.Text
splittedDate = Split(wrongFormat,"/")
goodFormat = splittedDate(1) & "/" & splittedDate(0) & "/" splittedDate(2)
If wrongFormat was 1/18/2014 but your system would like to read it as 18/1/2014, it's now fine because goodFormat will be equal to 18/1/2014 after the split and re-build.

Related

VBA/PowerPoint: Split date-time field into lines

I have a PowerPoint presentation, where I add an automatically updating date-time field to a text box (via Insert -> Text -> Date & Time, with checked "Update Automatically"). The textbox is resized so that the text (Wednesday, March 31, 2021) is split across two lines, for example:
Wednesday,
March 31, 2021
I would like to process the information line-wise, trying the following VBA:
Sub TryLines()
For Each Line In ActiveWindow.Selection.TextRange2.Lines
Debug.Print Line
Next Line
End Sub
If I call this function with the whole date-time field (distributed across two lines) selected, I get the following output:
Wednesday, March 31, 2021
Wednesday, March 31, 2021
I.e. PowerPoint recognizes that there are actually two lines, but is apparently not able to "break up" the date-time field into actual separate lines, and instead treats the date-time field as a monolith. A similar thing seems to happen for Characters.
Actual question: Is there a way to retrieve the text within a field line-wise? I would like to be independent of date format and of the actual wrapping.
Some more background, if helpful: At last, I would like to compute the polygon formed by the text-selection highlightning. Since I did not find a method to do this in TextRange2, I thought about splitting into lines and compute rectangles per line:
Sub TryToComputeLineBounds() ' call this while the date-time field is selected
For Each Line In ActiveWindow.Selection.TextRange2.Lines
Dim x(4) As Single, y(4) As Single
Line.RotatedBounds x(1), y(1), x(2), y(2), x(3), y(3), x(4), y(4)
Debug.Print Line
For i = 1 To 4
Debug.Print x(i) & " | "; y(i)
Next i
Next Line
End Sub
I realized that the measured points are the same per (what I assumed) line, and then found out that Lines does not actually give me the lines within a date-time field.
I think you're getting the Lines and Characters as a monolith because there is something special about inserted Date & Time that means it will never "break up". I tried your code with a text box that had some characters I typed in and it worked - I was able to read lines and characters one at a time.
So maybe make a temporary copy of the text box but without automatic date inserted, i.e. a Text value equivalent to the date, then use the copy to compute the polygon.
As Morboss surmised, a date field is read as one line regardless of how it appears. In the user interface, if you click on a multiline text, the insertion point appears where you click. Not so with a date: the first time you click on it the entire field is selected and no insertion point appears.
As a workaround, get the day name and date with string parsing:
Sub GetDayName()
Dim SpacePos As Long
Dim FieldText As String, DayName As String, DateValue As String
FieldText = ActiveWindow.Selection.TextRange2.Text
SpacePos = InStr(FieldText, " ")
DayName = Left(FieldText, SpacePos)
DateValue = Right(FieldText, (Len(FieldText) - SpacePos))
MsgBox DayName
MsgBox DateValue
End Sub

Can an unbound text box containing a string be set to equal a date(time) field programatically?

Alright. The goal is to programatically grab a string of numbers from an unbound control on a form. Why? I have a form that contains two controls for a start time and a finish time. The format for these controls are dd/mm/yyyy hh:dd. The end users are complaining that they hate having to take the time to enter the date and time in a single field, especially considering the old form (a horrible Excel spreadsheet where users could type whatever they felt like typing), allowed them to just type the 4-digit time. I am trying to replicate that experience, but as we know, date and time are wrapped into one field in Access.
The idea is to supply the date/time field with the values from the string using separate unbound control. For example, one control will be labelled 'Start Time' and will accept 4 numbers with an input mask of 99:99. Before the form is updated, I would like to pass the string from the control Unfortunately, I do not have the code, but I will attempt to build psuedo code here:
Class Level Module
Private Sub Form_BeforeUpdate(Cancel As Integer)
strStartTime as String
strFinishTime as String
strDate as String
rstDailyLog as recordset
Set rstDailylog = CurrentDb.OpenRecordset ("Daily Log" dbOpenDynaset)
'assign variables to unbound controls on form
strStartTime = Me![Start Time]
strFinishTime = Me![Finish Time]
'Here, I assume I begin parsing my string to the date/time field
'function to edit send the string to the actual date/time field
'Basically, copied from Microsoft Docs
Sub EditName(rstCovertString As Recordset, strStart As String, strFinish As String)
With rstConvertString
.Edit
![Start Time] = strStart
![Finish Time] = strFinish
.Update
.Bookmark = .LastModified
End With
What are the implications of doing so? For example, if the bound form displays a record with an unbound value, how will that record display the desired data?
As I was building this code, I just realized that the field that holds the date/time is a date/time data type?
Now I am really confused. If they are different data types, can I even send my start/finish variables to that control as a string?
It turns out that Access does a TRUCKLOAD of data type conversions for you.
When text box controls are bound to a underlying table, then that text box will return a datetime data type. Even if you stuff in a string - it gets converted to a datetime data type behind the scenes.
And same goes for text, or if the control is bound to a number. (again, data type forcing is actually occurring here. However, VBA is rather forgiving in this regards.
Thus, most of the time you don't notice this issue.
HOWEVER, WHEN the text box is NOT bound to a underlying table, then the data type of that text box is more loosely goosey.
So, set the format of the un-bound text box to date format. If you do this, then even assigning a string value to the text box will cause access to convert the string into a date time. In fact, your code should STILL take the data from that table, and if you are not directly assigining the date column to the text box?
Well, then format the string as USA format.
eg:
me.MyStartDate = format(dtValue, "MM/DD/YYYY")
or
me.MyStartDate = format(dtValue, "YYYY-MM-DD")
You will find that EVEN if your date format is different then above (say based on your computers regional settings), then Access will convert the above to an interal date format, and THEN display what your regional settings are REGARDLESS of the above.
So, your display might be:
DD/MM/YYYY (day first)
But, doing this:
me.MyStartDate = dtvalue
or
me.MyStartDate = format(dtValue,"YYYY-MM-DD")
will work.
So, do NOT convert the datetime value from the table into a string IF POSSIBLE to avoid doing so.
So, you simply assign that actual datetime value directly it to the text box. As long as Access sees and knows that text box has a date format, then it will assume and work with that text box as a date time data type.
The above ONLY works if you set the un-bound text box to have some kind of date formatting. Once you told access that the text box is a date type text box, then directly assign date values from a table (without conversion to a string) is your BEST solution.
As noted, for bound text boxes then the text box will take on the correct datatype - even if you don't format the text box.
And the same above trick also applies to number formats. And thus setting a number format for the text box will result in that text box NOT being a string/text type, but an actual number.
So, you can force/set un-bound text boxes to a given data type by use of the formatting option. Once you do this, then you should not need to format data from a table, but in fact just shove the actual date value into the text box. You can (and should) thus now be able to set any kind of date formatting you want for the text box - even setting that is the exact opposite of the actual date format your computer (and user) has chosen on a whim.
In other words, if you do this correct?
Then you don't care, or even have to know the date format settings on any given computer, and your code will always work.
Of all the suggestions here by me?
If possible, assign the actual date value to the text box, and do NOT format the string. This will allow you to set any kind of date/time format for the text box.
Once you defined/set the text box to be a date format, then it is a datetime thing and data type. As a result, you should not require any conversion from the table data to set/fill out the text box.
Edit
You have:
'assign variables to unbound controls on form
strStartTime = Me![Start Time]
strFinishTime = Me![Finish Time]
No! - declare the above two vars as date, not strings.
dim dtStartTime as date
dim dtFinishTime as date
now:
dtStartTime = Me![Start Time]
dtFinishTime = Me![Finish Time]
'Here, I assume I begin parsing my string to the date/time field
No, don't parse. You have the data as a internal datetime. How you display this data is up to you or the users regional settings. As a developer, it is a date type and a date "thing". Don't convert to string!!!
'function to edit send the string to the actual date/time field
'Basically, copied from Microsoft Docs
Sub EditName(rstCovertString As Dao.Recordset, dtStart As Date, _
dtFinish As date)
Access will often recognize a string with a date/time structure as a date/time value. Could use CDate() function to be sure or use # delimiters.
Do these tests in VBA editor immediate window.
?IsDate("1/1/2020 14:50")
?IsDate(CDate("1/1/2020 14:50"))
?IsDate(#1/1/2020 14:50#)
?IsDate("1/1/2020" & " " & "14:50")
All return True.
If you want to display the saved date/time then bind a textbox to the field. Lock the control if you don't want users to edit in it. Then use VBA to save any edits done in the unbound textboxes. I recommend AfterUpdate event for code to save. Use BeforeUpate event to validate user input.

Excel VBA InputBox value is not a date

I have a user input box where you type in a string, annoyingly this string looks like a date 00/00/0000 and excel reformats it as such.
When the value can't be a date ex. 18/19/4561 (month can't be 18 or 19) it displays it correctly.
But whenever it can be seen as a possible date it switches things around.
I've tried setting the value as a string rather than nothing but excel still changes it when putting it in the page.
When I try manually inputting it in the cell or equal the values from a manually entered cell it works fine.
But whenever I get it from the inputbox it messes with it. Even when I hard code the string to a variable (x = "05/06/4564") it switches things around.
How do I force excel to leave the string as is?
Prefix the value with a single apostrophe and Excel will interpret it as a string.
Eg '18/19/4561
Also, have you tried setting the cell format to Text

Date Formatting in Excel VBA

I have written a long procedure in VBA to manipulate a data set. Part of this involves using and formatting dates, and I can't get it to work properly.
The initial data as downloaded has dates in the format "yyyy-mm-ddThh:mm:ssZ" - e.g. 2014-12-11T04:59:00Z.
I then convert these into a date in UK format of "dd/mm/yyyy". Looping over all relevant cells, I use the following method:
initial_date = Range("A1").Value
Dim publish_date As Date
publish_date = DateValue(Mid(initial_date,9,2) & "/" & Mid(initial_date,6,2) & "/" & Mid(initial_date,1,4))
Range("A1").Value = publish_date
This seems to work fine. The cell automatically changes format to "Date" and when I calculate the difference between these dates and dates in another column, it works fine.
I then pick up these dates again and add to an array:
feed(1, 8) = Range("A1")
and then transfer this value into another array:
new_array(7, 1) = feed(1, 8)
Finally, I insert the value from the new array into a different cell. Having used UK date formatting thus far, I now want this value to display in the form "mm/dd/yyyy".
Range("E1") = new_array(7, 1)
Range("E1").NumberFormat = "mm/dd/yyyy"
This is where it goes wrong.
Running the code as above, the dates are all displayed as "dd/mm/yyyy" format. Excel changes the format of the cells to "custom". Finding the difference between these and other dates works, so the data seems to be stored correctly but not displaying as I want.
If I change the code to
Range("E1") = new_array(7, 1)
Range("E1").NumberFormat = "dd/mm/yyyy"
the dates still do not display correctly. Dates which can be written either way around (i.e. day is equal to or less than 12) display correctly, but are in fact the wrong date. i.e. 2014-12-11T04:59:00Z displays as 12/11/2014 which is what I want, but Excel thinks the date is the 12th November instead of 11th December. Dates such as 29/09/2014 which cannot be written both ways round display in UK format, but are not recognised properly by Excel which thinks the long date should be "29/09/2014" instead of "29 September 2014".
When I remove the formatting line completely, the results are the same.
I'm sorry for the rather long-winded explanataion, but there's clearly something I'm not understanding about how Excel and VBA handle, store and format dates. If anyone could enlighten me what's going wrong, I'd really appreciate it!
(Note, in all the code snippets above, where I quote e.g. Range("A1") this is shorthand. There is in fact a lot more code involved in looping and selecting values, but I know this works, so I am not concerned. The extracts above just demonstrate what happens for the first value in each loop.)
try
Range("E1").NumberFormat = "mm/dd/yyyy"
Range("E1") = Format(new_array(7, 1), "mm/dd/yyyy")

Excel - Copy the displayed value not the actual value

I am a pilot, and use a logbook program called Logten Pro. I have the ability to take excel spreadsheets saved from my work flight management software, and import them into Logten Pro using the CSV format.
My problem however, is that the work flight management software, exports the date and time of take-off of a flight into one cell in the following excel format: DD/MM/YYYY H:MM:SS PM.
This is handled fine by Excel, and is formatted by default to DD/MM/YY even though the actual value is more specific, comprising of the full length date and time group.
This is a problem because Logten Pro will only auto-import the date if it is in DD/MM/YY format, and there is no way to pull out just the displayed DD/MM/YY date rather than the full date time group actual value, unless you manually go through and delete the extra text from the function box.
My question is: Is there a VBA macro that can automatically copy the actual displayed text, and paste it into another cell, changing the actual value as it does, to just the DD/MM/YY value? Additionally, can this be made to work down a whole column rather than individual cells at a time?
Note I have no VBA experience so the perfect answer would just be a complete VBA string I could copy and paste.
Thank You.
As pointed out in the comments, you'd better not use VBA but formulas instead.
This formula:
TEXT(A1,"dd-mm-yyy")
will return the formated date in a text way. You can drag and drop the formula in the whole range of your cells and Copy/Paste Special > Values so that you will only have the needed values to get imported in Logten Pro.
There are three options using formulas.
Rounddown
Excel stores the date time as a number and uses formatting to display it as a date.
The format is date.time, where the integer is the date and the fraction is the time.
As an example
01/01/2012 10:30:00 PM is stored as 40909.9375
All the values after the decimal place relate to the hours and minutes
So a formula could be used to round the number down to a whole number.
=ROUNDDOWN(A1,0)
Then format the value as a short date.
It will then display as 01/01/2012
INT
As above, but using a different formula to get rid of the fraction (time)
=INT(A1)
Text
Alternately the date only could be extracted as text using this formula
=TEXT(A1,"dd/mm/yyyy")
It will then display as 01/01/2012
I'm a bit late to the party on this one, but recently came across this as was searching for answers to a similar problem.
Here is the answer I finally came up with.
Option Explicit
Sub ValuesToDisplayValues()
Dim ThisRange As Range, ThisCell As Range
Set ThisRange = Selection
For Each ThisCell In ThisRange
ThisCell.Value = WorksheetFunction.Text(ThisCell.Value, ThisCell.NumberFormat)
Next ThisCell
End Sub
This answers the question as asked, apart from the new values are pasted over the existing ones, not into a new cell, as there is no simple way to know where you would want the new values to be pasted. It will work on the whole range of selected cells, so you can do a whole column if needed.