2018年10月18日木曜日

[MQL4] GetLastError() は2度呼んではいけない

MQL4 では直前の関数が失敗した場合、[GetLastError()](https://docs.mql4.com/check/getlasterror) を使ってエラーコードを取得することが出来ます。

しかし、この関数を連続して呼び出すと値が変わってしまうので要注意です。


### 2度目は値が0
具体的には以下のように、2度目の呼び出しでは値が 0 になってしまいますなお、4108 は "Invalid Ticket"。

```mq4
if (!OrderModify(ticket, price, stoploss, takeprofit, expiration)) {
    printf("GetLastError1 %d", GetLastError());
    printf("GetLastError2 %d", GetLastError());
}

// 結果
// GetLastError1 4108
// GetLastError2 0
```

こんなあからさまに2度呼ぶことは無いと思うのですが、後述の `ErrorDescription()` を使う場合など、うっかり書いてしまうことはありそうです。


### GetLastError() は必ず変数で受けてから使う
対策としては、エラー発生直後に必ず変数で受けるよう習慣づけるのが一番かと思います。

```mq4
if (!OrderModify(ticket, price, stoploss, takeprofit, expiration)) {
    int error = GetLastError();
    printf("GetLastError1 %d", error);
    printf("GetLastError2 %d", error);
}    

// 結果
// GetLastError1 4108
// GetLastError2 4108
```


### エラーコードをエラーメッセージに変換する方法
このエラーコード、[Trade Server Return Codes](https://docs.mql4.com/constants/errorswarnings/enum_trade_return_codes) に一覧があると思いきや、この表には一部のコードしか載っていません4108 も載っていない。

これではエラーの原因がわからないので、これを文字列に変換する標準ライブラリが用意されています。

> 参考
>
> [[MQL4] GetLastError() で取得したエラーコードをエラーメッセージに変換する方法](https://strategyofc.blogspot.com/2018/10/mql4-getlasterror.html)

2018/10/19 追記
「一部のコードしか載っていません」と書いたのですが、[Runtime Errors](https://docs.mql4.com/constants/errorswarnings/errorcodes) の方には 4000番台のエラーも載っていましたどこかで見た気はしていた。 [Trade Server Return Codes](https://docs.mql4.com/constants/errorswarnings/enum_trade_return_codes) は [Runtime Errors](https://docs.mql4.com/constants/errorswarnings/errorcodes) から若い番号のものを抜粋した表のようです。
[OrderModify()](https://docs.mql4.com/trading/ordermodify) 等は 4000番台のエラーも返すのに、リンクされているドキュメントが不十分というのは不親切だなぁ。