IF vs. SELECT - Check if Date Textbox is empty / null (1 Viewer)

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
I have a form that generates a report based that selects between two dates entered in textboxes (txtStartDate & txtEndDate).

Why does this work?
PHP:
Private Function CheckDates()

Dim btns As String
btns = vbExclamation

Dim StartDate As Variant
Dim EndDate As Variant

StartDate = Me.txtStartDate
EndDate = Me.txtEndDate


If IsNull(StartDate) Then
    Dim MsgBoxStartTitle As String
    Dim MsgBoxStartText As String
    Dim MsgBoxStartDateError As String

    MsgBoxStartTitle = "No Start Date Entered!"
    MsgBoxStartText = "Please enter a starting date for the report!"
    MsgBoxStartDateError = MsgBox(MsgBoxStartText, btns, MsgBoxStartTitle)
    Me.txtStartDate.SetFocus
    ExitCmd = True
    Exit Function
Else

End If

End Function

but this doesn't?

PHP:
Private Function CheckDates()

Dim btns As String
btns = vbExclamation

Dim StartDate As Variant
Dim EndDate As Variant

StartDate = Me.txtStartDate
EndDate = Me.txtEndDate

Select Case StartDate

Case Is = Null
Dim MsgBoxStartTitle As String
Dim MsgBoxStartText As String
Dim MsgBoxStartDateError As String

MsgBoxStartTitle = "No Start Date Entered!"
MsgBoxStartText = "Please enter a starting date for the report!"
MsgBoxStartDateError = MsgBox(MsgBoxStartText, btns, sgBoxStartTitle)
Me.txtStartDate.SetFocus
ExitCmd = True
Exit Function

Case Is <> Null
ExitCmd = False
End Select

End function
:confused:


Also. why won't it work when I use this
Dim StartDate as Date
But it works with
Dim StartDate as Variant
:confused:
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
When you dimension a variant it's value is not Null - it's Empty.
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
That can be condensed right down to this.

You've declared it as a function although it doesn't return a value so it would be better as a Sub.

You don't need to dimension variables for the message box especially if you are only using it once in the running of the routine so you can put them directly into the MsgBox command.

There's no need to create an EndDate variable as you never used it in the code.

There's no need to make a StartDate variable as you have this routine written in your form's module meaning you can reference the control txtStartDate directly.

ExitCmd isn't specified within the routine - no idea what that is doing there.

If there is no ELSE to your IF statement there's no need to put an ELSE in - just close it with the END IF statement.

Code:
Private Sub CheckDates()

    If IsNull(Me.txtStartDate) Then
        MsgBox "Please enter a starting date for the report!", vbExclamation, "No Start Date Entered!"
        Me.txtStartDate.SetFocus
        Exit Sub
    End If

End Sub
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
Mile-O-Phile

Off the bat, I should have probably mentioned that I am using Access 97 for this database.

I've tried replacing Null with Empty and " " but it still doesn't work.
:(

I do use the EndDate but I didn't included it here for the sake of brevity. Probably should have deleted it, sorry about that!

The reason for the CmdExit = True/False is because I pass that value to my report buttons (Preview/Print/Mail/Save As) so that if CmdExit = True it will exit the command button and not bother to show a preview or accidentaly print and so on...

I've tried to not dim the MsgBox variable but it'll give me a compile error saying variable not defined. I've done it before without Dim-ing and I don't know what I get this error.

There's no need to make a StartDate variable as you have this routine written in your form's module meaning you can reference the control txtStartDate directly.
- Good point but now that I think of it, I may declare it as a global variable (is that the correct term?) like I did ExitCmd so that I can use it when I specify the name of the file when I save it as a SnapShot file. I like to do it that way so that if I have to reuse the code but have different names for txtBoxes I just have to change in the Dim statment. Or is there a reason I shouldn't do it?
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
Cosmos75 said:
Off the bat, I should have probably mentioned that I am using Access 97 for this database.

I use Access 97 too.

I've tried replacing Null with Empty and " " but it still doesn't work.

I just made a quick SELECT CASE on a variant with Case Is = Empty and it worked.

I do use the EndDate but I didn't included it here for the sake of brevity. Probably should have deleted it, sorry about that!


Grrrrr!!! :p


The reason for the CmdExit = True/False is because I pass that value to my report buttons (Preview/Print/Mail/Save As) so that if CmdExit = True it will exit the command button and not bother to show a preview or accidentaly print and so on...

Understood.

I've tried to not dim the MsgBox variable but it'll give me a compile error saying variable not defined. I've done it before without Dim-ing and I don't know what I get this error.

You'll be getting the error if you use brackets in a MsgBox statement when you don't have to.

i.e.

Code:
MsgBox "No Need For Brackets", vbOkOnly, "Example One"

Result = MsgBox("Now Brackets Are Needed", vbYesNo, "Example Two")


I may declare it as a global variable (is that the correct term?) like I did ExitCmd so that I can use it when I specify the name of the file when I save it as a SnapShot file.

Global variable/public variable (same thing). You should try to limit the use of these in your database as everytime you reference one the whole module in which it was declared is loaded into the computer's memory.


I like to do it that way so that if I have to reuse the code but have different names for txtBoxes I just have to change in the Dim statment. Or is there a reason I shouldn't do it?

In that case make the whole function sub Public in a standalone module and pass the dates in.

i.e.

Code:
Public Sub CheckDates(ByRef txtStartDate As Textbox, ByRef txtEndDate As Textbox)

Now you don't need to dimension these variables in your routine as you have passed them from the calling form/report.
 
Last edited:

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
PHP:
btns = vbExclamation

Select Case Me.txtStartDate

Case Is = Empty
MsgBoxStartTitle = "No Start Date Entered!"
MsgBoxStartText = "Please enter a starting date for the report!"
MsgBoxStartDateError = MsgBox MsgBoxStartText,  btns,  MsgBoxStartTitle
Me.txtStartDate.SetFocus
ExitCmd = True
Exit Function

Case Is <> Empty
ExitCmd = False
End Select

I've tried this but it doesn't work. It won't return ExitCmd = true.

This is the code I have behind my Preview Button

PHP:
Private Sub cmdPreviewDateRange_Click()
On Error GoTo Err_cmdPreviewDateRange_Click

Call CheckDates

Select Case ExitCmd
Case Is = True
    Exit Sub
Case Is = False
End Select

    Dim stDocName As String

    stDocName = Me.cboReportDateRange.Column(0)
    
    DoCmd.OpenReport stDocName, acPreview

Exit_cmdPreviewDateRange_Click:
    Exit Sub

Err_cmdPreviewDateRange_Click:
    MsgBox Err.Description
    Resume Exit_cmdPreviewDateRange_Click
    
End Sub
Do you see anything wrong??
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
Cosmos75 said:
Code:
Select Case Me.txtStartDate

Case Is = Empty

This time you are referencing the textbox and not a variant - a textbox will return Null if it is empty.

What you'd rather use, though, is the IsDate() function.

Code:
btns = vbExclamation
 
If Not IsDate(Me.txtStartDate) Then
   ExitCmd = False
Else
    MsgBoxStartTitle = "No Start Date Entered!"
    MsgBoxStartText = "Please enter a starting date for the report!"
    MsgBoxStartDateError = MsgBox(MsgBoxStartText,  btns,  MsgBoxStartTitle)
    Me.txtStartDate.SetFocus
    ExitCmd = True
    Exit Function
End If

I don't see the need to use the SELECT CASE function as your situation is basically an either/or possibility and not something where you can have many probabilities i.e. 10 possible cases.
 
Last edited:

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
in your second part this is unnecessary:

Code:
Select Case ExitCmd
    Case Is = True
        Exit Sub
    Case Is = False
End Select

As all you need to say, in one line, is:

Code:
If ExitCmd = True Then Exit Sub

If it's true then the sub will exit; there's no need to check if it's false because if it wasn't then it defeats the purpose of being a boolean (either True or False - no leeway) so if it hasn't exited the sub then it is obviously false and will continue to run the remainder of your code.
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
Mile-O-Phile,

I'd like to be able to use Select Case as there might be other conditions I'd like to add.

I plan to add a txtbox showing the earliest avaiable date with date as well as the latest. So eventually, I'd like to have something like this

PHP:
Select Case me.txtStartDate

Case Is = Null

Case Is < me.txtEarliestDate

Case Is > me.txtLatestDate

Case Is Else

End Select

I tried to use

MsgBoxStartDateError = MsgBox MsgBoxStartText, btns, MsgBoxStartTitle

but I get an error message saying "Expected End Of Statement"

MsgBox MsgBoxStartText, btns, MsgBoxStartTitle is ok BUT it'll still give ma an error message saying variable not defined for the MsgBoxStartTitle & MsgBoxStartText.


Doe having the follwing cause my having to Dim variables?
PHP:
Option Compare Database
Option Explicit

Forgive me if all this seems obvious but I am still trying to figure out VBA for Access. AND THANK YOU for all your help so far!
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
Cosmos75 said:
but I get an error message saying "Expected End Of Statement"

Brackets - My fault, I've edited the earlier post to include them.

One other thing: CASE IS ELSE will cause an error; just CASE ELSE
 

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
And yes, the variables will have to be defined as you have Option Explicit set - good practice that.

Also, you can save memory by dimensioning btns as an integer rather than a string as each access constant has a numerical value.

Even a variable designed for a message box response can be an intger, too.
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
Argh!! it's not working!! HELP!!

PHP:
Option Compare Database
Option Explicit
Dim ExitCmd As Boolean

Private Function CheckDates()

Dim btns As String
btns = vbExclamation

Dim ReportName As String
ReportName = Me.cboReportDateRange.Column(0)

If Me.cboReportDateRange = "" Then
    Dim MsgBoxReportTitle As String
    Dim MsgBoxReportText As String
    Dim MsgBoxReportError As String
    MsgBoxReportTitle = "No report selected!"
    MsgBoxReportText = "Please select a report."
    MsgBoxReportError = MsgBox(MsgBoxReportText, btns, MsgBoxReportTitle)
    Me.cboReportDateRange.SetFocus
    ExitCmd = True
    MsgBox "Report " & ExitCmd
    Exit Function
Else
    ExitCmd = False
    MsgBox "Report " & ExitCmd
    Exit Function
End If


Dim StartDate As Variant
Dim MINDate As Variant
Dim MAXDate As Variant

StartDate = Me.txtStartDate
MINDate = DMin("MinOfUsageDay", "qryAvailableUsageDaysMIN")
MAXDate = DMax("MaxOfUsageDay", "qryAvailableUsageDaysMAX")

Select Case StartDate

Case Is = Empty
    Dim MsgBoxStartTitle As String
    Dim MsgBoxStartText As String
    Dim MsgBoxStartDateError As String
    MsgBoxStartTitle = "Out of range!"
    MsgBoxStartText = "Please enter a new starting date for the report!"
    MsgBoxStartDateError = MsgBox(MsgBoxStartText, btns, MsgBoxStartTitle)
    Me.txtStartDate.SetFocus
    MsgBox "Start is empty"
    ExitCmd = True
    Exit Function

Case Is < MINDate
    Dim MsgBoxMINTitle As String
    Dim MsgBoxMINText As String
    Dim MsgBoxMINDateError As String
    MsgBoxMINTitle = "Enter later start date!"
    MsgBoxMINText = "Please enter a new starting date for the report!"
    MsgBoxMINDateError = MsgBox(MsgBoxMINText, btns, MsgBoxMINTitle)
    Me.txtStartDate.SetFocus
    MsgBox "Start is < MIN"
    ExitCmd = True
    Exit Function

Case Is > MAXDate
    Dim MsgBoxMAXTitle As String
    Dim MsgBoxMAXText As String
    Dim MsgBoxMAXDateError As String
    MsgBoxMAXTitle = "Enter earlier start date!"
    MsgBoxMAXText = "Please enter a starting date for the report!"
MsgBoxMAXDateError = MsgBox(MsgBoxMAXText, btns, MsgBoxMAXTitle)
    Me.txtStartDate.SetFocus
    MsgBox "Start is > MAX"
    ExitCmd = True
    Exit Function

Case Else
    ExitCmd = False
    MsgBox "Start is within valid range"
    Exit Function

End Select


End Function

Private Sub cmdPreviewDateRange_Click()
On Error GoTo Err_cmdPreviewDateRange_Click

Call CheckDates

If ExitCmd = True Then
    Exit Sub
End If

    Dim stDocName As String

    stDocName = Me.cboReportDateRange.Column(0)
    
    DoCmd.OpenReport stDocName, acPreview

Exit_cmdPreviewDateRange_Click:
    Exit Sub

Err_cmdPreviewDateRange_Click:
    MsgBox Err.Description
    Resume Exit_cmdPreviewDateRange_Click
    
End Sub

I can't get it to work!!!
:(

None of the MsgBoxes for the StartDate Select Case statements are shown?!?!?!?!?
:confused:

Does it matter that I have an input mask for txtStartDate?

If I choose a report from the report combobox (cboReportDateRange), I will get the message Report False, but I don't choose anything, I an error message saying "Invalid use of Null".
I get the same message if I use If Me.cboReportDateRange = "" Then
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
Here u go.. just barely managed to get it small enough!!
 

Attachments

  • report97.zip
    96.5 KB · Views: 136

Mile-O

Back once again...
Local time
Today, 20:22
Joined
Dec 10, 2002
Messages
11,316
As I said before change CheckDates to a Sub and not a Function as you are not using it to return a value.

I've modified your code and it now works - there were many silly errors in there which will explain why it wouldn't work.

Firstly, here's the CheckDates sub rewritten to work with all the unnecessary variables you have dimensioned taken out. You even tried to dimension three variables twice within the same routine.

Code:
Private Sub CheckDates()

    Dim ReportName As String
    Dim MINDate As Date
    Dim MAXDate As Date
    
    'ReportName = Me.cboReportDateRange.Column(0)

    If IsNull(Me.cboReportDateRange) Then
        MsgBox "You have not selected a report to generate. Please select a report.", vbExclamation, "No report selected!"
        ExitCmd = True
        Me.cboReportDateRange.SetFocus
        Exit Sub
    Else
        ExitCmd = False
    End If

    MINDate = DMin("MinOfUsageDay", "qryAvailableUsageDaysMIN")
    MAXDate = DMax("MaxOfUsageDay", "qryAvailableUsageDaysMAX")

    If IsNull(Me.txtStartDate) Then
        MsgBox "Please enter a starting date for the report!", vbExclamation, "No Start Date Entered!"
        Me.txtStartDate.SetFocus
        ExitCmd = True
        Exit Sub
    End If

    If IsNull(Me.txtEndDate) Then
        MsgBox "Please enter a ending date for the report!", vbExclamation, "No End Date Entered!"
        Me.txtEndDate.SetFocus
        ExitCmd = True
        Exit Sub
    End If

    Select Case Me.txtStartDate
        Case Is < MINDate
            MsgBox "You've entered a start date that is later that the latest avaiable start date. Please enter a new starting date for the report!", vbExclamation, "Out of Range!"
            Me.txtStartDate.SetFocus
            ExitCmd = True
            Exit Sub
        Case Is > MAXDate
            MsgBox "Please enter a starting date for the report!", vbExclamation, "No Start Date Entered!"
            Me.txtStartDate.SetFocus
            ExitCmd = True
            Exit Sub
        Case Else
            ExitCmd = False
    End Select

End Sub

You should not consider this code to be a finished article as there is massive scope for development.

A good routine does what it has to do in 60 lines of code or less and a good routine does one operation.

Yours was rather big and performs a number of operations.

I'd suggest not checking the dates on the click of the button but on each textbox's BeforeUpdate event - that way if it is an illegal date you can inform them with a message box and make use of that particular event's Cancel argument.

The OnClick of the button could easily just look at the vaues of the StartDate, EndDate, and the report combo and inform the user if they are Null and exit the sub and running the report if all our values are okay.

So, on to why it would not work:

1) On the click of the button the first thing you were doing was making a variable called ReportName and trying to assign the value of a combobox to it. If the combobox hadn't had a selection made then an error would occur (Invalid Use Of Null)

2) Next step, you were asking if the combobox was empty. Why reference the combobox if you've just assigned its value to the variable ReportName? You then dimensioned three variables for a message box but I'll discuss these at the end of the thread - let's just say unnecessary for now. Of course, the combobox would never be EMPTY, if it had no value it would be NULL so your code wouldn't notice that as it ran through.

3) In the same part as #2 you exit the routine if the combobox doesn't have a value and even if it does. As checking if it is EMPTY will make the program think there is a value in the combobox the code follows on through and sets your boolean to TRUE and then exits the routine altogether.

4) Dim StartDate As Variant, and the others. Variants take up bigger amounts of memory than the other variables and it is a best practice to choose the data type most suited to your variable in this case, the title says it all, a Date variable.

5) The method in which you got the maximum date and the minimum date looks as if you've created two queries for the sole purpose of retrieving the MAX and MIN dates. This is a step too much. You can simply use DMAX("Field", "tblBase") where tblBase is the table you are getting the data from. Domain Aggregate functions are notoriously slow enough without having to run a query each to get the respective values you want.

6) When checking the dates are valid you have this structure:

Code:
If date is not okay then
    do something
    exit the routine
Else
    exit the routine
End If

Can you see why this bit wasn't working?

When evaluating on a value/function that will return True or False and you are only interested in one of those values there is no need to bother with the other.

Code:
If date is not okay Then
    do something
    exit the routine
End If

7) Finally, your select case statements, no matter what, had the outcome that you would exit the routine. Not really helpful when you still have code to run through in that routine.



Just as an extra thing, regarding message boxes and variable declaration.

You seem to have the habit of doing this (see below) and I don't know whether someone showed you it that way once and you've always done it like that or it was in a book, etc.

Code:
Dim MsgBoxMAXTitle As String
Dim MsgBoxMAXText As String
Dim MsgBoxMAXDateError As String
MsgBoxMAXTitle = "No Start Date Entered!"
MsgBoxMAXText = "Please enter a starting date for the report!"
MsgBoxMAXDateError = MsgBox(MsgBoxMAXText, btns, MsgBoxMAXTitle)

I'm not saying there is anything wrong with it, it's just unnecessary for the task at hand.

You are diplaying a message box and btns[/b] as you declared elsewhere in the code is storing the vbExclamation constant (the fact that it is an Access constant begs the question why you need to store it).

A message box, such as you have created, only has one button: it's value is vbOk.

In your code, when you click that OK button you are storing the integer value for vbOk in the variable MsgBoxMAXDateError although you never have the need to use it in your code. So why bother?

As you don't need the value, this should suffice:

Code:
MsgBox MsgBoxMAXText, vbExclamation, MsgBoxMAXTitle

The only problem I can see with your declaration of variables for the message and title parts of the message box - for every message box you are declaring three variables: one to hold its message, one to hold its title, and one to hold a result that you'll never use.

If your message boxes are going to contain the same messages then it would be a smarter approach to use two variables (for the message and the title) but in these cases you are better off, and more efficient, to just say:

Code:
MsgBox "This is a message box", vbExclamation, "This is its title"

The only time you would need to store the result of a message box is when you want to evaluate the option chosen by the user, let's say, in a vbYesNo box.

i.e

Code:
Dim intResult As Integer
intResult = MsgBox("Are you bored reading all of this?", vbQuestion + vbYesNo, "Question for the Attentive")
If intResult = vbYes Then
    MsgBox "Well don't worry, we're almost at the end.", vbInformation, "Relief"
Else
    MsgBox "Bored? How can you be bored? Code is fun!", vbExclamation, "Boredom Alert"
End If

As a general rule, but not written, you should declare all your variables at the start of your routine - it helps from making mistakes like you did by dimensioning variables with the same name twice within the same routine.

Hope all this is of help...


:eek: :eek: :eek: :eek: :eek:
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
THANK YOU!!!!!!!!!!

Mile-O-Phile

OMG! How long did that take you!!
:eek:

THANK YOU! THANK YOU! THANK YOU!
:)

I TRULY appreciate the amount of effort you've taken to help me out on this!!

I also appreciate your suggestions, I will change the code accordingly!

I didn't know that you can also call (Call CheckDates) a sub. I thought you could only do that with functions.
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 15:22
Joined
Feb 19, 2002
Messages
43,335
you cannot compare a field to null. This means that the following two statements will ALWAYS return false:

If A = Null Then

If A <> Null Then

Check the field for null by using the IsNull() function and then if it is not null, execute the case statement.
 

jaydwest

JayW
Local time
Today, 13:22
Joined
Apr 22, 2003
Messages
340
you can't use = null or is null with Select case. To get around this we use the NZ function, e.g.

Select Case NZ(Date, "Null)
Case "Null"

Case Else

End Select


Hope this helps.
 

Cosmos75

Registered User.
Local time
Today, 14:22
Joined
Apr 22, 2002
Messages
1,281
Pat Hartman,

Thank you for letting me know that!

jaydwest,

Never heard of the function NZ before! Will try to keep that in mind for the future!!

This sure has been quite a lesson for me!!
:D
 

Users who are viewing this thread

Top Bottom