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

时间:2013-03-07 07:40:52

标签: javascript vbscript compiler-errors type-mismatch

我已经将这个实验室设备连接到我的电脑上了。它使用特殊的OCX文件与设备通信(读取,设置参数等)。我从手册中得到了这个代码似乎正在运行。我收到一个消息框,上面写着“Magnification = 1272.814 Last error = API not initialized”。

<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>

因为我在vbs中有0%的知识,在jscript中有大约10%的知识,我试图在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手册的内容

  

长GetLastError(VARIANT *错误)

     
    

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

  
     

长期获取(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变体,则为analogue     值作为缩放字符串返回,并附加单位(例如     AP_WD将返回“= 10mm”)。对于数字参数,VT_R4变体     导致状态编号,VT_BSTR变体导致状态字符串     (例如,DP_RUNUPSTATE将返回状态0或“关闭”或     相当于支持的语言)。在C ++中,如果是变体     type被指定为VT_BSTR,然后API将在内部分配一个     调用者必须使用SDK调用取消分配的BSTR     :: SysFreeString(vValue.bstrVal)

  

1 个答案:

答案 0 :(得分:2)

欢迎使用StackOverflow!

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

JavaScript没有所谓的输出参数。这意味着所有函数参数都按值传递(作为副本)。让我们举例说明。

' 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前缀是可选的。为了清楚起见,我把它包括在内。

该示例说明的是“通过引用”或“输出”参数的含义。它的行为类似于返回值,因为它修改了引用的变量。虽然修改“按值”变量在函数范围之外没有任何影响,因为我们修改了该变量的“副本”。

// 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

现在看一下this thread。通过使用空对象看起来有一种局部解决方案。我不确定哪种情况会起作用,但肯定是非常有限的黑客攻击。

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

[编辑]好吧,我做了很多努力回复,看起来像是一眼就看:)从你遇到的语言限制开始。然后去解释这个限制的性质(什么是“进/出”参数),最好的方法是通过示例,这就是我所做的。之后,我向您展示了解决JS中此限制的唯一解决方法。我们可以将此视为完整答案吗?

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

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

好吧,让我们说下面附加的问题:“为什么它应该将对象作为函数参数传递”,仍然是主要问题的一部分。好吧,正如你所看到的,即使是每天使用JS的人(不是其中之一)也不知道“幕后”会发生什么,也就是说,不要期望在这种情况下JS引擎做什么,或者这个作弊JS引擎做了一些它不打算做的事情。就个人而言,由于我很少使用JS而不是这些任务,我甚至不确定这个技巧是否有效。但是,当JS-guys断言它有效(在某些情况下)时,我们会信任它们。但这就是全部。如果这种方法失败,那么它就不是一种选择。

现在剩下的是一些功课,你会研究所有可用的VBs / Js集成方法,也测试它们以查看哪一个最适用于你的域名,如果你偶然遇到困难,只需然后回到论坛,讨论新主题和你要解决的具体问题。

为了尽可能提供帮助,我将为您提供一些入门指南。

这是计划......

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

2. 如果您在浏览器环境(HTML或HTA)中工作,那么您可以嵌入(VBs / Js),并且您的集成将很简单。

3. 或者可以将VB / J与Windows Script Files (.wsf)集成。

4. 或者使用允许在JScript内(或向后/反向)运行VBScript的ScriptControl。

链接:

什么是Batch-Embeded-Script:

5. 其他一些方法(如果您发现,则不知道)。

嗯,经过所有这些改进之后,我看不出我能追加什么,而且正如我想的那样,现在 我的答案不仅仅是完整的。如果您同意我的回答,请点击白色大箭头接受它。当然,如果您希望其他用户得到更好的回复,您可能仍会等待,但请记住,未解决的问题会暂时保持活动状态,然后关闭。