1

Following this question, I'm trying to convert the VBScript code on this page to JScript. If I runt the below .hta code:

<HTML>
<BODY>
    <INPUT id=button1 name=button1 type=button value=Button>
    <SCRIPT LANGUAGE="VBScript">
        sub button1_onclick()
            dim app
            set app = createobject("Excel.Application")
            app.Visible = true
            dim wb
            set wb = app.workbooks.add
            end sub
    </SCRIPT>
</BODY>
</HTML>

It opens an empty Excel sheet upon clicking on the button. as expected. However, if I convert the VBScript part to JScript

<HTML>
<BODY>
    <INPUT id=button1 name=button1 type=button value=Button>
    <script LANGUAGE="JScript">
        function button1_onclick() {
            // var app = WScript.CreateObject("Excel.Application");
            var app = new ActiveXObject("Excel.Application");
            app.Visible = true;
            var wb = app.Workbooks.Add();
        }
    </script>
</BODY>
</HTML>

it doesn't open Excel at all when clicking the button. I would appreciate it if you could help me know what is the problem and how I can resolve it. Thanks for your support in advance.

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • 3
    `button1_onclick` function is never run. You need to attach an event listener to the input element, ``, and change the function name to `openExcel` to avoid conflicts between element `id`s and global variables/functions. – Teemu Dec 02 '20 at 05:48
  • Thanks @Teemu , have you tested this? because I did try it last night and it didn't work either. – Foad S. Farimani Dec 02 '20 at 08:31
  • 2
    Yes, I have. If it still doesn't work for you, that's maybe because of the multiple languages used. If you've VBS and JS on the same page, you might need to point the correct language in the onclick attribute, like so: ``. Your actual code in the event handler works as it is. – Teemu Dec 02 '20 at 08:33
  • @Teemu No, I don't think that was the problem. I had commented the VBScript part out. I will test again tonight and will let you know here. thanks for your kind support. – Foad S. Farimani Dec 02 '20 at 08:47
  • 2
    If you can't get it to work (check with an alert that the function is run), it might be something similar to [this question](https://stackoverflow.com/q/65103877/1169519), unfortunately I don't know the answer to that. Similar code to your's has been working in my HTA apps for a decade, even with the newest Office Excel. – Teemu Dec 02 '20 at 09:02
  • 2
    A remediation to my second comment: "_If you've VBS and JS on the same page ..._" It's not just the code for the click event, it's any VBS on the page. – Teemu Dec 02 '20 at 09:16
  • 1
    Also, the line commented out `WScript.CreateObject` will never work in an HTA because it doesn’t have access to the Windows Scripting Host. This is because MSHTA is it’s own host that supports Active Scripting languages. The caveat to this is you can still use some WScript libraries that are accessible through COM like `WScript.Shell` etc. – user692942 Dec 02 '20 at 09:26
  • 1
    @Teemu figured the issue out. I was using the `onclick=""` while I should have used `onclick="()"`. See those parentheses apprantly matter. – Foad S. Farimani Dec 02 '20 at 20:43
  • 1
    I can imagine it's hard to move from VBS to JS, all gotchas are on the way ... – Teemu Dec 02 '20 at 20:48
  • @Teemu well, actually I have zero experience with both. I rather learn the latter though. The issue is that there is much more documentation for VBScript than classic JScript. – Foad S. Farimani Dec 02 '20 at 20:51
  • Actually, I think you'll find you stumbled on that from the answer I have provided. @Teemu suggested including the event handler but my answer showed you how. – user692942 Dec 03 '20 at 01:24
  • Also @Teemu the use of the language selection moniker in event handlers is inaccurate, it's been peddled so much now it's hard to separate fact from fiction. The sole purpose of language monikers like `vbscript:` and `javascript:` [are to bind functions directly from the `href` attribute](https://stackoverflow.com/questions/27253420/calling-vbscript-function-from-button-input-type#comment42982492_27253420). See [Why do you see colons while calling a javascript function in html sometimes?](https://stackoverflow.com/a/14605294/692942). – user692942 Dec 03 '20 at 01:28
  • @Lankymart Years ago (probably era of IE9), I answered a question (could have been in comments only) where OP said an inline eventlistener didn't run. I made some tests at that time, and I can remember that the issue was reproducible. The language first occurring in a file somehow "hijacked" the inline listeners, and "the language selection moniker" did solve that problem. I'd recall the event in the question was an onchange event of a select element. Unfortunately I couldn't find that post anymore, I even tried to find such a comment with a SEDE-query, but to no avail. – Teemu Dec 03 '20 at 07:02
  • @Teemu that maybe a weird IE thing but language selection monikers where primarily designed to support launching code from a `href` any other usage is coincidental. – user692942 Dec 03 '20 at 08:56
  • Using `onclick` element attribute to bind events is a poor approach anyway, the correct approach is to match the event syntax for JScript which in this case would be `function button1::onclick()`. – user692942 Dec 03 '20 at 09:42
  • @Lankymart Isn't that syntax only for ActiveX events? I mean if we had an instance of IE as an ActiveX, then that would work. But now we have a DOM event, not an ActiveX event ..? – Teemu Dec 03 '20 at 14:00
  • 1
    @Teemu not just for ActiveX controls, it's for JScript event binding as well. Go try it, both examples in my answer have been tested. To be clear the event binding comes from the Script Engine not from ActiveX. See [AutoMagic](https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/ms974564(v=msdn.10)?redirectedfrom=MSDN#automagic) - *"The good thing about this mechanism is you can use it to respond to ActiveX Control events."*. – user692942 Dec 03 '20 at 14:37
  • 1
    @Lankymart I don't know what to say ... I've been working with HTAs for more than 15 years (mostly hobby-based, though), and I didn't know about the DOM event binding the Script engine can do. Thanks a lot for all this, every day is really for learning. – Teemu Dec 03 '20 at 15:02
  • 1
    @Teemu I've been dipping out of VBScript and JScript for more years than I care to mention and still feel I'm learning new things. Sometimes, it's just so much time has passed that I'm refreshing what I once knew. – user692942 Dec 03 '20 at 15:13

1 Answers1

1

Why doesn't Object_Event syntax work?

It's actually very simple Object_Event syntax is VBScript, to allow events to automatically bind in JScript you just need to use the correct syntax which is Object::Event, here is an example using automatically bound events.

<html>
<body>
    <input id="button1" name="button1" type="button" value="Button">
    <script language="JScript">
        function button1::onclick() {
            var app = new ActiveXObject("Excel.Application");
            app.Visible = true;
            var wb = app.Workbooks.Add();
        }
    </script>
</body>
</html>

Just tested this and it seems to be working, so it may just be you are missing the onclick event handler as @Teemu suggests in the comments.

<html>
<body>
    <input id="button1" name="button1" type="button" value="Button" onclick="return button1_onclick();">
    <script language="JScript">
        function button1_onclick() {
            var app = new ActiveXObject("Excel.Application");
            app.Visible = true;
            var wb = app.Workbooks.Add();
        }
    </script>
</body>
</html>

The only real difference is the inclusion of the onclick event handler on the <input> element.

onclick="return button1_onclick();"

It displays a button which when clicked opens Microsoft Excel with a new Workbook.


Useful Links

user692942
  • 16,398
  • 7
  • 76
  • 175