Hey, Scripting Guy! Question

Hey, Scripting Guy! In an HTA, how can I read the individual lines in a multi-line text box?

-- KM

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KM. You know, to be perfectly honest the Scripting Guy who writes this column has always had a grudging admiration for people who do totally ridiculous things and yet somehow manage to get away with them. For example, in the past couple weeks a large amount of the spam mail he has received has been exactly the same: it purports to be a “secret and confidential” message from the CEO of some company. These emails were obviously not intended for the Scripting Guy who writes this column; instead, the CEOs must have inadvertently addressed them to the Scripting Guy rather than their fellow inside traders. (We hate when that happens: you sit down to type kenmyer@fabrikam.com and you end up typing pilar.ackerman@contoso.org instead.)

As it turns out, these secret and confidential messages were all supposed to clue the CEOs’ cronies in on some incredible deals: thanks to a leveraged buyout/dramatic breakthrough/government contract the stock of some company no one has ever heard of is about to go through the roof. And now that you have this inside tip, all you need to do is buy the stock, sit back, and wait for the money to roll in. Thank goodness CEOs don’t know how to use email, eh?

Note. Interestingly enough, these CEOs all seem to have email names like way_2_cool_dude. But maybe if you’re the CEO of some major company you are a way too-cool dude.

The best part is that the company mentioned in the email is a real company and one whose stock is priced very low. We assume that the spammer must own a bunch of shares of this company’s stock, and is trying to entice as many people as he or she can to buy additional shares. In turn, that will drive the price up, at which point the spammer likely sells their shares and starts over again with another company. We don’t know for sure if that’s what’s going on; after all, maybe way_2_cool_dude really is the CEO of some company. But that sounds like a pretty good way to scam people. (Hmmm … wonder if anyone has patented that idea ….) Admittedly, it’s hard to believe that literally scores of CEOs would accidentally send you secret and confidential emails on the very same day. But, then again, if you’ve ever seen the people who run some of our major companies, well ….

At any rate, it all sounds ridiculous, but apparently it works, and works well.

Speaking of which, we Scripting Guys are well aware that there’s no way to read the individual lines in a multi-line text box. However – and please keep this under your hat, as it’s both secret and confidential – we happen to know of a way that can help you achieve the same effect. Just between us, you might want to consider stocking up on HTML Applications (HTAs); when word of this leaks out the number of people writing HTAs is going to go through the roof (which means you might want to buy stock in roofing companies while you’re at it):

<SCRIPT LANGUAGE="VBScript">

Sub TestSub
    strText = MyTextArea.Value
    arrLines = Split(strText, vbCrLf)
    For Each strLine in arrLines
        Msgbox strLine
    Next
End Sub

</SCRIPT>

<body>
    <textarea name="MyTextArea" rows=5 cols=70></textarea><p>
    <input type="button" value="Run Script" onClick="TestSub">
</body>

As you can see (and only you; remember, this is secret and confidential) this is an extremely simple HTA, consisting primarily of a multi-line text box named MyTextArea (technically, a multi-line text box is known as a text area) and a button labeled Run Script. The idea is that you type some information into the text area and then click the button; when the button is clicked it then runs a subroutine named TestSub. In turn, that subroutine reports back the value of each individual line in the text area.

By the way, here’s the HTML tagging that puts a text area (5 rows high by 70 columns wide) and a button in our HTA:

<textarea name="MyTextArea" rows=5 cols=70></textarea><p>
<input type="button" value="Run Script" onClick="TestSub">

What’s that? Well, you’re right: we did say that there was no way to read individual lines in a multi-line text box, didn’t we? And that’s true; there isn’t. Therefore, we’re going to cheat a little here. We’re assuming that after you type information into the text box you then press ENTER to go to the next line. In other words, you’re really typing in a list of information as opposed to a paragraph of information For example, maybe each line in your text box consists of a user name:

Ken Myer
Pilar Ackerman
Jonathan Haas

If that’s true, then we can separate the individual lines (that is, the individual user names) by using the following subroutine:

Sub TestSub
    strText = MyTextArea.Value
    arrLines = Split(strText, vbCrLf)
    For Each strLine in arrLines
        Msgbox strLine
    Next
End Sub

What we’re doing here is first grabbing all the text in the text box and stashing it in a variable named strText; that’s what this line of code is for:

strText = MyTextArea.Value

After we’ve done that we use the VBScript Split function to convert the data in strText to an array named arrLines:

arrLines = Split(strText, vbCrLf)

As you can see, we pass two parameters to the Split function: the value we want to convert to an array and the character we want to “split” on. (In other words, which character do we use to mark the end of one item in the array and then beginning of the next item?) Because we pressed the ENTER key after each line, we want to split on the carriage return-linefeed character, something we specify using the VBScript constant vbCrLf.

What will that do for us? That will give us an array named arrLines, consisting of the following items:

Ken Myer
Pilar Ackerman
Jonathan Haas

And you’re absolutely right: that’s an array in which each item represents an individual line in the text box.

At this point, of course, you can do anything you want with this information. Just for the sake of doing something we simply set up a For Each loop and echo back the value of each line in the text box:

For Each strLine in arrLines
    Msgbox strLine
Next

We’re assuming you’ll come up with a task that’s a little more interesting, and a little more useful.

Incidentally, you need the For Each loop only if you want to read every line in the text box. What if you wanted to read only, say, line 2? No problem. After all, each line is just an element in an array; to get the value of a specific line all we have to do is reference the appropriate index number. Because the first item in an array has the index number 0, that means the second item (the second line) has an index number of 1. This single line of code echoes back the value for the second line in the text box:

Msgbox arrLines(1)

Again, keep in mind that all this works only if you’ve pressed the ENTER key at the end of each line. Suppose you don’t do that, suppose you type in a paragraph that looks like this:

This is a paragraph typed into a text area. Instead of typing ENTER
at the end of each line we simply let the text wrap. That means there’s
really only one line in this text box.

If you run click the Run Script button the subroutine will simply echo back the entire paragraph; that’s because, as far as the subroutine is concerned, there’s only one line in the text box. Is it possible to somehow parse each line in the text box without using the ENTER key? Well, we can’t say with 100% certainty that it can’t be done. But for all practical purposes, no, it can’t be done.

Why not? Well, for one thing, suppose you had a text box that resized itself any time the HTA was resized. In that case the value of each “line” would change depending on the width of the text box. Of course, even in this case the vbCrLf trick would still work because we’re splitting on the carriage return-linefeed, regardless of how many lines appear to be in the text box.

Not a perfect solution by any means, but we hope it helps, KM. Meanwhile, now that people know how to read individual lines in a text area, well, the Scripting Guy who writes this column is going to just sit back and wait for the money to start rolling in.

Note. Well, no, he’s not exactly sure how he’s going to make money off this. Why, do you think he should have thought of that before writing the column and trying to pull off a scam like this one?