Hey, Scripting Guy! Question

Hey, Scripting Guy! I read your column about the HTA that could load and then display all the files in a folder. That was pretty useful, but I had an idea to make it even better. When looking at a log file I often see portions of the log that I’d like to copy and save to a separate text file. Is there any way to highlight text in an HTA and then append just the highlighted text to another file?

-- KF

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KF. Well, today is Friday, February 8th, which means that the 2008 Winter Scripting Games are just one week away. As exciting as that is to most of us, however, we realize that some people aren’t interested in the Scripting Games. (Now, now; remember, it takes all kinds to make a world.) Therefore, we thought we’d talk about something different today.

So let’s see, what can we talk about? Well, politics are definitely in the news these says, especially here in the US. And as far as the Scripting Guys are concerned, Americans would be far better off if – well, never mind. Microsoft doesn’t really like us to talk about politics. (Actually Microsoft doesn’t really like the Scripting Guys to talk about anything. But that’s a different story.)

So what else? Well, there’s always religion, although, come to think of it, we’re not supposed to talk about religion, either.

True story. In a recent magazine article, we weren’t even allowed to say the word “devil.” Which was a bit of a problem seeing as how we had just returned from the Devil’s Punch Bowl and were dying to have some deviled eggs and a piece of Devil’s food cake. Needless to say, that also played havoc with our proposed tribute column to everyone’s favorite hockey player, Miroslav Satan.

Anyway, religion is out. Sports? Well, to tell you the truth, the Scripting Guy who writes this column is going through a bit of a dry spell as far as his favorite teams are concerned; none of them are doing very well at the moment. (Well, the New Jersey Devils and the Arizona State Sun Devils are doing all right, but we can’t talk about them.) In other words, he doesn’t want to talk about sports. OK, then how about the weather? Well, today in Seattle it’s cold and rainy; tomorrow is also supposed to be cold and rainy. And the day after that is also supposed to be cold and rainy. And – well, let’s not talk about the weather, either. OK?

In fact, why don’t we dispense with the small talk and just show you code for an HTML Application (HTA) that allows you to select text in a textarea and then append the selected information to a text file:

<SCRIPT Language="VBScript">    
Sub Window_Onload        
strComputer = "."        
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")        
Set colFiles = objWMIService.ExecQuery _            
("ASSOCIATORS OF {Win32_Directory.Name='C:\Scripts'} Where " _                
& "ResultClass = CIM_DataFile")       
 For Each objFile In colFiles            
Set objOption = Document.createElement("OPTION")            
objOption.Text = objFile.FileName            
objOption.Value = objFile.Name           
LogFiles.Add(objOption)        
Next    
End Sub    
Sub ReadFile        
Set objFSO = CreateObject("Scripting.FileSystemObject")        
Set objFile = objFSO.OpenTextFile(LogFiles.Value)       
 strContents = objFile.ReadAll        
objFile.Close        
BasicTextArea.Value = strContents    
End Sub        
Sub SaveSelection        
Set objSelection = Document.Selection.CreateRange()        
Set objFSO = CreateObject("Scripting.FileSystemObject")        
Set objFile = objFSO.OpenTextFile(FileNameBox.Value, 8)        
objFile.WriteLine        
objFile.WriteLine (LogFiles.Value)        
objFile.WriteLine objSelection.Text        
objFile.Close    End Sub</SCRIPT>
<body>    
<table width="100%">        
<tr>            
<td width="25%" valign="top">               
<select size="35" name="LogFiles" onChange="ReadFile" style="width:150px">                    
</select>            
</td>           
<td width="75%" valign="top">               
<textarea name="BasicTextArea" rows="35" cols="100"></textarea>           
</td>        
</tr>        
<tr>            
<td width="25%" valign="top">               
File name: <input type="text" size="25" name="FileNameBox" value="C:\Scripts\Test.txt">             
</td>           
<td width="75%" valign="top">               
<br><input type="button" value="Append Data" onClick="SaveSelection">          
</td>        
</tr>    
</table></body>

Wow, that is quite a bit of code, at least for a Hey, Scripting Guy! column. But don’t worry; we aren’t going to walk through each and every line today. Instead, we’ll refer you to our previous column to explain how the HTA loads all the files in a folder into a list box, then displays the contents of any file you select from that list box. All we’ll talk about today is the code that we added to our original HTA, code that enables you to select text in the HTA’s textarea, then append that selection to a separate text file.

With that in mind, let’s start by taking a look at the all-new second row in our table. (The first row in the table contains the list box and the textarea.) Here’s the HTML tagging for row 2 in the table:

<tr>    
<td width="25%" valign="top">        
File name: <input type="text" size="25" name="FileNameBox" value="C:\Scripts\Test.txt">    
 </td>    
<td width="75%" valign="top">        
<br>
<input type="button" value="Append Data" onClick="SaveSelection">    
</td>
</tr>

In the first cell in this table we’re adding a text box named FileNameBox, and setting the default value of this text box to C:\Scripts\Test.txt. That’s what this little bit of HTML is for:

<input type="text" size="25" name="FileNameBox" value="C:\Scripts\Test.txt">

Why did we add a text box here? Well, this gives us a place where we can type the path to the file where the selected text is supposed to be added. We give it a default value of C:\Scripts\Test.txt because we’re assuming that this is the file where we typically want to append information. However, it’s easy enough to redirect that data to a different file; all we have to do is type a different file path in our text box.

In the second cell in the row we use the following HTML tagging to add a button labeled Append Data:

<input type="button" value="Append Data" onClick="SaveSelection">

As you can see, each time the button is clicked the script runs a subroutine named SaveSelection. Now, try to guess what’s going to happen when the SaveSelection subroutine runs?

Oh, well, you’re right: we are going to save the selected text to a text file. We thought we might be able to stump you with that particular question. Apparently we were wrong.

Well, even though you already know what the SaveSelection subroutine does, let’s take a moment to talk about how it does this. The first thing we do inside this subroutine is create a new TextRange object; that’s done by calling the CreateRange() method, which happens to be part of the Document.Selection object:

Set objSelection = Document.Selection.CreateRange()

After creating the TextRange object (which automatically encompasses all the selected text in the HTA) we use these two lines of code to create an instance of the Scripting.FileSystemObject and then open a text file for appending (that’s what the second parameter, the 8, is for):

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(FileNameBox.Value, 8)

What’s that? Which text file are we opening? Why, we’re opening the file whose path is listed in the FileNameBox text box; as you might have guessed, the syntax FileNameBox.Value returns the text found in the FileNameBox text box.

So what are we going to do with that file now that it’s open? Well, to begin with, we’re going to use this line of code to add a blank line to the end of the file:

objFile.WriteLine

Once that’s done we’re going to use this block of code to write the name of the file that the selection comes from (grabbing the file path from the list box) followed by the selected text, something we can get at by referencing the Text property of our TextRange object:

objFile.WriteLine (LogFiles.Value)
objFile.WriteLine objSelection.Text

And then we close the file and simply wait for the user to select some more text and then click the Append Data button. That’s all we have to do.

We hope that answers your question, KF. In the meantime … wow, there just really isn’t anything to talk about other than the Scripting Games, is there? So what the heck, let’s just mention that the Games begin February 15th and run through March 3rd. However, you’ll want to show up on the 15th if at all possible: although the Games run through March 3rd most of the events will end before March 3rd. (For example, the deadline for Events 1 and 2 is Wednesday, February 20th. Check here for a full schedule, including a printable calendar.)

But even if you can’t make the deadlines for all the events, well, that doesn’t mean you can’t participate: just do whatever events you have time for and call it good. You’ll have fun and you’ll have a chance to put your scripting skills to the test (and maybe learn something new along the way). Equally important, by entering just one event you’ll be eligible for great Scripting Games prizes. And remember, you don’t have to use your real name when playing. (Surely you didn’t think someone really named their kid N3QGO or weedwhacker?) Try a script, send it in using a nickname like weedwhacker (well, maybe not weedwhacker; that’s already taken), and who knows? You just might win one of those great prizes.

Now, aren’t you glad we had this little talk?

Note. Now that you mention it, the Scripting Editor did leave a few doughnut crumbs in the office, didn’t she? But that’s no big deal, we’ll just get out our trusty little Dirt Devil vacuum and – well, never mind. We’ll just ask the janitor to take care of it.