【MQL5】FileWriteInteger関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. FileWriteInteger関数の働き・役割
  2. FileWriteInteger関数の引数について
  3. FileWriteInteger関数の戻り値について
  4. FileWriteInteger関数を使ったサンプルコード
  5. サンプルコード解説1:グローバル領域部分
    1. #property script_show_inputs
    2. input string InpSymbolName="EURUSD";
    3. input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1;
    4. input datetime InpDateStart=D'2013.01.01 00:00';
    5. input string InpFileName="Trend.bin";
    6. input string InpDirectoryName="Data";
  6. サンプルコード解説2:OnStart関数部分その1
    1. datetime date_finish=TimeCurrent();
    2. double close_buff[];
    3. datetime time_buff[];
    4. int size;
    5. ResetLastError();
  7. サンプルコード解説3:OnStart関数部分その2
    1. 終値データの取得
    2. エラーメッセージの表示
    3. 時間データの取得
    4. エラーメッセージの表示
  8. サンプルコード解説4:OnStart関数部分その3
    1. データのサイズを取得
    2. ファイルのオープン
  9. サンプルコード解説5:OnStart関数部分その4
    1. ファイルが正常に開けたか確認
    2. ファイルの書き込み確認
    3. トレンドフラグの初期化
    4. 配列サイズ変数の初期化
    5. 文字データを保存するための配列(uchar型)
  10. サンプルコード解説6:OnStart関数部分その5
    1. 終値データと時間データの比較
    2. トレンドの判定
    3. 上昇トレンドの処理
    4. 時間データの変換と格納
    5. 文字列の長さをファイルに書き込む
    6. 文字列データの書き込み
    7. トレンドフラグの更新
  11. サンプルコード解説7:OnStart関数部分その6
    1. 下降トレンドの判定
    2. 時間データの変換と格納
    3. 文字列の長さをファイルに書き込む
    4. 文字列データの書き込み
    5. トレンドフラグの更新
  12. サンプルコード解説8:OnStart関数部分その7
    1. ファイルのクローズ
    2. クローズ成功時のメッセージ出力
    3. ファイルが開けなかった場合のエラーメッセージ
    4. 処理の終了

FileWriteInteger関数の働き・役割

FileWriteInteger関数は、指定されたファイルのバイナリ形式で整数値を書き込むために使用されます。この関数は、ファイルポインタの現在位置からデータの書き込みを行います。バイナリファイルに対して整数を効率的に保存する際に有用です。例えば、データのシリアライズ(データを連続した形式に変換して保存や転送を容易にすること)や、トレンドの解析結果を保存する際などに活用されます。

ファイルハンドルを通じて、ファイルの書き込み位置や操作権限を管理しながら、指定されたバイト数で整数値を記録します。書き込む値のサイズは1~4バイトまで指定可能で、CHAR、SHORT、INTの形式で保存することができます。

FileWriteInteger関数の引数について

uint  FileWriteInteger(
  int  file_handle,        // ファイルハンドル
  int  value,              // 書かれる値
  int  size=INT_VALUE      // バイト単位でのサイズ
  );

FileWriteInteger関数は3つの引数を取ります。

file_handle
FileOpen関数によって返されるファイルハンドルを指定します。ファイル操作に必要な識別子であり、ファイルを開く際に取得します。

value
ファイルに書き込む整数値を指定します。バイナリ形式で保存されます。

size
書き込むデータのサイズをバイト単位で指定します。初期値はINT_VALUE(4バイト)で、1~4バイトのサイズを指定できます。

FileWriteInteger関数の戻り値について

FileWriteInteger関数戻り値は、正常に書き込まれたバイト数です。書き込まれたバイト数に応じて、ファイルポインタは自動的に移動します。もし書き込みに失敗した場合は、書き込みが行われなかったことを示すために0が返されます。

成功時の戻り値は書き込まれたバイト数であり、指定されたサイズ(1~4バイト)に応じた値が返されます。

FileWriteInteger関数を使ったサンプルコード

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs

//--- 端末からデータを受け取るパラメータ
input string             InpSymbolName="EURUSD";           // 通貨ペアのシンボル名を指定する。初期値は"EURUSD"
input ENUM_TIMEFRAMES    InpSymbolPeriod=PERIOD_H1;        // 時間軸を指定する。初期値は1時間足(H1)
input datetime           InpDateStart=D'2013.01.01 00:00'; // データのコピーを開始する日時を指定する。初期値は2013年1月1日 00:00

//--- データをファイルに書き込むためのパラメータ
input string             InpFileName="Trend.bin";          // ファイル名を指定する。初期値は"Trend.bin"
input string             InpDirectoryName="Data";          // ディレクトリ名を指定する。初期値は"Data"

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                  |
//+------------------------------------------------------------------+
void OnStart()
 {
  //--- 現在のサーバー時刻を取得する
  datetime date_finish=TimeCurrent();
  
  //--- 終値を保存するための配列を宣言する
  double close_buff[];
  
  //--- 時間データを保存するための配列を宣言する
  datetime time_buff[];
  
  //--- データのサイズを保存するための変数
  int size;
  
  //--- 最後のエラーコードをリセットする
  ResetLastError();
  
  //--- 指定した期間の終値データを取得し、配列に複製する
  if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
    {
    //--- 終値の取得に失敗した場合、エラーメッセージを表示し、スクリプトを終了する
    PrintFormat("終値データのコピーに失敗しました。エラーコード = %d",GetLastError());
    return;
    }
  
  //--- 指定した期間の時間データを取得し、配列に複製する
  if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
    {
    //--- 時間データの取得に失敗した場合、エラーメッセージを表示し、スクリプトを終了する
    PrintFormat("時間データのコピーに失敗しました。エラーコード = %d",GetLastError());
    return;
    }
  
  //--- 複製されたデータのサイズを取得する
  size=ArraySize(close_buff);
  
  //--- 値を書き込むためにファイルを開く(存在しない場合は新規作成される)
  ResetLastError();
  int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
  
  //--- ファイルが正常に開けたか確認する
  if(file_handle!=INVALID_HANDLE)
    {
    //--- ファイルが書き込み可能であることを通知する
    PrintFormat("%s ファイルは書き込み可能です",InpFileName);
    PrintFormat("ファイルのパス: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
    
    //--- トレンドフラグを初期化する(上昇:1、下降:-1、未定:0)
    int   up_down=0;
    
    //--- 文字列を保存するための配列サイズ変数
    int   arr_size;
    
    //--- 文字データを保存するための配列(uchar型)
    uchar arr[];
    
    //--- 終値データと時間データを順番に比較してトレンドをファイルに書き込む
    for(int i=0;i<size-1;i++)
       {
        //--- 現在のバーと次のバーの終値を比較してトレンドを判定
        if(close_buff[i]<=close_buff[i+1])
          {
          //--- 上昇トレンドの場合、トレンドフラグを1に設定し、時間データを書き込む
          if(up_down!=1)
             {
              //--- 時間データを文字列に変換し、配列に格納
              StringToCharArray(TimeToString(time_buff[i]),arr);
              arr_size=ArraySize(arr);
              
              //--- 文字列の長さを先にファイルに書き込む
              FileWriteInteger(file_handle,arr_size,INT_VALUE);
              
              //--- 文字列を1文字ずつファイルに書き込む
              for(int j=0;j<arr_size;j++)
                FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
              
              //--- トレンドフラグを上昇トレンドに設定
              up_down=1;
             }
          }
        else
          {
          //--- 下降トレンドの場合、トレンドフラグを-1に設定し、時間データを書き込む
          if(up_down!=-1)
             {
              //--- 時間データを文字列に変換し、配列に格納
              StringToCharArray(TimeToString(time_buff[i]),arr);
              arr_size=ArraySize(arr);
              
              //--- 文字列の長さを先にファイルに書き込む
              FileWriteInteger(file_handle,arr_size,INT_VALUE);
              
              //--- 文字列を1文字ずつファイルに書き込む
              for(int j=0;j<arr_size;j++)
                FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
              
              //--- トレンドフラグを下降トレンドに設定
              up_down=-1;
             }
          }
       }
    
    //--- ファイルを閉じる
    FileClose(file_handle);
    PrintFormat("データが書き込まれ、%s ファイルは閉じられました",InpFileName);
    }
  else
    {
    //--- ファイルが開けなかった場合、エラーメッセージを表示する
    PrintFormat("%s ファイルを開くことができませんでした。エラーコード = %d",InpFileName,GetLastError());
    }
 }

サンプルコード解説1:グローバル領域部分

//--- スクリプトの起動時に入力パラメータのウィンドウを表示する
#property script_show_inputs

//--- 端末からデータを受け取るパラメータ
input string             InpSymbolName="EURUSD";           // 通貨ペアのシンボル名を指定する。初期値は"EURUSD"
input ENUM_TIMEFRAMES    InpSymbolPeriod=PERIOD_H1;        // 時間軸を指定する。初期値は1時間足(H1)
input datetime           InpDateStart=D'2013.01.01 00:00'; // データのコピーを開始する日時を指定する。初期値は2013年1月1日 00:00

//--- データをファイルに書き込むためのパラメータ
input string             InpFileName="Trend.bin";          // ファイル名を指定する。初期値は"Trend.bin"
input string             InpDirectoryName="Data";          // ディレクトリ名を指定する。初期値は"Data"

このセクションでは、スクリプトのグローバル領域部分について解説します。この領域では、スクリプトの設定やユーザー入力パラメータを定義し、スクリプトの動作に必要な情報を指定しています。

#property script_show_inputs

このディレクティブは、スクリプトの実行時に入力パラメータウィンドウを表示するためのものです。スクリプトが実行されると、ユーザーがカスタマイズできる入力パラメータがウィンドウに表示され、実行前に調整可能となります。

input string InpSymbolName="EURUSD";

この部分は、通貨ペアのシンボル(特定の文字や記号)を指定するための入力パラメータを定義しています。
inputキーワードは、ユーザーが実行前に変更できるパラメータであることを示しています。ここでは、初期値として “EURUSD” が設定されています。このパラメータを使って、どの通貨ペアのデータを処理するかを指定します。

input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1;

この部分は、時間軸を指定するための入力パラメータを定義しています。
ENUM_TIMEFRAMESは時間軸を定義するための列挙型で、PERIOD_H1は1時間足(H1)を表しています。ユーザーが異なる時間軸(例:5分足、日足など)を指定することで、分析の範囲を変更することができます。

input datetime InpDateStart=D'2013.01.01 00:00';

この部分は、データのコピーを開始する日時を指定するための入力パラメータです。
dateTime型は日付と時刻を表します。ここでは、初期値として “2013年1月1日 00:00” が設定されています。ユーザーは、このパラメータを変更することで、データ取得を開始する日付を設定できます。

input string InpFileName="Trend.bin";

この部分は、データを保存するファイルの名前を指定するための入力パラメータです。
初期値として “Trend.bin” というファイル名が設定されています。このファイルには、トレンドデータがバイナリ形式で書き込まれます。ユーザーはファイル名を変更することが可能です。

input string InpDirectoryName="Data";

この部分は、データを書き込むディレクトリの名前を指定するための入力パラメータです。
初期値として “Data” というディレクトリ名が指定されています。スクリプトは、このディレクトリ内にファイルを作成し、データを書き込みます。ディレクトリ名もユーザーが変更することができます。

このグローバル領域では、ユーザーがスクリプトの動作をカスタマイズするためのパラメータが定義されており、これらのパラメータはスクリプトの主要な処理において使用されます。

サンプルコード解説2:OnStart関数部分その1

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                  |
//+------------------------------------------------------------------+
void OnStart()
 {
  //--- 現在のサーバー時刻を取得する
  datetime date_finish=TimeCurrent();
  
  //--- 終値を保存するための配列を宣言する
  double close_buff[];
  
  //--- 時間データを保存するための配列を宣言する
  datetime time_buff[];
  
  //--- データのサイズを保存するための変数
  int size;
  
  //--- 最後のエラーコードをリセットする
  ResetLastError();

このセクションでは、スクリプトの主要な処理が行われる OnStart関数の冒頭部分について解説します。OnStart関数は、スクリプトが実行された際に自動的に呼び出され、データの処理やファイル操作を行います。

datetime date_finish=TimeCurrent();

TimeCurrent関数を使用して、サーバー時間を取得しています。この時刻は、データの取得範囲を決定する際に使用され、変数 date_finish に格納されます。例えば、過去のデータから現在までの終値をコピーする際、この時刻を終端とします。

double close_buff[];

終値データを保存するための配列を宣言しています。close_buff はCopyClose関数によって、指定された時間軸における終値データを格納するために使用されます。この配列に、指定した通貨ペアの終値が時系列順に保存され、後にファイルに書き込むための準備が整えられます。

datetime time_buff[];

時間データを保存するための配列を宣言しています。time_buff はCopyTime関数によって、終値に対応する時間データを保存するために使用されます。終値データだけでなく、それが記録された時間情報も同時に処理され、これにより、ファイルには時刻と価格の両方が保存されます。

int size;

データのサイズを格納するための変数 です。終値や時間データを保存する際、配列要素数が必要になるため、そのサイズをこの変数 size に格納します。この後の処理で、配列要素を正しく操作するために使用されます。

ResetLastError();

ResetLastError関数は、最後に発生したエラーコードをリセットする関数です。スクリプト実行中にエラーが発生した場合、そのエラーコードを取得できますが、この関数でリセットすることで、新たなエラーが発生した際に確実に検出できるようにします。これにより、エラー処理が正しく行われ、トラブルシューティングが容易になります。

この部分では、終値と時間データの取得準備が行われており、これからスクリプトがデータをコピーして処理を進める準備段階が整えられます。次のセクションで実際のデータ取得やファイル操作の解説が続きます。

サンプルコード解説3:OnStart関数部分その2

  
  //--- 指定した期間の終値データを取得し、配列に複製する
  if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
    {
    //--- 終値の取得に失敗した場合、エラーメッセージを表示し、スクリプトを終了する
    PrintFormat("終値データのコピーに失敗しました。エラーコード = %d",GetLastError());
    return;
    }
  
  //--- 指定した期間の時間データを取得し、配列に複製する
  if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
    {
    //--- 時間データの取得に失敗した場合、エラーメッセージを表示し、スクリプトを終了する
    PrintFormat("時間データのコピーに失敗しました。エラーコード = %d",GetLastError());
    return;
    }

OnStart関数の中で、終値データと時間データを取得する処理部分を解説します。この処理では、指定した通貨ペアと時間軸に基づいて、過去のデータをコピーし、配列に保存します。

終値データの取得

CopyClose関数を使って指定した通貨ペアと時間軸の終値データを取得し、close_buffという配列にコピーします。

  • InpSymbolName は通貨ペアのシンボル(例:EURUSD)を示します。
  • InpSymbolPeriod は時間軸(例:1時間足)を示します。
  • InpDateStart から date_finish までの期間のデータが取得されます。

データの取得に失敗すると、CopyClose関数は-1を返し、その際にはエラーメッセージが表示され、スクリプトが終了します。

エラーメッセージの表示

終値データのコピーに失敗した場合、PrintFormat関数でエラーコードを含むメッセージを出力し、どのエラーが発生したのか確認できるようにします。GetLastError関数によって、直近のエラーコードが取得されます。

時間データの取得

CopyTime関数を使用して、終値に対応する時間データを取得し、time_buffという配列にコピーします。CopyClose関数と同様に、通貨ペア、時間軸、取得期間を指定しています。

時間データは、取得した終値データと対応するもので、各終値がいつのものであるかを正確に記録します。

エラーメッセージの表示

時間データのコピーに失敗した場合も、エラーメッセージが表示されます。エラーメッセージにはエラーコードが含まれており、データ取得に失敗した原因を特定するための手助けになります。

この部分では、終値データと対応する時間データを配列に保存する処理が行われています。データ取得が成功すれば、次の段階でそれらのデータを処理・保存する準備が整います。

サンプルコード解説4:OnStart関数部分その3

 //--- 複製されたデータのサイズを取得する
  size=ArraySize(close_buff);
  
  //--- 値を書き込むためにファイルを開く(存在しない場合は新規作成される)
  ResetLastError();
  int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);

ここでは、OnStart関数内でデータのサイズを取得し、ファイルを開く処理について解説します。この処理では、取得したデータの配列サイズを確認し、データを書き込むためのファイル操作を開始します。

データのサイズを取得

ArraySize関数を使って、終値データが格納された配列 close_buff の要素数を取得し、変数 size に格納します。これにより、データの処理に必要なサイズが取得され、後続のループ処理などで配列を正しく扱うことができます。配列要素数は、取得した終値データのバー数に対応します。

ファイルのオープン

ファイル操作の前に、ResetLastError関数を使用して最後のエラーをリセットしています。これにより、直近のエラーコードが消去され、新たなエラーが発生した場合に正しく処理できるようにします。

その後、FileOpen関数を使って、データを書き込むためのファイルを開きます。指定されたディレクトリ(InpDirectoryName)内にファイル(InpFileName)が存在しない場合は、新規作成されます。

ファイルは読み書き可能(FILE_READ|FILE_WRITE)なバイナリファイルとして開かれます。file_handle 変数 には、ファイルのハンドル(識別子)が格納され、このハンドルを使用してファイルに対する操作を行います。

サンプルコード解説5:OnStart関数部分その4

  //--- ファイルが正常に開けたか確認する
  if(file_handle!=INVALID_HANDLE)
    {
    //--- ファイルが書き込み可能であることを通知する
    PrintFormat("%s ファイルは書き込み可能です",InpFileName);
    PrintFormat("ファイルのパス: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
    
    //--- トレンドフラグを初期化する(上昇:1、下降:-1、未定:0)
    int   up_down=0;
    
    //--- 文字列を保存するための配列サイズ変数
    int   arr_size;
    
    //--- 文字データを保存するための配列(uchar型)
    uchar arr[];

このセクションでは、ファイルを開いた後の処理について解説します。ここでは、ファイルが正常に開かれたかを確認し、書き込むデータを準備するための変数配列の初期化を行います。

ファイルが正常に開けたか確認

file_handle に格納されたファイルハンドルINVALID_HANDLEでないことを確認することで、ファイルが正常に開かれたかどうかを判断します。INVALID_HANDLE は、ファイルを開く際に失敗した場合に返される特殊な値です。

ファイルの書き込み確認

ファイルが正常に開かれた場合、PrintFormat関数を使って、指定したファイルが書き込み可能であることを通知します。また、TerminalInfoString関数を使用して、ファイルが保存されているディレクトリのパスを出力します。これにより、ファイル操作が行われる場所をユーザーが確認できます。

トレンドフラグの初期化

up_down 変数 は、トレンド(価格の変動方向)を表すために使用されます。この変数 は以下の3つの値を持ちます。

  • 1: 上昇トレンドを表す
  • -1: 下降トレンドを表す
  • 0: まだトレンドが決まっていない状態を表す

トレンドフラグを初期化することで、後続のデータ処理でトレンドの変動を追跡し、必要に応じてデータを書き込む準備を整えます。

配列サイズ変数の初期化

arr_size 変数 は、文字データを保存するための配列のサイズを格納するために使用されます。この変数 は、文字列をファイルに書き込む際、文字数を正確に管理するために必要です。

文字データを保存するための配列(uchar型)

arr という名前の配列は、uchar型(unsigned char: 符号なしの1バイト整数型)で宣言されています。この配列は、時間データやトレンドフラグなどをバイナリ形式で保存する際に使用されます。文字列データや数値データをバイト単位で扱うために、この型が適用されており、ファイルに効率的に書き込むことができます。

ここまでで、ファイルが正常に開かれ、トレンドデータを保存するための準備が整いました。次に、データを書き込む具体的な処理が進行します。

サンプルコード解説6:OnStart関数部分その5

//--- 終値データと時間データを順番に比較してトレンドをファイルに書き込む
    for(int i=0;i<size-1;i++)
       {
        //--- 現在のバーと次のバーの終値を比較してトレンドを判定
        if(close_buff[i]<=close_buff[i+1])
          {
          //--- 上昇トレンドの場合、トレンドフラグを1に設定し、時間データを書き込む
          if(up_down!=1)
             {
              //--- 時間データを文字列に変換し、配列に格納
              StringToCharArray(TimeToString(time_buff[i]),arr);
              arr_size=ArraySize(arr);
              
              //--- 文字列の長さを先にファイルに書き込む
              FileWriteInteger(file_handle,arr_size,INT_VALUE);
              
              //--- 文字列を1文字ずつファイルに書き込む
              for(int j=0;j<arr_size;j++)
                FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
              
              //--- トレンドフラグを上昇トレンドに設定
              up_down=1;
             }
          }

このセクションでは、OnStart関数内で終値データと時間データを順に比較し、トレンドをファイルに書き込む処理について解説します。終値の変動に応じてトレンドを判定し、データをバイナリ形式でファイルに記録します。

終値データと時間データの比較

for文を使って、配列の各要素を順に処理し、現在のバー(ローソク足)の終値と次のバーの終値を比較しています。size-1 までの範囲でループすることで、終値データの最後の要素まで処理を行います。

トレンドの判定

if文を使用して、現在のバーの終値が次のバーの終値以下かどうかを確認します。終値が次の終値よりも小さい、または等しい場合、価格が上昇していると判断されます。この条件を満たすと、次にトレンドフラグを確認します。

上昇トレンドの処理

up_down 変数 が1でない場合、上昇トレンドに変更するための処理が行われます。トレンドフラグを変更する前に、時間データをファイルに書き込む準備をします。

時間データの変換と格納

TimeToString関数を使って、時間データを文字列に変換し、StringToCharArray関数を使ってその文字列をバイナリデータ形式に変換します。このバイナリデータを uchar型配列arr に格納し、配列のサイズを arr_size 変数 に保存します。

文字列の長さをファイルに書き込む

FileWriteInteger関数を使って、まず文字列の長さ(配列のサイズ)をファイルに書き込みます。これにより、後でファイルを読み取る際に、文字列の長さが判別できるようになります。

文字列データの書き込み

for文を使用して、文字列データを1文字ずつファイルに書き込んでいきます。FileWriteInteger関数を使用して、各文字データをバイナリ形式でファイルに保存します。

トレンドフラグの更新

すべてのデータが書き込まれた後、up_down 変数を1に設定して、現在のトレンドが上昇トレンドであることを示します。これにより、同じトレンドが続いている限り、この処理が再度実行されることはありません。

ここまでで、上昇トレンドが検出された場合の処理が完了しました。次に、下降トレンドの場合の処理やその他のファイル操作が続きます。

サンプルコード解説7:OnStart関数部分その6

 else
          {
          //--- 下降トレンドの場合、トレンドフラグを-1に設定し、時間データを書き込む
          if(up_down!=-1)
             {
              //--- 時間データを文字列に変換し、配列に格納
              StringToCharArray(TimeToString(time_buff[i]),arr);
              arr_size=ArraySize(arr);
              
              //--- 文字列の長さを先にファイルに書き込む
              FileWriteInteger(file_handle,arr_size,INT_VALUE);
              
              //--- 文字列を1文字ずつファイルに書き込む
              for(int j=0;j<arr_size;j++)
                FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
              
              //--- トレンドフラグを下降トレンドに設定
              up_down=-1;
             }
          }
       }

ここでは、終値データを比較した結果、下降トレンドと判断された場合の処理について解説します。上昇トレンドの場合と同様に、終値データの変化に基づいて時間データをファイルに書き込み、トレンドフラグを変更します。

下降トレンドの判定

else文で、上昇トレンドでない場合の処理が行われます。if文で up_down 変数-1 でないことを確認し、下降トレンドに移行するかどうかを判定します。下降トレンドに移行する条件が整った場合、時間データの書き込み処理が行われます。

時間データの変換と格納

TimeToString関数を使用して、現在の時間データを文字列に変換し、それをStringToCharArray関数でバイナリデータに変換します。この変換されたデータは、uchar型配列arr に格納され、配列のサイズを arr_size に保存します。

文字列の長さをファイルに書き込む

FileWriteInteger関数を使用して、変換した文字列の長さ(配列のサイズ)をファイルに書き込みます。これにより、ファイルの読み取り時に、文字列データの長さが分かるようになります。

文字列データの書き込み

for文を使用して、文字列データをバイナリ形式で1文字ずつファイルに書き込みます。FileWriteInteger関数によって、配列内の各文字が順番にファイルに保存されます。

トレンドフラグの更新

データの書き込みが完了した後、up_down 変数-1 に設定して、現在のトレンドが下降トレンドであることを示します。これにより、同じ下降トレンドが続く限り、再度この処理が実行されることを防ぎます。

ここまでで、下降トレンドが検出された場合の処理が完了しました。これにより、トレンドの変化に応じて適切に時間データがファイルに書き込まれ、トレンドフラグが更新されます。次は、ファイルを閉じる処理が行われます。

サンプルコード解説8:OnStart関数部分その7

 //--- ファイルを閉じる
    FileClose(file_handle);
    PrintFormat("データが書き込まれ、%s ファイルは閉じられました",InpFileName);
    }
  else
    {
    //--- ファイルが開けなかった場合、エラーメッセージを表示する
    PrintFormat("%s ファイルを開くことができませんでした。エラーコード = %d",InpFileName,GetLastError());
    }
 }

このセクションでは、OnStart関数の最後に行われるファイルのクローズ処理と、エラーメッセージの出力について解説します。ファイル操作が完了した後、必ずファイルを閉じることでデータが正しく保存され、エラーが発生した場合にはその原因を表示します。

ファイルのクローズ

FileClose関数を使用して、ファイルを閉じます。file_handleに指定されたファイルハンドル引数として渡すことで、開いているファイルが閉じられ、これまでに書き込まれたデータが保存されます。ファイルを閉じることにより、他のプロセスやスクリプトでファイルを操作する際の競合を防ぐことができます。

クローズ成功時のメッセージ出力

PrintFormat関数を使用して、ファイルが正しく閉じられたことを通知します。ここでは、ファイル名(InpFileName)を含むメッセージを出力し、どのファイルにデータが書き込まれたのかがわかるようにしています。これにより、ユーザーはデータ保存が完了したことを確認できます。

ファイルが開けなかった場合のエラーメッセージ

elseブロックでは、ファイルが開けなかった場合にエラーメッセージを表示します。PrintFormat関数を使用して、エラーコードを含むメッセージを出力します。GetLastError関数によって、直近のエラーコードを取得し、その内容に基づいて問題を特定することができます。

このエラーメッセージは、ファイル操作が正しく行われなかった場合に原因を追跡するために役立ちます。たとえば、ファイルのパスが間違っている、またはファイルシステムに問題がある場合などが考えられます。

処理の終了

これでOnStart関数のすべての処理が完了し、スクリプトの実行も終了します。ファイルの書き込みが成功したかどうかに関わらず、適切にファイルを閉じる、またはエラーメッセージを表示することで、スクリプトの動作が確実に管理されています。

タイトルとURLをコピーしました