我有一个相当大的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
答案 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 );
}
//+------------------------------------------------------------------+
必须出现的规则是什么?是否必须是第一行?如果使用,Option Explicit语句必须在任何其他语句之前出现在脚本中。
好吧,正如你所说的,它并不是真的“包含”,你只是在运行时使用ExecuteGlobal加载文本并评估一个单独的脚本。它不是替换脚本中的库文本,而是加载并运行单独的脚本。
这个单独的脚本可以在其中包含Option Explicit
作为第一个语句,因为它是单独运行的。
为了与Option Explicit
一起运行,您需要确保所有库都声明所有变量。如果您不愿意找到变量名称并修改库来声明它们,那么我认为您没有其他选择。
您可能只能让您的主要加载脚本脚本不使用Option Explicit,以及比您自己的库中使用Option Explicit更复杂的东西。希望您的主脚本足够简单,无需使用Option Explicit即可轻松调试。