DoEasy. 控件 (第 32 部分): 水平滚动条,鼠标轮滚动·进阶篇
(2/3)· 从箭头按钮到滑块拖拽与滚轮响应,补齐 WinForms 滚动条的交互闭环
◍ 动态数组与字符串的运行时报错码
在 MT5 的 MQL5 运行时层,数组和字符串相关的错误码从 4006 开始连续编排,调试 EA 时若日志抛出这类数字,基本能直接定位到内存或类型误用。
- 指向动态数组三宗罪:类型不对、尺寸不匹配、或对象已损坏;4007 则是重分配内存不足,或者你试图改一个静态数组的大小——后者在编译期不报错,运行期才崩。
- 与 4009 专门管字符串:前者是重分配字符串内存不够,后者是用了没初始化的字符串。4010 起开始卡边界,日期时间非法返回 4010,而数组总元素数硬上限是 2147483647(约 21.47 亿),超了就 4011。
指针类错误收尾:4012 是错指针,4013 是错类型指针。外汇与贵金属杠杆高、波动剧烈,这类底层错误在高频重算指标时可能集中爆发,建议开 MT5 用 GetLastError() 逐码验证。
{
"Массив неподходящего типа, неподходящего размера или испорченный объект динамического массива",
"Array of a wrong type, wrong size, or a damaged object of a dynamic array"
},
{
"Недостаточно памяти для перераспределения массива либо попытка изменения размера статического массива",
"Not enough memory for the relocation of an array, or an attempt to change the size of a class="kw">static array"
},
{"Недостаточно памяти для перераспределения строки","Not enough memory for relocation of class="type">class="kw">string"},
{"Неинициализированная строка","Not initialized class="type">class="kw">string"},
{"Неправильное значение даты и/или времени","Invalid date and/or time"},
{"Общее число элементов в массиве не может превышать class="num">2147483647","Total amount of elements in array cannot exceed class="num">2147483647"},
{"Ошибочный указатель","Wrong pointer"},
{"Ошибочный тип указателя","Wrong type of pointer"}「EA 报错码 4014 到 4023 的实盘含义」
在 MT5 写 EA 或指标时,编译器报的系统错误码往往直接决定你能否顺利加载到图表。下面这组错误码覆盖 4014–4023,是资源调用、数学计算和回测中断三类高发问题。
- 表示禁止调用的系统函数,常见于在指标里调了只允许 EA 使用的接口;4015 是动态与静态资源重名,编译器无法区分。4016 指 EX5 内找不到该名称的资源文件,多半是 bmp 或 wav 没打包进编译器。
- 限制很硬:不支持的资源类型,或单文件超过 16 MB 直接拒载;4018 则是资源名超 63 字符被截断报错。4019 是数学函数溢出,比如 pow() 传了极端值。
- 值得注意——在回测中调 Sleep() 后若越过测试结束日,会触发该码并终止片段。4021 是未知错误占位,4022 代表外部强停(优化中断、关掉可视化窗口或测试代理挂掉),4023 为类型不匹配。
开 MT5 随便写个带 #resource 的脚本,故意把资源名写到 64 字符,编译就能复现 4018,比看文档直观。
{"Системная функция не разрешена для вызова","Function not allowed for call"}, class=class="str">"cmt">// class="num">4014
{"Совпадение имени динамического и статического ресурсов","Names of dynamic and class="kw">static resource match"}, class=class="str">"cmt">// class="num">4015
{"Ресурс с таким именем в EX5 не найден","Resource with this name not found in EX5"}, class=class="str">"cmt">// class="num">4016
{"Неподдерживаемый тип ресурса или размер более class="num">16 MB","Unsupported resource type or its size exceeds class="num">16 Mb"}, class=class="str">"cmt">// class="num">4017
{"Имя ресурса превышает class="num">63 символа","Resource name exceeds class="num">63 characters"}, class=class="str">"cmt">// class="num">4018
{"При вычислении математической функции произошло переполнение ","Overflow occurred when calculating math function "}, class=class="str">"cmt">// class="num">4019
{"Выход за дату окончания тестирования после вызова Sleep()","Out of test end date after calling Sleep()"}, class=class="str">"cmt">// class="num">4020
{"Неизвестный код ошибки (class="num">4021)","Unknown error code(class="num">4021)"}, class=class="str">"cmt">// class="num">4021
{
"Тестирование было прекращено принудительно извне. Например, прервана оптимизацию, или закрыто окно визуального тестирования, или остановлен агент тестирования",
"Test forcibly stopped from the outside. For example, optimization interrupted, visual testing window closed or testing agent stopped"}, class=class="str">"cmt">// class="num">4022
{"Неподходящий тип","Invalid type"}, class=class="str">"cmt">// class="num">4023运行时错误码的双语映射表
在 MT5 的 EA 或脚本里做错误自检时,直接把错误码打印成英文往往不够友好。把码号对应到母语和国际化双语文本,是本地化诊断信息的常见做法。 上面这段声明了一个二维字符串数组 messages_runtime_sqlite,第二维 TOTAL_LANG 存放两种语言:索引 0 为俄文(用户国别语言),索引 1 为英文(国际语言)。错误域覆盖 5601 到 5626,专用于 SQLite 数据库操作相关的运行时错误。 例如 5601 对应「Общая ошибка / Generic error」,5603 对应「Отказано в доступе / Access denied」。你在开 MT5 写数据库模块时,可以直接复制这个映射结构,用 GetLastError() 拿到码号后做数组下标偏移读取,避免硬编码字符串。 外汇与贵金属交易接入本地数据库做信号缓存时属高风险操作,错误未捕获可能导致订单逻辑中断,建议先于策略测试器验证错误分支。
class="type">class="kw">string messages_runtime_sqlite[][TOTAL_LANG]= { {"Общая ошибка","Generic error"}, class=class="str">"cmt">// class="num">5601 {"Внутренняя логическая ошибка в SQLite","SQLite internal logic error"}, class=class="str">"cmt">// class="num">5602 {"Отказано в доступе","Access denied"}, class=class="str">"cmt">// class="num">5603 {"Процедура обратного вызова запросила прерывание","Callback routine requested abort"}, class=class="str">"cmt">// class="num">5604
◍ SQLite 底层报错码映射片段
在 MT5 的数据库接口封装里,错误码与提示文本通常以成对字符串数组形式硬编码,方便 EA 在调用 DatabaseOpen / DatabaseExecute 失败时直接定位问题。下面这段映射覆盖了 5605 至 5614 共 10 个 SQLite 相关返回码。
- 对应数据库文件被锁,多发生在多实例同时写同一文件时;5606 是表级锁冲突;5607 并非逻辑错误,而是 malloc 分配失败,实盘跑高频写入 EA 时若内存吃紧会触发。
- 到 5614 则偏向存储层故障:只读库写操作、interrupt 中断、磁盘 IO 错、镜像损坏、未知 file_control 码、库满插入失败、文件无法打开。外汇与贵金属策略若依赖本地库缓存 tick,这类错可能让回测与实盘状态不一致,属于高风险隐患。
开 MT5 后可在 MetaEditor 全局搜 5610 或 Disk I/O error,确认你用的标准库是否含此映射,缺了就自己补进错误分发函数。
{"Файл базы данных заблокирован","Database file locked"}, class=class="str">"cmt">// class="num">5605
{"Таблица в базе данных заблокирована ","Database table locked"}, class=class="str">"cmt">// class="num">5606
{"Сбой malloc()","Insufficient memory for completing operation"}, class=class="str">"cmt">// class="num">5607
{"Попытка записи в базу данных, доступной только для чтения ","Attempt to write to readonly database"}, class=class="str">"cmt">// class="num">5608
{"Операция прекращена с помощью sqlite3_interrupt() ","Operation terminated by sqlite3_interrupt()"}, class=class="str">"cmt">// class="num">5609
{"Ошибка дискового ввода-вывода","Disk I/O error"}, class=class="str">"cmt">// class="num">5610
{"Образ диска базы данных испорчен","Database disk image corrupted"}, class=class="str">"cmt">// class="num">5611
{"Неизвестный код операции в sqlite3_file_control()","Unknown operation code in sqlite3_file_control()"}, class=class="str">"cmt">// class="num">5612
{"Ошибка вставки, так как база данных заполнена ","Insertion failed because database is full"}, class=class="str">"cmt">// class="num">5613
{"Невозможно открыть файл базы данных","Unable to open the database file"} class=class="str">"cmt">// class="num">5614「数据库与授权类的错误码映射」
在 MT5 的 MQL5 程序里,数据库相关报错常以 5615 起编的整型码回传,下面这段结构体数组就是俄文原提示与英文提示的直接映射,便于你在 EA 日志里做双语定位。 代码里 5615 对应「Database lock protocol error」,说明多实例抢锁时协议层出错;5618 的「String or BLOB exceeds size limit」提醒单条记录的大小上限被突破,写缓存前需先估算字节数。
- 的「Authorization denied」常见于用到了宿主不支持的 OS 特性(5622)后被终端拒绝授权,这类错误在跨平台迁移脚本时概率较高,建议在 DatabaseOpen 之后立即用 GetLastError 捕获区间 5615–5623。
{"Ошибка протокола блокировки базы данных ","Database lock protocol error"}, class=class="str">"cmt">// class="num">5615
{"Только для внутреннего использования","Internal use only"}, class=class="str">"cmt">// class="num">5616
{"Схема базы данных изменена","Database schema changed"}, class=class="str">"cmt">// class="num">5617
{"Строка или BLOB превышает ограничение по размеру","String or BLOB exceeds size limit"}, class=class="str">"cmt">// class="num">5618
{"Прервано из-за нарушения ограничения","Abort due to constraint violation"}, class=class="str">"cmt">// class="num">5619
{"Несоответствие типов данных","Data type mismatch"}, class=class="str">"cmt">// class="num">5620
{"Ошибка неправильного использования библиотеки","Library used incorrectly"}, class=class="str">"cmt">// class="num">5621
{"Использование функций операционной системы, не поддерживаемых на хосте","Uses OS features not supported on host"}, class=class="str">"cmt">// class="num">5622
{"Отказано в авторизации","Authorization denied"}, class=class="str">"cmt">// class="num">5623数据库与矩阵向量运行期报错码对照
在 MT5 自建指标或 EA 里直接调 SQLite 与矩阵运算时,运行期报错不会给你中文提示,而是吐出内部错误码。下面这段二维字符串数组就是标准错误文案的双语映射,第一列俄语、第二列英语,索引注释里的数字才是你该记的码。 比如 5625 对应 sqlite3_bind 的索引越界:绑定参数序号超出了预处理语句实际的问号数量,常见于循环绑参时少写了一次 prepare。5626 则是打开的文件根本不是 SQLite 库文件,多半是路径拼错或把 csv 当 db 塞进去了。 矩阵和向量相关的错误从 5700 起跳。5701 是对象没初始化就参与运算,5702 是两个矩阵维度对不上,5703 和 5704 分别是尺寸和类型非法。外汇与贵金属行情高频推送下做矩阵计算,这类错误可能瞬间拖垮 OnTick,建议在调用前用 ArrayIsInitialized 和矩阵 Size 做断言。 把下面数组原样贴进 mq5,配合 GetLastError 转文案,比盯着终端裸码调试快得多。
{"Не используется ","Not used "}, class=class="str">"cmt">// class="num">5624
{"class="num">2-й параметр для sqlite3_bind находится вне диапазона","Bind parameter error, incorrect index"}, class=class="str">"cmt">// class="num">5625
{"Открытый файл не является файлом базы данных","File opened that is not database file"}, class=class="str">"cmt">// class="num">5626
};
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Array of execution time error messages(class="num">5700 - class="num">5706) |
class=class="str">"cmt">//| (Matrix and vector methods) |
class=class="str">"cmt">//| (class="num">1) in user&class="macro">#x27;s country language |
class=class="str">"cmt">//| (class="num">2) in the international language |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">string messages_runtime_matrix_vector[][TOTAL_LANG]=
{
{"Внутренняя ошибка исполняющей подсистемы матриц/векторов","Internal error of the matrix/vector executing subsystem"}, class=class="str">"cmt">// class="num">5700
{"Матрица/вектор не инициализирован","Matrix/vector not initialized"}, class=class="str">"cmt">// class="num">5701
{"Несогласованный размер матриц/векторов в операции","Inconsistent size of matrices/vectors in operation"}, class=class="str">"cmt">// class="num">5702
{"Некорректный размер матрицы/вектора","Invalid matrix/vector size"}, class=class="str">"cmt">// class="num">5703
{"Некорректный тип матрицы/вектора","Invalid matrix/vector type"}, class=class="str">"cmt">// class="num">5704