I’m in a good mood today, which makes two days in a row that I haven’t just sat around grousing and complaining (a new personal record!). But that’s because baseball season has officially started: we drafted our team last Thursday, the weather’s been nice, and we’ve already had a couple of practices. We have a really great group of kids to work with, and I think we might end up being a pretty good team. And that’s not just a case of, “Oh, every coach says that about his team.” In fact, after our first practice last year, I remember saying — to myself — “Ohmigosh; we’re not gonna win a game all year!” (As it turned out, we ended up going 19-14, pretty good for a team with only one 14-year-old in a league dominated by 14-year-olds). This year – well, it’ll be interesting to see how it all plays out. If we get the pitching we expect to get, we should be OK.

 

Incidentally, the name of our team is White Swan, which is apparently some sort of car-detailing place (I never heard of it, but, then, again I’m largely oblivious to the rest of the world). White Swan is an OK name, I guess. When I was in Little League, I played for Plumbers and Steamfitters Local 409 (kind of rolls off the tongue, doesn’t it?). But it could have been worse: I could have played for Mueller’s Funeral Home. Mueller’s is a very reputable place and it’s great that they support youth baseball, but, still …. With names like Plumbers and Steamfitters Local 409 and Mueller’s Funeral Home, it probably shouldn’t come as any great surprise that back then teams were never referred to by name, but instead by the color of their hats. (Oh, wow, the red hats are playing the green hats today. That should be a good game.”)

 

Funny thing about me: when I’m in a good mood, I’m lazy; I actually work better and harder when I’m in a bad mood. So, yeah, I didn’t post anything yesterday. And I didn’t really have anything to post today either when, through divine intervention or something, I got back-to-back emails from people with a similar problem. They had both written scripts that required users to enter dates, and they were having problems with people who entered dates using the incorrect format. Why, they lamented, didn’t VBScript have some sort of date picker built in?

 

To tell you the truth, I’ve always marveled at how well VBScript handled dates. For example, consider this very simple script, which asks you to enter a date and then extracts and reports the day of the month that you entered:

 

strDate = InputBox("Enter a date:")

Wscript.Echo Day(strDate)

 

What’s cool about this is that it’s almost impossible not to enter a date that VBScript can’t handle; for example, I can enter any of these, and the correct day will be reported:

 

3/3/2003

3-3-2004

March 3, 2004

3-March-2004

3, 3, 2004

 

All in all, pretty slick. Still, I can see where having a built-in date picker could be useful. For one thing, sometimes you don’t actually know the date; you just know that the day you wanted was two weeks ago last Thursday. In a case like that, having a date picker, some kind of calendar that you can just click (as opposed to typing in a date) would be pretty handy. Likewise, any time you enter a date, your computer’s ability to interpret the date you entered depends on your language and regional options. For example, although this is a valid date format in some parts of the world, using this in the above script causes an error on my US English version of Windows:

 

3.3.2004

 

Allowing someone to pick a date from a calendar would help prevent errors that can occur when someone uses an unrecognized date format. But how the heck do you do that? After all, VBScript doesn’t have a built-in date picker, and the odds are pretty good it never will.

 

But, hey, all is not lost; one alternative is to use the Microsoft Calendar Control, which ships with Microsoft Office. (It probably ships with other Microsoft software as well; I don’t keep very good track of that sort of thing.) The Calendar Control (Mscal.ocx) is an ActiveX control, which means you can:

 

  1. Embed the control in an HTML file.
  2. Use a script to display the HTML file.
  3. Allow the user to click a date on the control.
  4. From your script, determine the date the user clicked on.

 

All in all, pretty easy. If you want a nice little graphical date picker, start by creating an HTML file that includes Calendar Control. Here’s an example of a simple date picker page. (Note. Something crazy is going on with the HTML here, and it was causing the rest of the post to display in a really bizarre fashion. And when I tried directly editing the HTML of the page, it would let me do so, and then it would just reset my HTML to its weird HTML. As a temporary fix, I'm using {} instead of the usual HTML brackets. I'll get this fixed as soon as I can.)

 

{HTML}
{HEAD}
{TITLE}Date Picker{/TITLE}

{/HEAD}

{SCRIPT language="VBScript"}
{!--
Sub OKButton_OnClick
OkClicked.Value = 1
End Sub
'--}
{/SCRIPT}

{BODY bgcolor="buttonface"}

{p align="center"}

{OBJECT CLASSID="clsid:8E27C92B-1264-101C-8A2F-040224009C02"
id=Calendar1}
{param name="BackColor" value="-2147483633"}
{param name="DayLength" value="1"}
{param name="MonthLength" value="1"}
{param name="DayFontColor" value="0"}
{param name="FirstDay" value="7"}
{param name="GridCellEffect" value="1"}
{param name="GridFontColor" value="10485760"}
{param name="GridLinesColor" value="-2147483632"}
{param name="ShowDateSelectors" value="-1"}
{param name="ShowDays" value="-1"}
{param name="ShowHorizontalGrid" value="-1"}
{param name="ShowTitle" value="-1"}
{param name="ShowVerticalGrid" value="-1"}
{param name="TitleFontColor" value="10485760"}
{param name="ValueIsNull" value="0"}
{/OBJECT}

{br}
{INPUT NAME="OKButton" TYPE="BUTTON" VALUE="OK" }
{input type="hidden" name="OKClicked" size="20"}{/P}
{/BODY}
{/HTML}


This page consists primarily of three items:

 

  • An Object tag. This specifies the class ID for the Calendar Control (clsid:8E27C92B-1264-101C-8A2F-040224009C02) and gives the control a name (Calendar1).
  • A hidden field (named OKClicked). After the user selects a date, he or she clicks the OK button; in turn this sets the value of the hidden field OKClicked to 1. Why? Well, in the script that calls this HTML page, we want to make sure that the calendar is displayed until the user has made a selection and clicks OK. As you’ll see, the way we do that is to put the script in loop, waiting until the value of OKClicked has changed. When OKClicked changes value, that’s the signal to break out of the loop, grab the value from the Calendar Control, and continue with the rest of the script.

    Are there other, better ways to do this? Well, it wouldn’t surprise me. This is the way I Iearned how to display an HTML page and read values from it; if you know a better way, by all means do that instead. (I think it’s safe to say that just because I do something that’s not necessarily reason enough for you to do the same thing.)
  • An OK button. This simply sets the value of OKClicked and then triggers a chain reaction that causes our script to get the date the user picked and then dismiss the HTML page.

 

Note. I included a bunch of the Calendar Control options in the script, just so you could get an idea of how you can customize the look and feel on the control. If you’d like more information on what you can do with the Calendar Control, you might check out this article on MSDN.

 

In addition to the HTML page (which I cleverly named Calendar.htm), we need a VBScript script that opens Calendar.htm and grabs the date picked by the user. Here’s a script that does just that:

 

Set objExplorer = CreateObject _

("InternetExplorer.Application")

objExplorer.Navigate "file:///C:\scripts\calendar.htm"

objExplorer.ToolBar = 0

objExplorer.StatusBar = 0

objExplorer.Width=400

objExplorer.Height = 300

objExplorer.Visible = 1

Do While (objExplorer.Document.Body.All.OKClicked.Value = "")

Wscript.Sleep 250

Loop

strPassword = objExplorer.Document.Body.All.Calendar1.Value

objExplorer.Quit

Wscript.Sleep 250

Wscript.Echo strPassword

 

Again, this is really pretty straightforward. We create an instance of Internet Explorer, and then use the Navigate method to open the file C:\Scripts\Calendar.htm. We configure the UI (for example, hiding the toolbar and the status bar), and make our Web page visible. We then go into a loop, checking every quarter of a second (250 milliseconds) to see if OKClicked has changed in value.

 

As soon as OKClicked changes in value (and the only way that can happen is if the user clicks the OK button), we grab the date selected in the Calendar Control, and dismiss our instance of Internet Explorer. Because I’m lazy, all I do at that point is echo the date that was chosen; needless to say, you could do something a bit more interesting than just echo the chosen date. For example, you could add in a function that transforms the date into a UTC date, and then pass that date to a WMI query that, say, searches for files created on that particular day. Pretty cool, and a lot better than asking people (including yourself) to type in a UTC date like 03032004******.000000-480.

 

Hey, a graphical date picker you can use in a script; man, no wonder I’m in such a good mood!