//+------------------------------------------------------------------+ //| ReloadSetsFromCommonFixed.mq5 | //| Исправленная версия скрипта, | //| учитывающая возможную проблему | //| с загрузкой разных сет-файлов | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Your Name" #property version "1.00" #property strict #property script_show_inputs // --- Настройки --- input int KolSet = 8; // Количество сет-файлов для обработки (например, 1..N) // --- Подключение библиотек --- #include // Для SetSettings2, GetSettings #include // Убран, если не используется напрямую // --- Константы --- #define COMMON_SET_FOLDER_PATH "___SET\\" // Относительный путь к папке в Common Files #define TESTER_FILES_PATH "tester\\files\\" // Путь к папке в терминале (для временной загрузки сета) #define SET_FILE_EXTENSION ".set" //+------------------------------------------------------------------+ //| Подсчитывает количество файлов .set в папке Common\Files\___SET | //+------------------------------------------------------------------+ int CountSetFilesInCommon() { string path = COMMON_SET_FOLDER_PATH + "*.set"; string filename; int count = 0; long search_handle = FileFindFirst(path, filename, FILE_COMMON); if(search_handle != INVALID_HANDLE) { count++; while(FileFindNext(search_handle, filename)) { count++; } FileFindClose(search_handle); } return count; } //+-------------------------------------------------------------------+ //| Получает имя k-го файла .set в папке Common\Files\___SET (1-based)| //+-------------------------------------------------------------------+ bool GetKthSetFileNameFromCommon(int k, string &filename_out) { if(k < 1) return false; string path = COMMON_SET_FOLDER_PATH + "*.set"; string filename; int current_count = 0; long search_handle = FileFindFirst(path, filename, FILE_COMMON); if(search_handle != INVALID_HANDLE) { current_count++; if(current_count == k) { filename_out = filename; FileFindClose(search_handle); return true; } while(FileFindNext(search_handle, filename)) { current_count++; if(current_count == k) { filename_out = filename; FileFindClose(search_handle); return true; } } FileFindClose(search_handle); } return false; } //+------------------------------------------------------------------+ //| Входная точка скрипта | //+------------------------------------------------------------------+ void OnStart() { Print("--- Запуск скрипта ReloadSetsFromCommonFixed ---"); int total_available_sets = CountSetFilesInCommon(); Print("Найдено доступных .set файлов в ", COMMON_SET_FOLDER_PATH, ": ", total_available_sets); if(total_available_sets == 0) { Print("ОШИБКА: В папке ", COMMON_SET_FOLDER_PATH, " не найдено ни одного .set файла. Прерываю выполнение."); return; } int sets_to_process = MathMin(KolSet, total_available_sets); Print("Будет обработано ", sets_to_process, " файлов из ", KolSet, " запрошенных."); for(int i = 1; i <= sets_to_process; i++) { Print("\n--- Обработка файла #", i, " ---"); string set_filename; if(!GetKthSetFileNameFromCommon(i, set_filename)) { Print("ОШИБКА: Не удалось получить имя файла для индекса ", i, ". Пропускаю."); continue; } Print("Обрабатывается файл: ", set_filename); // --- 1. Копирование исходного .set файла из ___SET в tester\files --- string source_path = COMMON_SET_FOLDER_PATH + set_filename; string dest_path = TESTER_FILES_PATH + set_filename; // Проверяем существование исходного файла if(!FileIsExist(source_path, FILE_COMMON)) { Print("ОШИБКА: Исходный файл не существует: ", source_path); continue; } // Удаляем файл в tester\files, если он уже существует if(FileIsExist(dest_path, FILE_COMMON)) { if(!FileDelete(dest_path, FILE_COMMON)) { Print("Предупреждение: Не удалось удалить старый файл ", dest_path, ". Код ошибки: ", GetLastError()); } else { Print("Старый файл в tester\\files удален: ", dest_path); } } // Копируем файл bool bFailIfExists; // if(!CopySetFileBinary(source_path, dest_path)) // Вариант 4 // if(!CopySetFileWithCorrectEncoding(source_path, dest_path)) // Вариант 1 // if(!CopySetFileWithUnicode(source_path, dest_path)) // Вариант 2 // if(!FileCopy(source_path, FILE_COMMON, dest_path, FILE_COMMON)) // Вариант 3 if(!FileCopy(source_path, FILE_COMMON, dest_path, FILE_COMMON)) // Исходно { Print("ОШИБКА: Не удалось скопировать ", source_path, " в ", dest_path, ". Код ошибки: ", GetLastError()); continue; } else { int check_handle1 = FileOpen(dest_path, FILE_READ | FILE_TXT | FILE_COMMON | FILE_ANSI); // Добавляем FILE_ANSI if(check_handle1 != INVALID_HANDLE) { string copied_content = ""; while(!FileIsEnding(check_handle1)) { string line = FileReadString(check_handle1); if(copied_content != "") copied_content += "\n"; copied_content += line; } FileClose(check_handle1); // Конвертируем в ANSI для корректного отображения в журнале uchar src_array[], dst_array[]; StringToCharArray(copied_content, src_array, 0, StringLen(copied_content), CP_UTF8); int converted_len = CharArrayToString(dst_array, 0, WHOLE_ARRAY, CP_ACP); Print("Длина скопированного файла: ", StringLen(copied_content), "\nСодержимое скопированного файла (первые 200 символов): ", StringSubstr(copied_content, 0, 200)); } Print("Файл скопирован в tester\\files для загрузки: ", dest_path," bFailIfExists=",bFailIfExists); // --- Дополнительная проверка: читаем и распечатываем скопированный файл --- // Открываем скопированный файл в tester\files для чтения int check_handle = FileOpen(dest_path, FILE_READ | FILE_TXT | FILE_COMMON); if(check_handle != INVALID_HANDLE) { string copied_content = ""; // Читаем всё содержимое while(!FileIsEnding(check_handle)) { if(copied_content != "") copied_content += "\n"; // Используем \n для внутреннего форматирования строки copied_content += FileReadString(check_handle); /* bool CopyFileW(string lpExistingFileName, string lpNewFileName, bool bFailIfExists); if(!kernel32::CopyFileW(SrcPath,DstPath,false)) // Переписываем Settin из песочницы Files в папку Tester PrintFormat("Error = %d",GetLastError()); // 4009 Неинициализированная строка */ } FileClose(check_handle); // Печатаем первые 200 символов (или меньше) содержимого скопированного файла для проверки int len = StringLen(copied_content); string snippet = copied_content; Print("Длина скопированного файла: ", len,"\nСодержимое скопированного файла (первые 200 символов): ", snippet); } else { Print("ПРЕДУПРЕЖДЕНИЕ: Не удалось открыть скопированный файл ", dest_path, " для проверки содержимого. Код ошибки: ", GetLastError()); // Продолжаем выполнение, но теперь мы знаем, что проверить содержимое не удалось } // --- Конец проверки --- } // --- 2. Загрузка скопированного .set файла в тестер через MTTESTER::SetSettings2 --- Print("Загрузка файла ", set_filename, " в тестер..."); bool load_success = MTTESTER::SetSettings2(set_filename); // Передаём только имя файла if(!load_success) { Print("ОШИБКА: MTTESTER::SetSettings2(", set_filename, ") вернул false. Пропускаю файл. Убедитесь, что файл в tester\\files корректен."); // Удаляем временный файл из tester\files FileDelete(dest_path, FILE_COMMON); continue; } else { Print("Загрузка параметров из ", set_filename, " выполнена (MTTESTER::SetSettings2 вернул true)."); } // --- КРИТИЧЕСКИ ВАЖНО: Добавляем задержку для стабилизации GUI --- // Попробуем увеличить задержку Sleep(2000); // Увеличено с 1000 до 2000 мс Print("Задержка после SetSettings2 выполнена."); // --- 3. Повторная проверка загрузки (опционально, но полезно для отладки) --- // Попробуем снова загрузить тот же файл, чтобы убедиться, что он "прижился" // (Это может сбросить какие-то внутренние состояния MTTester, если они были) Print("Повторная загрузка файла ", set_filename, " для подтверждения..."); bool reload_success = MTTESTER::SetSettings2(set_filename); if(!reload_success) { Print("ПРЕДУПРЕЖДЕНИЕ: Повторная загрузка ", set_filename, " не удалась. Возможны проблемы с параметрами."); // Продолжим, но результат GetSettings может быть ненадёжным } else { Print("Повторная загрузка успешна."); } Sleep(1000); // Ещё небольшая задержка после повторной загрузки // --- 4. Чтение текущих параметров из тестера через GetSettings --- Print("Чтение параметров из тестера через GetSettings..."); string current_settings_from_tester = ""; bool read_success = MTTESTER::GetSettings(current_settings_from_tester); if(!read_success) { Print("ОШИБКА: MTTESTER::GetSettings() вернул false. Не удалось прочитать параметры из тестера. Пропускаю сохранение."); // Удаляем временный файл из tester\files FileDelete(dest_path, FILE_COMMON); continue; } else { Print("Параметры успешно прочитаны из тестера через GetSettings (длина строки: ", StringLen(current_settings_from_tester), ")."); // Включим печать, чтобы видеть, какие параметры читаются для каждого файла Print("Прочитанные параметры (для файла ", set_filename, "): ", current_settings_from_tester); } // --- 5. Запись прочитанных параметров обратно в файл в папке ___SET с тем же именем --- string target_file_path_in_common = COMMON_SET_FOLDER_PATH + set_filename; Print("Запись параметров в файл: ", target_file_path_in_common); int file_handle = FileOpen(target_file_path_in_common, FILE_WRITE | FILE_TXT | FILE_COMMON); if(file_handle == INVALID_HANDLE) { Print("ОШИБКА: Не удалось открыть файл '", target_file_path_in_common, "' для записи. Код ошибки: ", GetLastError()); // Удаляем временный файл из tester\files FileDelete(dest_path, FILE_COMMON); continue; } bool write_success = FileWriteString(file_handle, current_settings_from_tester + "\r\n"); if(!write_success) { Print("ОШИБКА: FileWriteString не смог записать данные в файл '", target_file_path_in_common, "'."); FileClose(file_handle); // Удаляем временный файл из tester\files FileDelete(dest_path, FILE_COMMON); continue; } else { Print("Параметры успешно перезаписаны в исходный файл: ", target_file_path_in_common); } FileClose(file_handle); Print("Файл закрыт."); // Удаляем временный файл из tester\files после обработки FileDelete(dest_path, FILE_COMMON); Print("Временный файл из tester\\files удалён: ", dest_path); } Print("\n--- Завершение скрипта ReloadSetsFromCommonFixed ---"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CopySetFileBinary(string source_path, string dest_path) { // Открываем исходный файл как бинарный int src_handle = FileOpen(source_path, FILE_READ | FILE_BIN | FILE_COMMON); if(src_handle == INVALID_HANDLE) { Print("Не удалось открыть исходный файл. Ошибка: ", GetLastError()); return false; } // Получаем размер файла ulong file_size = FileSize(src_handle); // Читаем весь файл в массив байт uchar buffer[]; ArrayResize(buffer, (int)file_size); FileReadArray(src_handle, buffer, 0, (int)file_size); FileClose(src_handle); // Открываем целевой файл как бинарный int dst_handle = FileOpen(dest_path, FILE_WRITE | FILE_BIN | FILE_COMMON); if(dst_handle == INVALID_HANDLE) { Print("Не удалось открыть целевой файл. Ошибка: ", GetLastError()); return false; } // Записываем массив байт bool result = (FileWriteArray(dst_handle, buffer) == (int)file_size); FileClose(dst_handle); return result; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CopySetFileWithCorrectEncoding(string source_path, string dest_path) { // Открываем исходный файл в Common с явным указанием кодировки ANSI (обычно .set файлы в ANSI) int src_handle = FileOpen(source_path, FILE_READ | FILE_TXT | FILE_COMMON | FILE_ANSI); if(src_handle == INVALID_HANDLE) { Print("Не удалось открыть исходный файл. Ошибка: ", GetLastError()); return false; } // Читаем всё содержимое string content = ""; while(!FileIsEnding(src_handle)) { content += FileReadString(src_handle) + "\r\n"; } FileClose(src_handle); // Открываем целевой файл в tester\files с той же кодировкой int dst_handle = FileOpen(dest_path, FILE_WRITE | FILE_TXT | FILE_COMMON | FILE_ANSI); if(dst_handle == INVALID_HANDLE) { Print("Не удалось открыть целевой файл. Ошибка: ", GetLastError()); return false; } // Записываем содержимое bool result = (FileWriteString(dst_handle, content) > 0); FileClose(dst_handle); return result; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CopySetFileWithUnicode(string source_path, string dest_path) { // Пробуем открыть в разных кодировках int src_handle = FileOpen(source_path, FILE_READ | FILE_TXT | FILE_COMMON | FILE_UNICODE); if(src_handle == INVALID_HANDLE) { // Если не получается с UNICODE, пробуем ANSI src_handle = FileOpen(source_path, FILE_READ | FILE_TXT | FILE_COMMON | FILE_ANSI); if(src_handle == INVALID_HANDLE) { Print("Не удалось открыть исходный файл ни в одной кодировке. Ошибка: ", GetLastError()); return false; } } // Читаем всё содержимое string content = ""; while(!FileIsEnding(src_handle)) { content += FileReadString(src_handle) + "\r\n"; } FileClose(src_handle); // Определяем кодировку для записи (лучше использовать ANSI для совместимости) int dst_handle = FileOpen(dest_path, FILE_WRITE | FILE_TXT | FILE_COMMON | FILE_ANSI); if(dst_handle == INVALID_HANDLE) { Print("Не удалось открыть целевой файл. Ошибка: ", GetLastError()); return false; } // Записываем содержимое bool result = (FileWriteString(dst_handle, content) > 0); FileClose(dst_handle); return result; }