HTA TutorialHTA Tutorial #11

I left you last time with a little task. How did you get on? It should look a little like the following:

<HTML>
<BODY>
<HEAD>
<title>Save</title>
<HTA:APPLICATION>

<Script Language=VBS>

sub subRead()   
dim fs
dim a

Const ForReading = 1
  
	Set fs = CreateObject("Scripting.FileSystemObject")
	If (fs.FileExists("hello.txt")) Then
		Set a = fs.OpenTextFile("hello.txt", ForReading)
		msgbox(a.ReadLine)
		a.Close
	Else
    		msg = "file" & " doesn't exist."
		msgbox(msg)
	End If
	end sub

sub subCreate()
	dim b
	dim fs

	Set fs = CreateObject("Scripting.FileSystemObject")     
	If (fs.FileExists("hello.txt")) Then
    		msg = "file" & " exists."
		msgbox(msg)
	Else
		Set b = fs.CreateTextFile("hello.txt", True)
		b.WriteLine("Hello")
		b.Close
	End If
end sub
</SCRIPT>
</HEAD>
<body scroll="no">
<INPUT TYPE="Submit" ID="btnQuit" VALUE="Quit" onclick=self.close()>
<INPUT TYPE="Submit" ID="btnRead" VALUE="Read" onclick=subRead()>
<INPUT TYPE="Submit" ID="btnCreate" VALUE="Create" onclick=subCreate()>
</BODY>
</HTML>

If there are any experienced programmers reading this then they will be hopping up and down, complaining that what I've done is a bit long winded and could be simplified using a function to test whether a file exists and save on duplication of code. Well, quite right and well spotted!! However, I'm trying to keep this as simple as possible without taking too many steps at once so I'm sure we'll get around to that in later tutorials. The above however is perfectly acceptable and does the job. How did you test it by the way? You should first delete the file created and check that the Read button can be pressed without causing an error. Then press Create and then Read to check that the file has been created without error. Finally, pressing Create should produce a message saying that the file already exists. Does your program do all that? Well done!! If not, well don't be too disheartened just remember to test it thoroughly with all the permutations next time.

Now as promised last time, here is some code to append to a file.

<HTML>
<BODY>
<HEAD>
<title>Append</title>
<HTA:APPLICATION>

<Script Language=VBS>

sub subAppend()
dim b
dim fs

const ForAppending = 8

	Set fs = CreateObject("Scripting.FileSystemObject")     
	Set b = fs.OpenTextFile("hello.txt", ForAppending)
	b.WriteLine("Hello " & now)
	b.Close
end sub
</SCRIPT>
</HEAD>
<body scroll="no">
<INPUT TYPE="Submit" ID="btnQuit" VALUE="Quit App" onclick=self.close()>
<INPUT TYPE="Submit" ID="Append" VALUE="Append" onclick=subAppend()>
</BODY>
</HTML>

The only real difference is that the code for appending is 8 which is assigned to a different variable (makes it easier to integrate with larger programs as above). I am also appending the string hello with the date and time (using the now command) so you can see a bit more clearly what is happening.

Reading back the data isn't quite so straight forward. The previous example would only take the first line from the file and there are more than that. Indeed, it isn't actually known how many lines there are in the file which makes setting a loop value difficult. Luckily, all we need do is read the number of lines until the end of file is reached which again the file system object can help us with. Here's the code:

<HTML>
<BODY>
<HEAD>
<title>Append</title>
<HTA:APPLICATION>

<Script Language=VBS>

sub subReadAll()
dim fs
dim a
	Set fs = CreateObject("Scripting.FileSystemObject")     
	Set a = fs.OpenTextFile("hello.txt")
	Do While a.AtEndOfStream <> True
		retstring = a.ReadLine
		msgbox(retstring)
	Loop
	a.Close
end sub

</SCRIPT>
</HEAD>
<body scroll="no">
<INPUT TYPE="Submit" ID="btnQuit" VALUE="Quit App" onclick=self.close()>
<INPUT TYPE="Submit" ID="btnReadAll" VALUE="Read All" onclick=subReadAll()
</BODY>
</HTML>

We'll concentrate on the subroutine doing all the work:

sub subReadAll()
dim fs
dim a
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile("hello.txt")

The routine is started and all the object variables are set. Now there comes a loop.

Do While a.AtEndOfStream <> True

The loop starts and will continue until we reach the end of the file (or stream as it is called) and the AtEndOfStream is true until the end has been reached when it becomes false and the loop stops.

retstring = a.ReadLine
msgbox(retstring)

We then read the string and display it in a message box. Luckily, the object routines will keep track of where we are in the file.

Loop
a.Close
end sub

The loop then ends and the file is closed. That's it. We are almost at the stage when you can takea look at the phone.hta that I have supplied. However, there may be one more thing that give you a few problems and I'll go into that next time. In the meantime, keep experimenting and trying to create your own applications because ultimately you'll only learn from experience. Good luck.

Back

Written by Nick Cheesman. Last updated: 01/04/2004
Please email
nickjc@nickjc.co.uk if you need help