I am working with an Access database where I have a form that contains several date entry fields. I have a new user that is used to using a period as a delimiter for dates so instead of "6/22/11" or "6-22-11", they enter "6.22.11". I would like to continue to allow this type of entry, but Access converts "6.22.11" to a time instead of a date. I have tried setting the format on the text box to "Short Date" with no help. I have also tried adding code to the "Lost Focus" event but that is to late since Access has already done the conversion. The "Before Update" event fires before the conversion but will not allow me to change the text in the textbox. Any ideas on how I can allow all three forms of date entry?
your above example
Private Sub Texto0_KeyPress(KeyAscii As Integer)
If Chr(KeyAscii) = "." Then
KeyAscii = Asc("/")
End If
End Sub
works for me.
Another aproximation is play with the BeforeUpdate and AfterUpdate events.
In BeforeUpdate you cannot modify de content of the control, but you can set a flag (a variable defined at module/form level) in the AfterUpdate event and change the content: it will trigger again the BeforeUpdate, but in this case, because is flagged you sould ignore it and unflag.
http://office.microsoft.com/en-us/access-help/control-data-entry-formats-with-input-masks-HA010096452.aspx
Input Mask.
I wrote the following function for a user who was used to entering 6 and 8 digit dates in input masks by just typing a string of numbers with no delimiter. You should be able to modify it for your purposes:
'---------------------------------------------------------------------------
' Purpose : Enables entry of 8-digit dates with no delimiters: 12312008
' Usage : Set OnChange: =DateCtlChange([Form].[ActiveControl])
' 8/ 6/09 : Allow entry of 6-digit dates with no delimiters
' (year 2019 and 2020 must still be entered as 8-digit dates)
'---------------------------------------------------------------------------
Function DateCtlChange(DateCtl As TextBox)
Dim s As String, NewS As String
On Error GoTo Err_DateCtlChange
s = DateCtl.Text
Select Case Len(s)
Case 6
If s Like "######" Then
If Right(s, 2) <> "19" And Right(s, 2) <> "20" Then
NewS = Left(s, 2) & "/" & Mid(s, 3, 2) & "/" & Mid(s, 5, 2)
End If
End If
Case 8
If s Like "########" Then
NewS = Left(s, 2) & "/" & Mid(s, 3, 2) & "/" & Mid(s, 5, 4)
End If
End Select
If IsDate(NewS) Then
DateCtl.Text = NewS
DateCtl.SelStart = Len(DateCtl.Text)
End If
Exit_DateCtlChange:
Exit Function
Err_DateCtlChange:
Select Case Err.Number
'Error 2101 is raised when we try to set the text to a date
' that fails the date control's validation
Case 2101 'The setting you entered isn't valid for this property.
'Log error but don't show user
Case Else
'Add your custom error logging here
End Select
Resume Exit_DateCtlChange
End Function
Access uses the system date and time format to determine how to translate a value. Another option - that would affect every program on this user's computer - is this: http://office.microsoft.com/en-us/access-help/change-the-default-date-time-number-or-measurement-format-HA010351415.aspx?CTT=1#BM2
Alternatively you can use spaces instead of slashes in dates in Access. Thus the user can use the left hand on the space bar and use the right hand on the numeric keyboard. I feel this is much easier to use than either the slash or the hyphen.
Related
I have a field on a form and I need the user to leave it blank or enter a value that is a specific length (20 characters). Does anyone have code that may solve this need?
I have tried:
(Len([SIM / ENGRV]) = 20) or (isnull([SIM / ENGRV])) or ([SIM / ENGRV]="")
I assume the control (field) name in the form is Text1.
So you can use this code in the before update event .
Of course, the code can be much shorter,
But I think that's the clearest way to understand the logic.
Private Sub Text1_BeforeUpdate(Cancel As Integer)
Dim varTmp As Variant
' first check if [ENGRV] > 0 to avoid devision by zero error
If Not IsNumeric([ENGRV]) And [ENGRV] = 0 Then
Text1.Undo
Cancel = True
Else
' now avoid [SIM] is null error
If Nz([SIM], "") = "" Then
Text1.Undo
Cancel = True
Else
varTmp = [SIM] / [ENGRV]
' now we know that varTmp is somthing and not empty then check the length
If Len(Trim(str(varTmp))) <= 20 Then
Text1.Undo
Cancel = True
End If
End If
End If
End Sub
You can do that at the table level. Set the Validation Rule of the field to:
Len([SIM / ENGRV])=20 Or [SIM / ENGRV] Is Null
I have code that does something then you press enter in textfield, problem is when you use Ctrl+Enter, i can capture that event but access tells me in next line that that field is apparently NULL
Private Sub Text5_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Or KeyAscii = 10 Then
If Len(Me.Text5) = 0 Then Exit Sub
If Val(Right(Me.Text5, 1)) > 2 Then Me.Text5 = Left(Me.Text5, Len(Me.Text5) - 1) & "0"
So 'Len' works fine, but the 'Right' function gives out 'Invalid use of null', when i hit debug and check the value it is NULL
I can't figure it out
I guess i need to remove new line characters but how to do that when the text box is null and every function for strings spits out that error
The problem with your check is that Len(Null) is not 0, it's Null.
There are a couple ways to get around this. First, as mentioned in the comments, you can simply add a check for IsNull:
If IsNull(Me.Text5) Or Len(Me.Text5) = 0 Then
The other way you can do this is force it to coalesce by concatenating vbNullString:
If Len(Me.Text5 & vbNullString) = 0 Then
Also you could use Nz and set a return value of your wish in case if the expression is null, in this example also vbNullString and check the result of this function:
If Nz(Me.Text5, vbNullString) = vbNullString Then
or
If Len(Nz(Me.Text5, vbNullString) = 0) Then
or
If Nz(Me.Text5, 0) = 0 Then
or
If Not Nz(Me.Text5, False) Then
For sure you can store the result in a variable first and then check and work with this later on.
Whatever fulfills your needs.
Well, i test it as much as i can and it's just that when you use Ctrl+Enter on a field and capture the key press, field will be null for some reason, i don't see possible way around this
I have 3 combo boxes that contain numbers:
Me.Authorized
Me.Officer
Me.Enlisted
What I'm trying to do is add the values of Me.Officer and Me.Enlisted and make sure it equals Me.Authorized. I have all the other statements/commands figured out, but I can't wrap my head around this one.
The combo box selected value is a string, even when that string contains only digits. You can use Val() to convert that string to a number.
So your required condition can be expressed as ...
Val(Me.Officer) + Val(Me.Enlisted) = Val(Me.Authorized)
You can enforce that requirement in the form's Before Update event ...
Private Sub Form_BeforeUpdate(Cancel As Integer)
If (Val(Me.Officer) + Val(Me.Enlisted) <> Val(Me.Authorized)) Then
MsgBox "Officer plus Enlisted must be equal to Authorized."
Cancel = True
End If
End Sub
That event procedure will abort a record save when your requirement is not satisfied.
I'm trying to find a way to do the following:
I want to have two different formats for a certain text box. To do so, I've done the following: User types one or two digits in a form text box(who's input and format are both "#,0;0;_") and has "yes/no" box on the right of that number field which asks if it's "kg per bag"(so by default it's the other measurement unit which is Percentages), then an OnLoad event is fired when viewing the report for that form, which checks if the yes/no value is yes or no. If "yes" then the format is set to "#.0 & " kg/bag"", if no it's set to "#.0 & " %"".
I will have to additionally divide by 100 when percentages are the ones picked, but first I want the whole thing to work... Which I still can't do!
Sadly, I'm nowhere near getting it to work... Here is my current macro on the onload event of the report, which is marked as not valid expression:
Link to the image on Imgur
Or here is the MacroBuilder Code:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<UserInterfaceMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><UserInterfaceMacro For="Report" Event="OnLoad"><Statements><ConditionalBlock><If><Condition>[yn]=False</Condition><Statements><Action Name="SetValue"><Argument Name="Item">[Text0].[Format]</Argument><Argument Name="Expression">#,0 & " kg/bag"</Argument></Action></Statements></If><Else><Statements><Action Name="SetValue"><Argument Name="Item">[Text0].[Format]</Argument><Argument Name="Expression">#,0 & " %"</Argument></Action></Statements></Else></ConditionalBlock></Statements></UserInterfaceMacro></UserInterfaceMacros>
Which is displayed as:
If [yn]=False Then
SetValue
Item = [text0].[format]
Expression = #,0 & " kg/bag"
Else
SetValue
Item = [text0].[format]
Expression = #,0 & " %"
End if
Can anyone give me a hint on where to go with this? Thank you!!
P.S. Comma is my decimal separator in regional settings!
You don't really need to change format only concatenate the numeric value with unit (kg/bag or %).
Using VBA, try the following code in the OnLoad event (I am assuming the recordsource field behind the text0 control is called the same -text0):
If Forms!yourformname![yn] = False Then
Reports!yourreportname!text0 = Me.text0 & " kg/bag"
Else
Reports!yourreportname!text0 = (Me.text0)/100 & "%"
' ALTERNATIVELY: Reports!yourreportname!text0.Format = "percent"
End If
Alternatively in the OnLoad event, use an embedded macro or call an external macro with the following one action (if/then changed into the IIF function):
SetValue
Item: text0
Expression: =IIF(Forms!yourformname![yn] = False, text0 & " kg/bag", text0/100 & "%")
I'm currently working on what should be a relatively simple database, which is very close to being at its end, until I hit the inevitable problem.
I'm using Global Variables and a Form to collect parameters to pass into the Criteria portion of a Query, which works just fine for the first two, which are basic strings and integers.
Then comes the dates, which work, so long as you chose a date from the DatePicker that is entered into the query.
For example, if the query field holds 6/1/2014, 6/3/2014, and 6/8/2014, and the date 6/5/2014 is picked, the form will crash and go blank, though if you pick 6/8/2014, it'll go on as it should.
I had tried a variety of different forms of the code, but in the most basic form I simple have:
Between Get_Global('GBL_Start_Date_ID') AND Get_Global('GBL_End_Date_ID')
I'm not sure if I should be limiting the DatePicker based on the values entered in the query, or if there's a more robust way of going about this, or maybe I just completely missed a simple checkbox.
EDIT
My code for the Global Variables looks like this:
Option Compare Database
Global GBL_Start_Date_ID As Date
Global GBL_End_Date_ID As Date
Global GBL_Customer_ID As Long
Global GBL_Engineer_ID As Long
Public Function Init_Globals()
GBL_Start_Date_ID = #6/1/2014#
GBL_End_Date_ID = #6/30/2014#
GBL_Customer_ID = 1
GBL_Engineer_ID = 1
End Function
Public Function Get_Global(gbl_parm)
Select Case gbl_parm
Case "GBL_Customer_ID"
Get_Global = GBL_Customer_ID
Case "GBL_Engineer_ID"
Get_Global = GBL_Engineer_ID
Case "GBL_Start_Date_ID"
Get_Global = GBL_Start_Date_ID
Case "GBL_End_Date_ID"
Get_Global = GBL_End_Date_ID
End Select
End Function
And I just add a simple line to the AfterUpdate event of the ComboBoxes and TextBoxes to assign the variable:
GBL_Engineer_ID = Me.EngineerSelection
Thanks in advance,
Aaron
You can do two things. Fix the query as it is written or make it much more robust.
To fix it as written
Between "#" & Get_Global('GBL_Start_Date_ID') & "#" AND "#" & Get_Global('GBL_End_Date_ID') & "#"
OR
change your Get_Global function
Public Function Get_Global(gbl_parm)
Select Case gbl_parm
Case "GBL_Customer_ID"
Get_Global = GBL_Customer_ID
Case "GBL_Engineer_ID"
Get_Global = GBL_Engineer_ID
Case "GBL_Start_Date_ID"
Get_Global = "#" & GBL_Start_Date_ID & "#"
Case "GBL_End_Date_ID"
Get_Global = "#" & GBL_End_Date_ID & "#"
End Select
End Function
You are correctly specifying that the values of GBL_Start_Date_ID and GBL_End_Date_ID are dates by using #s when you create them however when you use them in your query they appear without them. You can prove to yourself this is what is happening by typing ?#1/1/2014# into the immediate window. The date is printed as 1/1/2014 which when used in your query, makes Between 6/1/2014 AND 6/30/2014 which is a syntax error.
To make things all that much better you need to parameterize this part of your query. Change this
Between Get_Global('GBL_Start_Date_ID') AND Get_Global('GBL_End_Date_ID')
to this
Between pStartDate AND pEndDate
Before you call your query you need to do your usual checks: are either of these null? is pStartDate < pEndDate?
By performing these checks and parameterizing this you ensure that you never end up with a query like this. Calling your query means you need to need to populate the parameters with DAO or ADO.
Between AND