需要帮助将vbs代码转换为jscript.我得到一个运行时错误类型不匹配

Need help converting vbs code to jscript. Im getting a Runtime Error Type Mismatch

本文关键字:一个 不匹配 类型 运行时错误 帮助 vbs 代码 jscript 转换      更新时间:2023-09-26

我有这个连接到我电脑上的实验设备。它使用特殊的OCX文件与设备通信(读取,设置参数等)。我从手册中得到了这个代码,似乎是有效的。我得到一个消息框说"放大率=1272.814最后一个错误=API未初始化"。

<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>

所以,因为我有0%的知识在vbs和大约10%的jscript我试图重写同样的东西在Javascript。我也有一些必要的代码已经写在js。

<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"'n Last error="+er);
Api1.ClosingControl(); 
</script>

不幸的是,我在.Get.GetLastError方法中获得var value; var er;var value=""; var er="";的类型不匹配错误

这是API手册中必须说的

long GetLastError(VARIANT* Error)

[out] Error是错误字符串与最后一个错误的错误代码相关联备注:此调用将返回与最后一个错误相关的VT_BSTR变体。返回值:如果调用成功,返回0。如果调用失败,则出现错误从函数返回代码。

long Get(LPCTSTR lpszParam, VARIANT* vValue)

[in] lpszParam是参数的名称,例如" AP_MAG "
[in][out] vValue是参数的值备注:本次调用将获取指定参数的值,并在vValue中返回。在c++中,在调用该函数之前,必须指定变体类型(vValue.vt)转换为VT_R4或VT_BSTR。如果没有定义变量类型对于vValue,模拟参数(AP_XXXX)默认为VT_R4数字参数VT_BSTR (DP_XXXX)。如果变体类型为VT_R4对于模拟参数,则浮点表示为在变体中返回。如果传递了VT_BSTR变体,则模拟返回的值是带有单位的缩放字符串(例如:AP_WD将返回" = 10mm ")。对于数字参数,VT_R4变体结果为状态号,而VT_BSTR变体将产生状态字符串(例如,DP_RUNUPSTATE将返回状态0或"Shutdown"或在所支持的语言中等效)。在c++中,如果是变量type被指定为VT_BSTR,那么API将在内部分配一个调用者必须使用SDK调用取消分配的BSTR:: SysFreeString (vValue.bstrVal)

欢迎来到StackOverflow!

嗯,每种语言都是有目的的。然后谈到在浏览器(或WSH)环境中处理ActiveX对象,VBScript是最好的选择,而JavaScript是最糟糕的选择。

JavaScript没有所谓的out参数。这意味着所有函数参数都是按值传递的(作为拷贝)。让我们用例子来说明。
' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8
Sub Foo(ByVal arg1, ByRef arg2)
    arg1 = 6
    arg2 = 8
    MsgBox "Local args: " & arg1 & ", " & arg2
End Sub

在VBS中默认参数是通过引用传递的,所以函数参数声明中的ByRef前缀是可选的。我把它包括在内是为了清楚。

这个例子说明了"by reference"或"out"参数的含义。它的行为类似于返回值,因为它修改了引用变量。而修改"按值"变量在函数作用域之外没有作用,因为我们修改了该变量的"副本"。

// JavaScript
function foo(arg1) {
    arg1 = 2;
    alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);
// Local var = 2
// Outer var = 0

现在看看这个线程。看起来有一种使用空对象的部分解决方案。我不确定在哪些情况下会起作用,但可以肯定的是,这是非常有限的hack。

如果这对你的情况没有帮助,那么看起来是时候使用VBScript了。从VBS开始是很容易的。这是我接触过的最友好的语言。我需要几天,甚至几周的时间才能开始使用其他语言,而只用了几个小时的VBS,我就可以自由地使用它了。

[编辑]嗯,我做了很多努力来回复,就像乍一看一样:)从你遇到的语言限制开始。之后我将解释这个限制的本质(什么是"in/out"参数),最好的方法是通过示例,这就是我所做的。之后,我将向您展示在JS中处理此限制的唯一解决方案。我们可以认为这是完整的答案吗?

你没有提到你是否测试了这个"空对象技巧",但正如你仍然问的那样,我假设你这样做了,它不适用于你的OCX,对吗?然后,在这种情况下,你只是被迫通过VBScript处理你的OCX,这是我从一开始的答案。如果你更喜欢使用JS,那么你需要在你的解决方案中集成一段VB代码。

正如你所指出的,这个VBs/Js集成是一个全新的问题。是的,这当然是一个好问题,但这是一个新的话题。

好,让我们说你在下面附加的问题:"为什么它应该工作与传递对象作为一个函数参数",仍然是主要问题的一部分。好吧,正如你所看到的,即使是每天使用JS的人(我不是其中之一)也不知道"引擎盖后面"发生了什么,也就是说,不要指望在这种情况下JS引擎做什么,或者这是如何欺骗JS引擎去做一些它不打算做的事情。就我个人而言,因为我很少使用JS,也不是为了这样的任务,我甚至不确定这个技巧是否有效。但是当js的人声称它是有效的(在某些情况下),那么我们就会相信他们。但这就是全部。如果这个方法失败了,那么它就不是一个选择。

现在剩下的是一点家庭作业,你需要研究所有可用的VBs/Js集成方法,也测试它们,看看哪一个最适用于你的领域,如果碰巧你遇到困难,就带着新的主题和你想要解决的具体问题回到论坛。

为了尽可能地帮助你,我将为你提供一些参考资料。

这是计划……

1。如果可以在没有VBs/Js集成的情况下工作,那么使用单独的。VBs文件(在WSH环境中),否则…

2。如果你在浏览器环境中工作(HTML或HTA),那么你可以嵌入两者(VBs/Js),你的集成将是简单的。

3。或者可能集成VBs/Js与Windows Script Files (.wsf)。

4。或者使用ScriptControl允许在JScript中运行VBScript(或反向/相反)。

链接:

  • 使用ScriptControl
  • 如何使用脚本控件调用函数
  • 一个使用ScriptControl的VBs/Js集成示例Batch-Embeded-Script

什么是批量嵌入脚本:

  • 根据/批处理混合
  • JS/批处理混合

5。其他方法(如果你发现,我不知道)

好吧,在所有这些改进之后,我看不出还有什么可以添加的,而且我认为,现在我的回答非常完整。如果你同意我的答案,然后接受它点击白色的大箭头。当然,如果您希望从其他用户那里得到更好的回复,您可能仍然需要等待,但请记住,未回答的问题只会保持活跃一段时间,然后就会关闭。

相关文章: