Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1549

 
klycko #:

Спасибо за юмор!

Вечером проверю

Добавил ваш юмор в скрипт, и вот что оказалось:

//+------------------------------------------------------------------+
//|                                                        probb.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#import "kernel32.dll"
bool CopyFileW(string lpExistingFileName, string lpNewFileName, bool bFailIfExists);
#import
//+------------------------------------------------------------------+
void OnStart()// создал файл File.csv в папке Files, скрипт копирует его в папку терминала
  {
   string File = "File.csv";
   string Path = TerminalInfoString(TERMINAL_DATA_PATH);
   string LastPath = Path + "\\MQL5\\Files\\" + File;
   string NewPath = "";
   
   if(!FileIsExist("File.csv"))
      Print("Пошёл на хе..., нет в папке такого файла!");

   for(int i = 0; i < 3; i++)
     {
      if(i == 0)
         NewPath = Path + "\\" + File;
      else
         if(i == 1)
            NewPath = LastPath + ".txt";
         else
            NewPath = Path + "\\New" + File;

      bool res = kernel32::CopyFileW(LastPath, NewPath, false);
      Print(res);
     }
  }

Хотя в папке Files есть файл File.csv, скрипт его не видит и печатает:

Пошёл на хе..., нет в папке такого файла!

false

false

false



Просто фантастика!!!

 

	          
 
klycko #:

Просто фантастика!!!

Нет никакой фантастики. 

Сделайте в свойствах папки видимость расширения файлов.

У вас как я вижу файл имеет имя File.csv.txt,  а вы пытаетесь найти  File.csv, естественно его найти не получается.


 

Фантастика продолжается.

Взял пример скрипта из документации на FileCopy.

Дополнил его вашей проверкой на существование файла.

Результат аналогичный - скрипт файла не видит.

//+------------------------------------------------------------------+
//|                                                         prob.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- покажем окно входных параметров при запуске скрипта
#property script_show_inputs
//--- входные параметры
input string InpSrc="source.txt";       // источник
input string InpDst="destination.txt";  // копия
input int    InpEncodingType=FILE_ANSI; // ANSI=32 или UNICODE=64
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   if(!FileIsExist("InpSrc",0))     // FILE_COMMON
      Print("Нет в папке такого файла!");

//--- отобразим содержимое источника (он должен существовать)
   if(!FileDisplay(InpSrc))                                      //  5004    Ошибка открытия файла
      return;
//--- проверим, существует ли уже файл копии (не обязан быть создан)
   if(!FileDisplay(InpDst))
     {
      //--- файл копии не существует, копирование без флага FILE_REWRITE (правильное копирование)
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
   else
     {
      //--- файл копии уже существует, попробуем скопировать без флага FILE_REWRITE (неправильное копирование)
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
      //--- содержимое файла InpDst останется прежним
      FileDisplay(InpDst);
      //--- скопируем еще раз с флагом FILE_REWRITE (правильное копирование при существовании файла)
      if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
//--- получили копию файла InpSrc
   FileDisplay(InpDst);
  }
//+------------------------------------------------------------------+
//| Чтение содержимого файла                                         |
//+------------------------------------------------------------------+
bool FileDisplay(const string file_name)
  {
//--- сбросим значение ошибки
   ResetLastError();
//--- откроем файл
   int file_handle=FileOpen(file_name,FILE_READ|FILE_TXT|InpEncodingType);
   if(file_handle!=INVALID_HANDLE)
     {
      //--- отобразим в цикле содержимое файла
      Print("+---------------------+");
      PrintFormat("File name = %s",file_name);
      while(!FileIsEnding(file_handle))
         Print(FileReadString(file_handle));
      Print("+---------------------+");
      //--- закроем файл
      FileClose(file_handle);
      return(true);
     }
//--- не удалось открыть файл
   PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
   return(false);
  }
//+------------------------------------------------------------------+
 

Здравствуйте, Александр.

Должна быть какая-то причина такого поведения. Надо выдвигать гипотезы и проверять их последовательно. Например:

  • Hе закралась ли русская буква ('с' или 'е') в каком-то из имён файлов? Можно взять более суровые имена типа "1.bin"
  • Тот ли это каталог данных? Проверить его открытие из меню терминала или MetaEditor
  • Считает ли скрипт именно этот каталог текущим? Добавить в начало OnStart() две команды: открыть новый файл с созданием и закрыть его. Посмотреть, что он появился в ожидаемом каталоге
Больше пока не придумал
 
klycko #:

Фантастика продолжается.

Ещё раз. Имя файла нужно указывать с расширением этого файла.

Вы создали файл с расширением .txt  и с именем  File.csv

Значит полное имя файла, которое нужно указать в программе будет таким  -   File.csv.txt

У вас в винде в свойствах папки отключено отображение расширения файлов, от этого у вас такая путаница с именами файлов.

 
Aleksandr Slavskii #:

Нет никакой фантастики. 

Сделайте в свойствах папки видимость расширения файлов.

У вас как я вижу файл имеет имя File.csv.txt,  а вы пытаетесь найти  File.csv, естественно его найти не получается.

Большое спасибо! В этом и была проблема. Без вас я не смог бы найти ошибку. Желаю вам успехов!

 

Александр, добрый день!

Оказывается, файл нужно обязательно закрывать перед его переписыванием из песочницы в папку Tester.

Иначе не работает.

Долго же я это выяснял!!!

С уважением, Александр

   string NameSettings = mnth+dy+"-"+LimPos+"-"+DoubleToString(ProfitNew,0)+".set"; // Формируется имя для Settings
   int file_handle=FileOpen("//"+NameSettings,FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI);
   FileWriteString(file_handle,Settings+"\r\n");                                    // Записывается строка Settings в песочницу Files
   FileClose(file_handle);                                                          // Закрываем открытый файл, чтобы его можно было дальше перезаписывать

   if(!FileIsExist(NameSettings,0))                                                 // Проверка существования файла
      Print("Нет файла NameSettings!");
   string Path = TerminalInfoString(TERMINAL_DATA_PATH);
   string SrcPath = Path + "\\MQL5\\Files\\" + NameSettings;
   string DstPath = Path + "\\MQL5\\Profiles\\Tester\\" + NameSettings;
   ResetLastError();
   if(!kernel32::CopyFileW(SrcPath,DstPath,false))                                  // Переписываем Settings из песочницы Files в папку Tester
      PrintFormat("Error = %d",GetLastError());    
 
klycko #:

Александр, добрый день!

Оказывается, файл нужно обязательно закрывать перед его переписыванием из песочницы в папку Tester.

Иначе не работает.

А если так?  )))

   string NameSettings = mnth+dy+"-"+LimPos+"-"+DoubleToString(ProfitNew,0)+".set"; // Формируется имя для Settings
   int file_handle=FileOpen("//"+NameSettings,FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_CSV|FILE_ANSI);
   FileWriteString(file_handle,Settings+"\r\n");                                    // Записывается строка Settings в песочницу Files

   if(!FileIsExist(NameSettings,0))                                                 // Проверка существования файла
      Print("Нет файла NameSettings!");
   string Path = TerminalInfoString(TERMINAL_DATA_PATH);
   string SrcPath = Path + "\\MQL5\\Files\\" + NameSettings;
   string DstPath = Path + "\\MQL5\\Profiles\\Tester\\" + NameSettings;
   ResetLastError();
   if(!kernel32::CopyFileW(SrcPath,DstPath,false))                                  // Переписываем Settings из песочницы Files в папку Tester
      PrintFormat("Error = %d",GetLastError());   
   FileClose(file_handle);                                                          // Закрываем открытый файл, чтобы его можно было дальше перезаписывать
При условии, что файла с таким именем в папке назначения нет.
 
Yuriy Bykov #:

Здравствуйте, Александр.

Должна быть какая-то причина такого поведения. Надо выдвигать гипотезы и проверять их последовательно. Например:

  • Hе закралась ли русская буква ('с' или 'е') в каком-то из имён файлов? Можно взять более суровые имена типа "1.bin"
  • Тот ли это каталог данных? Проверить его открытие из меню терминала или MetaEditor
  • Считает ли скрипт именно этот каталог текущим? Добавить в начало OnStart() две команды: открыть новый файл с созданием и закрыть его. Посмотреть, что он появился в ожидаемом каталоге
Больше пока не придумал

Юрий, добрый вечер!

Спасибо за ваши советы. Буду внимательнее теперь.

Мои проблемы разрешились с помощью Александра.

Кроме того, оказалось, что нужно вовремя закрывать файл.

Привожу окончательный фрагмент работающего кода, может кому-нибудь будет полезен.

   Now = TimeLocal();                                                  // Момент формирования имени для Settings
   TimeToStruct(Now,dt_struct);                                        // Разложение момента формирования
   string mnth = dt_struct.mon;                                        // Месяц, день
   int dyy = dt_struct.day;
   string dy = dt_struct.day;
   if(dyy <= 9)
      dy = "0" + dy;
   string LimPos = MTTESTER::GetValue(Settings,"LimitPosition");                    // LimitPosition считывается
   int PosVert = StringFind(LimPos,"|",0);
   string razn = StringSubstr(LimPos,PosVert,-1);
   StringReplace(LimPos,razn,"");
   string NameSettings = mnth+dy+"-"+LimPos+"-"+DoubleToString(ProfitNew,0)+".set"; // Формируется имя для Settings
   int file_handle=FileOpen("//"+NameSettings,FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI);
   FileWriteString(file_handle,Settings+"\r\n");                                    // Записывается строка Settings в песочницу Files
   FileClose(file_handle);                                                          // Закрываем открытый файл, чтобы его можно было дальше перезаписывать

   if(!FileIsExist(NameSettings,0))                                                 // Проверка существования файла
      Print("Нет файла NameSettings!");
   string Path = TerminalInfoString(TERMINAL_DATA_PATH);
   string SrcPath = Path + "\\MQL5\\Files\\" + NameSettings;
   string DstPath = Path + "\\MQL5\\Profiles\\Tester\\" + NameSettings;
   ResetLastError();
   if(!kernel32::CopyFileW(SrcPath,DstPath,false))                                  // Переписываем Settings из песочницы Files в папку Tester
      PrintFormat("Error = %d",GetLastError());                                     // 4009  Неинициализированная строка
 

Опять какие- то проблемы с демо сервером... не подключается...