VBScript选项显式行顺序(与库相关)

时间:2018-04-18 14:41:01

标签: vbscript include option-explicit

我有一个相当大的VB脚本项目,其中主脚本“包含”了许多“库”,使用标准技巧来读取文件内容并在其上运行ExecuteGlobal。有些图书馆非常庞大,并且由各种第三方编写。

我想使用Option Explicit。但是,如果我把它作为执行的第一行,那么这些库中的一些就会爆炸。但是,如果我将指令移到我的包含列表下面,我会在该行上遇到错误Expected Statement。更令人困惑的是,如果Option Explicit出现在其中一个库的顶部(在它们列表的中间),一切都很好。但是,我想从任何库中删除(或注释掉),并且只在我的实现脚本中强制执行限制。

关于Option Explicit必须出现的规则是什么?它必须是第一行吗?当我通过“包含”应用它时,为什么它不是第一行呢?我怎样才能实现我的目标?

代码示例:

Option Explicit  ' CAUSES RUNTIME ERROR IN A LIBRARY

Sub Include( sRelativeFilePath )    
    Dim oFs : Set oFs = CreateObject("Scripting.FileSystemObject")
    Dim sThisFolder : sThisFolder = oFs.GetParentFolderName( WScript.ScriptFullName )
    Dim sAbsFilePath : sAbsFilePath = oFs.BuildPath( sThisFolder, sRelativeFilePath )
    ExecuteGlobal oFs.openTextFile( sAbsFilePath ).readAll()
End Sub
Include ".\SomeLib.vbs"
Include ".\SomeOther.vbs"
Include ".\YetAnother.vbs"

Vs的

Sub Include( sRelativeFilePath )    
    Dim oFs : Set oFs = CreateObject("Scripting.FileSystemObject")
    Dim sThisFolder : sThisFolder = oFs.GetParentFolderName( WScript.ScriptFullName )
    Dim sAbsFilePath : sAbsFilePath = oFs.BuildPath( sThisFolder, sRelativeFilePath )
    ExecuteGlobal oFs.openTextFile( sAbsFilePath ).readAll()
End Sub
Include ".\SomeLib.vbs"
Include ".\SomeOther.vbs"
Include ".\YetAnother.vbs"

Option Explicit  ' CAUSES COMPILATION ERROR 

1 个答案:

答案 0 :(得分:2)

#property indicator_chart_window double R, r3, r2, r1, p, s1, s2, s3; // SEMI-GLOBALs for easy runPriceCHECKs() //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { static int aLastVisitedBAR = EMPTY; // INIT if ( aLastVisitedBAR == iBars( _Symbol, PERIOD_D1 ) ) // TEST: { runPriceCHECKs(); // Check Price v/s PIVOT levels return( 0 ); // but PIVOTs never change during the same day ... so JIT/RET--^ } else aLastVisitedBAR == iBars( _Symbol, PERIOD_D1 ); // SYNC & RE-CALC: double rates[][6], yesterday_close, yesterday_high, yesterday_low; ArrayCopyRates( rates, _Symbol, PERIOD_D1 ); //---- if ( DayOfWeek() == 1 ) { if ( TimeDayOfWeek( iTime( _Symbol, PERIOD_D1, 1 ) ) == 5 ) { yesterday_close = rates[1][4]; yesterday_high = rates[1][3]; yesterday_low = rates[1][2]; } else { for ( int d = 5; d >= 0; d-- ) { if ( TimeDayOfWeek( iTime( _Symbol, PERIOD_D1, d ) ) == 5 ) { yesterday_close = rates[d][4]; yesterday_high = rates[d][3]; yesterday_low = rates[d][2]; } } } } else { yesterday_close = rates[1][4]; yesterday_high = rates[1][3]; yesterday_low = rates[1][2]; } //---- Calculate Pivots Comment( "\nYesterday quotations:\nH ", yesterday_high, "\nL ", yesterday_low, "\nC ", yesterday_close ); R = yesterday_high - yesterday_low; // a Day range p = ( yesterday_high + yesterday_low + yesterday_close ) /3;// a Standard Pivot r3 = p + ( R * 1.000 ); drawLine( r3, "R3", clrLime, 0 ); drawLabel( "Resistance 3", r3, clrLime ); r2 = p + ( R * 0.618 ); drawLine( r2, "R2", clrGreen, 0 ); drawLabel( "Resistance 2", r2, clrGreen ); r1 = p + ( R * 0.382 ); drawLine( r1, "R1", clrDarkGreen, 0 ); drawLabel( "Resistance 1", r1, clrDarkGreen ); drawLine( p, "PIVOT", clrBlue, 1 ); drawLabel( "Pivot level", p, clrBlue ); s1 = p - ( R * 0.382 ); drawLine( s1, "S1", clrMaroon, 0 ); drawLabel( "Support 1", s1, clrMaroon ); s2 = p - ( R * 0.618 ); drawLine( s2, "S2", clrCrimson, 0 ); drawLabel( "Support 2", s2, clrCrimson ); s3 = p - ( R * 1.000 ); drawLine( s3, "S3", clrRed, 0 ); drawLabel( "Support 3", s3, clrRed ); //---- runPriceCHECKs(); // Check Price v/s PIVOT levels //---- return( 0 ); } //+------------------------------------------------------------------+ //| drawLabel( string name, double lvl, color Color ) | //+------------------------------------------------------------------+ void drawLabel( string name, double lvl, color Color ) { if ( Bars < 10 ) return; if ( ObjectFind( name ) == 0 ) ObjectMove( name, 0, Time[10], lvl ); else { ObjectCreate( name, OBJ_TEXT, 0, Time[10], lvl ); ObjectSet( name, OBJPROP_COLOR, Color ); ObjectSetText( name, name, 8, "Arial", EMPTY ); } } //+------------------------------------------------------------------+ //| drawLine( double lvl, string name, color Col, int type ) | //+------------------------------------------------------------------+ void drawLine( double lvl, string name, color Col, int type ) { if ( ObjectFind( name ) == 0 ) ObjectDelete( name ); ObjectCreate( name, OBJ_HLINE, 0, Time[0], lvl, Time[0], lvl ); ObjectSet( name, OBJPROP_COLOR, Col ); ObjectSet( name, OBJPROP_WIDTH, 1 ); ObjectSet( name, OBJPROP_STYLE, ( type == 1 ) ? STYLE_SOLID : STYLE_DOT ); } //+------------------------------------------------------------------+ //| runPriceCHECKs() | //+------------------------------------------------------------------+ void runPriceCHECKs() { #define DEF_PROXIMITY_TRESHOLD_R3 ( 15 * Point ) #define DEF_PROXIMITY_TRESHOLD_R2 ( 10 * Point ) #define DEF_PROXIMITY_TRESHOLD_R1 ( 5 * Point ) #define DEF_PROXIMITY_TRESHOLD_P ( 2 * Point ) #define DEF_PROXIMITY_TRESHOLD_S1 ( 5 * Point ) #define DEF_PROXIMITY_TRESHOLD_S2 ( 10 * Point ) #define DEF_PROXIMITY_TRESHOLD_S3 ( 15 * Point ) if ( MathAbs( r3 - Close ) <= DEF_PROXIMITY_TRESHOLD_R3 ) ... PlaySound( aFileNAME_WAV_R3 ); // The file must be located in terminal_directory\Sounds or its sub-directory. Only WAV files are played. // Sleep( 250 ); // 250 [ms] AS A LAST RESORT, BETTER MAKE .WAV CUT-SHORT NOT TO LAST LONGER BY ITSELF // PlaySound( NULL ); return; if ( MathAbs( r2 - Close ) <= DEF_PROXIMITY_TRESHOLD_R2 ) ... return; if ( MathAbs( r1 - Close ) <= DEF_PROXIMITY_TRESHOLD_R1 ) ... return; if ( MathAbs( p - Close ) <= DEF_PROXIMITY_TRESHOLD_P ) ... return; if ( MathAbs( s1 - Close ) <= DEF_PROXIMITY_TRESHOLD_S1 ) ... return; if ( MathAbs( s2 - Close ) <= DEF_PROXIMITY_TRESHOLD_S2 ) ... return; if ( MathAbs( s3 - Close ) <= DEF_PROXIMITY_TRESHOLD_S3 ) ... return; // nop } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { return( 0 ); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- ObjectDelete( "S1" ); ObjectDelete( "S2" ); ObjectDelete( "S3" ); ObjectDelete( "R1" ); ObjectDelete( "R2" ); ObjectDelete( "R3" ); ObjectDelete( "PIVOT" ); ObjectDelete( "Support 1" ); ObjectDelete( "Support 2" ); ObjectDelete( "Support 3" ); ObjectDelete( "Piviot level" ); ObjectDelete( "Resistance 1" ); ObjectDelete( "Resistance 2" ); ObjectDelete( "Resistance 3" ); Comment( ":o)" ); //---- return( 0 ); } //+------------------------------------------------------------------+ 必须出现的规则是什么?是否必须是第一行?

the documentation

  

如果使用,Option Explicit语句必须在任何其他语句之前出现在脚本中。

当我通过“包含”应用它时,为什么它不是第一行呢?

好吧,正如你所说的,它并不是真的“包含”,你只是在运行时使用ExecuteGlobal加载文本并评估一个单独的脚本。它不是替换脚本中的库文本,而是加载并运行单独的脚本。

这个单独的脚本可以在其中包含Option Explicit作为第一个语句,因为它是单独运行的。

我如何实现目标?

为了与Option Explicit一起运行,您需要确保所有库都声明所有变量。如果您不愿意找到变量名称并修改库来声明它们,那么我认为您没有其他选择。

您可能只能让您的主要加载脚本脚本不使用Option Explicit,以及比您自己的库中使用Option Explicit更复杂的东西。希望您的主脚本足够简单,无需使用Option Explicit即可轻松调试。