preview
Do básico ao intermediário: Navegando na SandBox

Do básico ao intermediário: Navegando na SandBox

MetaTrader 5Exemplos |
120 0
CODE X
CODE X

Introdução

No artigo anterior Do básico ao intermediário: Acesso aleatório (II), foi mostrado como poderíamos efetivamente trabalhar com arquivos de forma a termos um acesso aleatório aos dados, ou informações presentes no mesmo. Foi explicado e demonstrado, que nem sempre um mesmo conceito, iria de fato gerar um mesmo tipo de resultado, olhando exclusivamente o conteúdo presente internamente no arquivo. Apesar de que, olhando os resultados, impressos no terminal, não haveria diferenças entre uma e outra implementação. Já que basicamente, a própria implementação faria o trabalho de corrigir a adequar os resultados ao que seria esperado.

Ok, como a forma de se trabalhar com arquivos, basicamente não muda muito, partindo do pressuposto que você venha a entender que cada arquivo, internamente é um tipo de registro estruturado. Porém sem nenhum tipo de declaração explicita, do tipo de dado que estará sendo visualizado ao observar o conteúdo de um arquivo. Podemos, a princípio, dar como encerrada esta primeira parte sobre como acessar e trabalhar com arquivos. Pois na prática, você terá que procurar estudar a documentação de cada linguagem específica, para que possa usufruir da melhor maneira possível, das funções e procedimentos presentes ali.

Não me entenda mal, meu caro leitor, por lhe dizer estas palavras. Muito provavelmente você gostaria de ver cada uma das funções e procedimentos, presentes no MQL5 sendo utilizadas. Porém, ao meu ver, isto não iria de fato trazer grandes benefícios. Muito pelo contrário, fazer este tipo de coisa, acabaria por engessar o conteúdo dos artigos, além de os tornar algo chato e cansativo. Mas o fato é que, apesar de dizer que podemos dar como encerrada este primeiro contato com arquivos. Ainda assim, não terminamos de abordar esta questão. Isto por que, o que foi visto até aqui, está restrito ao que tange as SandBox presentes e mantidas pelo MetaTrader 5. E basicamente, ainda estamos no âmbito do que poderia ser descrito como acesso de usuário.

Nо entanto, existe um outro nível que seria o acesso via aplicação. Mas isto será tratado em outro momento. Portanto, ao fazermos tal distinção, entre o que seria um acesso de usuário e um acesso de aplicação, surge algumas questões um tanto quanto complicadas, e que fogem completamente das regras impostas pelo uso das SandBox. E é aqui onde a coisa realmente começa a complicar. Isto caso você não tenha de fato compreendido, como o sistema de SandBox do MetaTrader 5 trabalha. E tal coisa foi vista nos artigos anteriores.

Mas antes de entrarmos nesta questão, que irá de fato, tornar a coisa muito complicada para alguns de vocês. Existem alguns procedimentos e funções, que ao meu entender, de fato merecem serem explicadas. Isto por conta da imensa utilidade que as mesmas tem. Isto pensando exclusivamente em trabalhos com arquivos. Já que as mesmas nos permitem fazer coisas que de outra forma não seriam possíveis de serem efetuadas. Mas para abordar este tema de maneira adequada, vamos ao que será o tópico principal deste artigo.


Navegando entre arquivos e diretórios

Apesar de que muitos possam considerar o trabalho de pesquisa algo um tanto quanto desnecessário. E isto, na maior parte das aplicações de fato será verdade. Existem situações muito, mais muito específicas, durante a programação, tanto aqui na programação para o MetaTrader 5, quanto para outras coisas. Onde de fato precisamos efetivamente implementar um trabalho de pesquisa dentro do que seria uma arvore de diretórios e arquivos. Entender como fazer isto, talvez seja uma das tarefas e atividades mais burocráticas que você poderá vir a experimentar. Isto por que, em muitos casos, é algo muito repetitivo e de certa forma chato. Porém ainda assim, não deixa de ser importante que você saiba como efetuar este tipo de tarefa.

Devido a certas características, ao programarmos para o MetaTrader 5, podemos fazer o trabalho de pesquisa de duas maneiras diferentes. Uma de forma interativa, e a outra de forma automática, por assim dizer. A maneira interativa, utiliza uma caixa de diálogo, muito parecida com um mini explorador de arquivos. Já a forma automatizada, visa utilizar funções fornecidas pelo MQL5, a fim de termos acesso a procedimentos fornecidos pelo sistema operacional, para fins de pesquisa no sistema de arquivos.

Para começar, vamos modificar, de maneira bem singela e fácil de entender, um dos scripts visto no artigo anterior. Isto para entender como se daria a forma interativa de acesso e pesquisa de arquivos e diretórios. O código já modificado pode ser observado logo abaixo, na integra.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     int handle;
07.     const datetime dt = D'31.10.2024 15:30:10';
08.     const int i32 = 356248;
09.     string filenames[];
10. 
11.     if (FileSelectDialog("Save as...", NULL, "All files (*.*)|*.*", FSD_WRITE_FILE, filenames, "Hello Word.txt") <= 0)
12.         return;
13. 
14.     if ((handle = FileOpen(filenames[0], FILE_WRITE| FILE_READ | FILE_ANSI)) == INVALID_HANDLE)
15.     {
16.         Print("Error...");
17.         return;
18.     };
19. 
20.     FileWrite(handle, i32, "Info", dt);
21. 
22.     FileFlush(handle);
23.     
24.     FileSeek(handle, 0, SEEK_SET);
25.     while (!FileIsEnding(handle))
26.         Print(FileTell(handle), " >> ", FileReadString(handle));
27. 
28.     FileClose(handle);
29. }
30. //+------------------------------------------------------------------+

Código 01

Não entendi. Onde está a mudança no código? Já que à primeira vista ele é exatamente igual aos que podem ser vistos no artigo anterior. Bem, as mudanças de fato são bem sutis e à primeira vista não causam muito impacto no código. Já que muitos acreditam que para se modelar um novo código, precisamos implementar o mesmo de forma radical. Mas na prática nem sempre é assim que fazemos. Basicamente a mudança aqui é bem fácil de entender, sendo que ela se encontra na linha onze. No entanto, apesar de a mudança ser apenas nesta linha onze, quando este código é executado teremos algo diferente sendo feito. Para começar, esta função FileSelectDialog irá abrir uma janela como pode ser visto na imagem logo abaixo.

Imagem 01

Nesta janela que podemos ver na imagem 01, que é uma janela oriunda e mantida pelo sistema operacional. Podemos facilmente visualizar algumas coisas. Primeiro o título da janela. Como você pode notar ele é o mesmo que estamos declarando como sendo o primeiro argumento da função FileSelectDialog. Como o segundo argumento passado para a função é um valor NULL, iremos começar no que seria a raiz da SandBox. Agora preste atenção, meu caro leitor, por estarmos dentro de uma SandBox, NÃO PODEREMOS sair do diretório, ou melhor dizendo da raiz atual. Ou seja, você não terá liberdade de navegar por todos os diretórios presentes na unidade de disco onde o MetaTrader 5 se encontra instalado. Ficando desta maneira restrito a arvore de diretórios dentro da SandBox atual.

No terceiro argumento da função, passamos um filtro, que você poderá utilizar para fins de seleção da janela de pesquisa. Você somente poderá selecionar os filtros que estiverem sendo informados aqui na linha onze. Sendo assim, não espere que o sistema operacional, venha a permitir utilizar filtros não indicados aqui, pois isto não irá acontecer. O próximo argumento da função, são os flags de seleção. Aqui é importante que você pratique um pouco, com outros flags para ver o tipo de resultado e proposito de cada um, já que podemos fazer bem mais coisas do que simplesmente indicar um nome de arquivo, ou algo do tipo. Veja a documentação, para saber que valores podem ser utilizados aqui nos flags.

Ok, agora nos resta entender os dois últimos argumentos da função FileSelectDialog. Sendo que esta parte, pode vir a variar ligeiramente dependendo do tipo de implementação que você esteja efetuando. Mas basicamente, o quinto argumento, deverá ser sempre um array dinâmico e cujo tipo de dados seja string. Isto porque, a função irá preencher este array com dados de interação do usuário com a janela vista na imagem 01. Já o último argumento, não necessariamente precisa aparecer como é visto no código 01. Porém, caso você espere usar algum nome específico de arquivo, deverá indicar isto aqui. Assim, teremos no final, a indicação do que seria o nome default esperado pela nossa aplicação. Lembrando que o usuário pode vir a mudar este nome.

Legal, se tudo ocorrer sem problemas, teremos um retorno da função, sendo maior que zero. Caso isto não tenha ocorrido, significa que houve um erro, e que deveremos abortar a aplicação. E isto é feito usando a linha doze. Caso tenhamos sucesso, e como queremos salvar um arquivo, iremos para a linha 14, onde o código volta a funcionar como era feito no artigo anterior. No entanto, observe o fato de que na criação, ou abertura do arquivo, que será feita pela função FileOpen, o primeiro argumento passado, é justamente o primeiro valor presente no array. Existem forma de se trabalhar com este array, de forma a carregar diversos arquivos ao mesmo tempo. Sendo que eles seriam selecionados pelo usuário, durante a chamada da linha onze. Como eu informei, é preciso que você procure praticar para entender melhor como esta função FileSelectDialog pode vir a ser utilizada por você em suas aplicações, aqui no MetaTrader 5.

Bem, acredito que esta breve explicação já lhe de alguma orientação a fim de entender e praticar como fazer uso da forma interativa de navegação na arvore de arquivos e diretórios. Mas então para separar as coisas, vamos ver em um novo tópico, como seria feita a navegação de forma não interativa.


Navegando via código

Existem algumas situações em que não queremos que o usuário venha a ter, diretamente, uma interação com o sistema de pesquisa. No entanto, ao mesmo tempo, queremos, seja por qualquer motivo, saber como a árvore de diretórios está sendo montada. Tanto no que diz respeito aos arquivos, quanto também a própria estrutura de diretórios. E para fazer isto, abrimos mão do que foi visto no código 01, e implementamos algo diferente. Porém com um objetivo bem específico.

Como aqui a ideia é ser o mais didático possível, não tendo como objetivo a criação de nenhuma aplicação em especial. Fica um tanto quanto difícil explicar a motivação pela qual podemos vir a desejar navegar pela árvore de diretórios. Porém, quero que você, meu caro leitor, procure abrir a sua mente e ver além do que será mostrado aqui em forma de código. Tente imaginar alguma aplicação que esteja interessada em saber como a estrutura de arquivos está sendo mantida. E com base nisto, pense em uma forma de usar isto na prática.

Muito bem, para começar de forma que você possa realmente entender como este tipo de navegação acontece. Vamos partir do princípio, que a SandBox do diretório MQL5\Files esteja vazia. Ou seja, não existe ainda nenhum arquivo ou diretório presente na SandBox. É importante começarmos com este princípio, para que tudo possa vir a fazer sentido. Com base nisto, começamos com o código visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     long    handle;
07.     string  szFileName;
08. 
09.     if ((handle = FileFindFirst("*", szFileName)) == INVALID_HANDLE)
10.     {
11.         Print("Failed...");
12.         return;
13.     }
14.     do
15.     {
16.         Print(szFileName, " is a ", FileIsExist(szFileName) ? "file ..." : "directory...");
17.     }while (FileFindNext(handle, szFileName));
18.     FileFindClose(handle);
19. 
20.     Print("Search in directory completed successfully.");
21. }
22. //+------------------------------------------------------------------+

Código 02

Agora lembre-se do seguinte: Toda e qualquer coisa que venhamos a fazer, estará restrita a SandBox que estivermos apontando. Você não pode, a princípio, ver coisas fora da SandBox. Não se esqueça disto. Então, quando executarmos este código 02 iremos ter o seguinte resultado, visto logo abaixo.

Imagem 02

Meu DEUS, o que aconteceu aqui? Como assim o código falhou? Que mal eu fiz a DEUS para merecer isto? Isto só pode ser castigo divino. ( RISOS ). Calma meu caro leitor, vamos com calma. Não existe nada de errado aqui no código. Ele funciona perfeitamente bem. Mas como assim? Você não está vendo que ele retornou um erro? Novamente, vamos com calma. Lembra do que foi dito antes de começarmos? Que iriamos a princípio ter o diretório MQL5\Files, que é a SandBox que estamos utilizando aqui, completamente vazio?

Pois bem, pelo fato de que FileFindFirst não ter encontrado absolutamente nada presente na SandBox, ela retorna um valor de handle inválido. Ou melhor dizendo, pelo motivo que nenhuma correspondência ao filtro foi encontrada, FileFindFirst retorna um valor indicando que a pesquisa não teve sucesso. É por isto que estamos vendo o resultado visto na imagem 02. Tanto que se você executar novamente o código 01 aqui e agora, irá ver o que é mostrado logo abaixo.

Imagem 03

Certo, acho que entendi. Mas e se tivermos algum tipo de conteúdo dentro da SandBox. O que irá acontecer? Bem, isto depende, de como o nosso código estará estruturado para trabalhar com o conteúdo presente na SandBox. Como aqui, e neste momento estamos trabalhando com algo bem simples e objetivo. O resultado será igualmente simples e objetivo. Porém, as coisas podem necessitar de alguma solução um pouco mais avançada, dependendo de cada caso específico. Porém, toda via e, entretanto, vamos primeiro ver o que aconteceria se tivéssemos algum tipo de conteúdo presente na SandBox. Para isto, criamos algumas coisas apenas para fins de teste. E isto pode ser visto, quando executamos novamente o código 01. Neste caso o resultado é o que pode ser observado na imagem logo abaixo.

Imagem 04

Ok, agora temos algo que pode vir a ser mostrado. Então, quando executarmos novamente o código 02, o resultado mostrado é o que podemos visualizar logo na sequência.

Imagem 05

Note que não mudamos absolutamente nada nos códigos, apenas adicionamos algum tipo de conteúdo dentro da SandBox. No entanto, aqui é onde as coisas começam a ficar um tanto quanto mais complicadas. Isto dependendo é claro do tipo de coisa que você esteja querendo implementar. Apesar do código 02, funcionar, como você pode ter observando, vendo as imagens acima. Existe um pequeno detalhe. O código 02, ficar preso no diretório inicial da pesquisa. Ele não consegue entrar nos diretórios mais acima, a fim de reportar o tipo de conteúdo presente neles. Sendo necessário que você venha a indicar que realmente deseja ir para um diretório específico. Isto antes mesmo de iniciar a pesquisa, que tem seu início na linha nove. O que em alguns casos limita um pouco as coisas.

Agora vamos parar e pensar um pouco. Isto porque, a solução para podermos navegar dentro da árvore de diretórios, está no próprio código 02. No entanto, é preciso fazer uma pequena mudança no mesmo para que ele venha a funcionar, da maneira como desejamos fazer. Que seria, o código conseguir reportar todos os arquivos presentes em cada um dos diretórios dentro da árvore presente na SandBox.

Muito bem, sabemos que ao indicar um filtro para a função FileFindFirst, podemos incluir o nome de um caminho dentro da SandBox. Então, e se, transformássemos este mesmo código 02 em um código recursivo? Será que conseguiríamos ter o comportamento que queremos? Isto a fim de que a linha 16 do código 02 pudesse vir a nos informar, o nome de cada arquivo e onde ele estaria localizado? Bem, esta é a grande questão a ser resolvida agora. Lembrando que existem diversas maneiras de se fazer o que irei mostrar aqui. Sendo cada caso um caso.

Ok, a primeira coisa a ser feita, é mudar o código para algo parecido com o que pode ser visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     SearchIn("");
07. 
08.     Print("== Research completed. ==");
09. }
10. //+------------------------------------------------------------------+
11. void SearchIn(const string szDir)
12. {
13.     long    handle;
14.     string  szFileName;
15. 
16.     Print("[",szDir,"]");
17.     if ((handle = FileFindFirst(szDir + "*", szFileName)) == INVALID_HANDLE)
18.         return;
19.     do
20.     {
21.         if (FileIsExist(szFileName)) Print(szFileName);
22.     }while (FileFindNext(handle, szFileName));
23.     FileFindClose(handle);
24. }
25. //+------------------------------------------------------------------+

Código 03

Este é o primeiro passo. Agora preste atenção, meu caro leitor. Quando este código for executado, o resultado será diferente do que foi mostrado anteriormente. Isto porque, agora estamos focamos em visualizar somente e tão somente os nomes dos arquivos. É muito importante que você entenda muito bem isto. Já que você provavelmente iria esperar ver algo parecido como o que é mostrado na barra de navegação do explorador de arquivos, onde podemos ver diretórios e o nome do arquivo tudo junto. Mas aquilo que você está vendo, é apenas e tão somente a forma do sistema operacional, o programa lhe mostrar as coisas. Internamente, dentro do que seria a estrutura de pastas e arquivos, que é gravado em disco, as coisas não são daquela maneira.

Na verdade, um sistema de arquivos seria muito parecido como uma lista, ou agenda. Talvez o problema e toda esta confusão foi criado quando o Windows 95 surgiu. Já que na época, começou a se falar em usar a árvore de diretórios como parte do nome do arquivo. O que na prática não é bem assim que acontece. Mas explicar isto, é algo que foge completamente do escopo deste artigo. Então vamos voltar a nossa questão principal. Assim, então o resultado da execução deste código 03 é visto na imagem logo abaixo.

Imagem 06

Note que aqui estamos vendo apenas o nome dos arquivos. Já os diretórios não são mostrados. Justamente por conta de que eles não nos interessam neste momento. No entanto, supondo que dentro dos diretórios, vistos na imagem 05, exista alguma coisa, como poderíamos fazer para ver o conteúdo presente ali? Bem, esta é a parte fácil. Mas antes de vermos isto, quero que você observe o fato de que, quando estivermos reportando um diretório, o último caractere será uma barra inclinada. Este fato é muito importante para o que iremos ver a seguir.

Ou seja, quando a string szFileName estiver se referindo a um diretório, teremos a presença de uma barra inclinada na string. Assim não precisamos de fato utilizar a função FileIsExist, a fim de analisar se estamos lidando com um diretório, ou com um arquivo. Basta que verifiquemos se na string existe ou não a presença de uma barra inclinada. Se existir, é um diretório. Se não, estaremos lidando com um arquivo. Simples assim. 

Contudo, quero que você observe um outro detalhe aqui, neste código 03. Veja que o procedimento da linha onze, recebe como argumento uma string. Esta seria o diretório inicial que estaremos pesquisando. No entanto, na linha seis, não estamos passando nenhum parâmetro para este procedimento da linha onze. Significando assim, que a pesquisa irá se dar, começando na raiz da SandBox. Entender isto é muito importante, pois agora vem a parte recursiva do código.

Lembra do fato de que, durante o teste para verificar se a string, tem ou não uma barra inclinada, estaremos de fato verificando se a string se refere ou não a um diretório? Pois bem, e se modificarmos o código a fim de vir a utilizar esta informação ao nosso favor. Isto é, ao invés de desperdiçarmos a informação de que a string contém o nome de um diretório. Fizermos uma mudança para que SearchIn, presente na linha onze fosse chamada com o conteúdo desta string. Que no caso sabemos ser um diretório. O que acontece? Bem, vamos ver isto na prática. E com base nesta ideia, podemos modificar o código 03, para o que é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     SearchIn("");
07. 
08.     Print("== Research completed. ==");
09. }
10. //+------------------------------------------------------------------+
11. void SearchIn(const string szDir)
12. {
13.     long    handle;
14.     string  szFileName;
15. 
16.     Print("[",szDir,"]");
17.     if ((handle = FileFindFirst(szDir + "*", szFileName)) == INVALID_HANDLE)
18.         return;
19.     do
20.     {
21.         if (StringFind(szFileName, "\\") > 0)
22.             SearchIn(szFileName);
23.         else
24.             Print(szFileName);
25.     }while (FileFindNext(handle, szFileName));
26.     FileFindClose(handle);
27. }
28. //+------------------------------------------------------------------+

Código 04

Muito bem, neste código 04 podemos ver as mudanças que foram feitas no código a fim de efetuar o que foi explicado a pouco. Portanto quando você vier a executa este código 04 irá conseguir um resultado bem diferente do que foi visto na imagem 06. No entanto ainda assim bem similar ao que pode ser entendido com base na imagem 06. Isto para alguns, enquanto outros podem vir a ficar confusos com o resultado visto. Para deixar isto claro você pode observar a imagem 07 logo abaixo.

Imagem 07

Ok, e onde está a parte confusa? Bem, olhando esta imagem 07, você conseguiria me dizer a que pasta o arquivo Backup.zip pertence? Hum, você pode dizer que seria a pasta Sub 02. Mas ao olhar com calma você pode observar que algo parecido aconteceu com a pasta Sub 01 e Sub 11. Mas espere um pouco aí. Isto daqui está muito mais confuso do que eu imaginava. Isto por que, olhando a imagem 04, noto que a pasta Sub 02 está na raiz, assim como a pasta Sub 01. Mas olhando as coisas assim, como é mostrado na imagem 07, tenho a impressão de que na verdade o arquivo Backup.zip estaria no caminho Sub 01\Sub 11\Sub 02. O que não parece ser o correto. Bem, agora fiquei um tanto quanto perdido.

De fato, olhando as coisas assim, fica um tanto quanto confuso saber exatamente como a árvore dentro da SandBox está estruturada. Então vou lhe mostrar como ela está estruturada, meu caro leitor. Assim você irá conseguir entender como o resultado deveria ser apresentado. Isto pode ser visto na animação logo abaixo.

Animação 01

Nesta animação 01, podemos nitidamente ver que temos uma estrutura bem simples de pastas e um arquivo que não está aparecendo na imagem 07. Isto a princípio parece ser bem estranho. Já que podemos notar que Backup.zip é mostrado na imagem 07, mesmo estando dentro de um diretório. Então onde está o erro? O erro está no fato de que na linha 22 do código 04, estamos ignorando a árvore de diretórios. Estamos na verdade apenas entrando dentro dos diretórios sem levar em conta a forma como a árvore está construída. Resolver isto este tipo de problema, é algo muito simples e até meio bobo, se você parar para pensar bem.

No entanto, vamos fazer algo a mais, no código a ser criado. Vamos adicionar, durante a impressão do nome do arquivo, o atual caminho que foi percorrido até que o arquivo tenha sido encontrado. Assim, teremos uma construção mais simples de entender. Isto a princípio. Com isto, temos o código que pode ser visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     SearchIn("");
07. 
08.     Print("== Research completed. ==");
09. }
10. //+------------------------------------------------------------------+
11. void SearchIn(const string szDir)
12. {
13.     long    handle;
14.     string  szFileName;
15. 
16.     Print("[",szDir,"]");
17.     if ((handle = FileFindFirst(szDir + "*", szFileName)) == INVALID_HANDLE)
18.         return;
19.     do
20.     {
21.         if (StringFind(szFileName, "\\") > 0)
22.             SearchIn(szDir + szFileName);
23.         else
24.             Print(szDir, szFileName);
25.     }while (FileFindNext(handle, szFileName));
26.     FileFindClose(handle);
27. }
28. //+------------------------------------------------------------------+

Código 05

Perfeito, então vamos executar este novo código que é visto acima. E ao fazermos isto, o resultado é o que podemos visualizar logo abaixo.

Imagem 08

Agora sim, fizemos algo bem legal de ser visto. Note que com uma simples mudança no código 04, a fim de produzir o que é visto no código 05, tivermos um resultado completamente diferente e até mesmo bem mais interessante. Tanto que se você desejar, pode até mesmo remover a linha dezesseis do código, que ainda assim irá conseguir entender como a estrutura de diretórios está construída. Sendo capaz de visualizar onde cada arquivo se encontra. Isto sim é bem legal. Porém existe um pequeno e um tanto quanto bastante chato problema, neste código 05. Isto para não dizer outra coisa. O código em si funciona, como você pode claramente notar. No entanto, existe um tipo muito específico de situação, onde podemos ter diretórios e arquivos sendo mostrados de forma mesclada. Isto não é falha no código e tão pouco um defeito na programação. Mas sim um problema de outra natureza.

E ela se dá justamente devido as interações de FileFindFirst e FileFindNext. O detalhe é que quando FileFindFirst é executada, ela irá pedir ao sistema operacional que lhe retorne algo cujo filtro está sendo indicado. Podendo este algo, ser um arquivo ou diretório. Você em tese não controla o que irá vir primeiro. Quem faz isto é o sistema operacional. Mas o problema em si acontece quando fazemos um novo pedido, para saber qual o próximo item. E isto é feito pela função FileFindNext. E qual é o problema? Bem, supondo que você deseje visualizar todos os arquivos antes dos diretórios. Ou vice versa. Como você poderia fazer isto? Lembrando que você não tem controle sobre que tipo de item o sistema operacional irá lhe retornar. Você apenas irá receber este item e analisar o que irá fazer com ele.

Bem, meu caro leitor, para resolver este tipo de coisa, precisaremos utilizar uma outra abordagem. E está será o tema que iremos começar a explorar já no próximo artigo.


Considerações finais

Neste artigo vimos como podemos de maneira muito simples, fácil e prática, olhar o que tem dentro de uma SandBox. Isto utilizando a plataforma MetaTrader 5. Apesar de à primeira vista, o que foi visto aqui, não fazer muito sentido e não ter um objetivo bem definido. Pelo menos neste primeiro momento. Saber, mas principalmente compreender como visualizar via código o conteúdo de uma pasta ou de uma raiz inteira, pode vir a lhe ajudar a encontrar de maneira bem rápida certos tipos de informações perdidas em meio a uma infinidade de arquivos e pastas.

Mas o principal objetivo de fato em se aprender a trabalhar com o que foi visto aqui, será o de conseguir entender uma outra coisa na qual iremos falar no próximo artigo. Então meu caro leitor, procure estudar com calma o que foi visto até aqui neste artigo, para que você de fato consiga compreender o que será visto a partir do próximo artigo. Pois agora iremos entrar em um tipo de coisa, que é muito divertida. Apesar de ser o terror para quem está começando a aprender programação. Então nos vemos no próximo artigo.

Arquivo Descrição
Code 01  Demonstração de navegação entre pastas
Code 02   Demonstração de navegação entre pastas 
Code 03   Demonstração de navegação entre pastas
Arquivos anexados |
Anexo.zip (1.59 KB)
Simulação de mercado: Position View (VII) Simulação de mercado: Position View (VII)
Neste artigo, começaremos a fazer algumas melhorias no indicador de posição. Isto para que seja possível interagir com ele. E modificar as linhas de preço, ou fechar uma posição diretamente via interação com o indicador de posição. Antes de realmente começarmos a parte da implementação. Vamos entender uma coisa aqui. Isto para os menos avisados. Não é possível, de maneira ou forma alguma, usar um indicador a fim de modificar algo no servidor de negociação. Isto por conta que o MetaTrader 5, conta com um sistema de segurança que permite apenas e somente aos Expert Advisores, fazerem algo em uma ordem ou posição. Nenhuma outra aplicação que não seja um Expert Advisor, conseguirá manipular ordens ou posições.
Negociando com o Calendário Econômico do MQL5 (Parte 1): Dominando as Funções do Calendário Econômico do MQL5 Negociando com o Calendário Econômico do MQL5 (Parte 1): Dominando as Funções do Calendário Econômico do MQL5
Neste artigo, exploramos como usar o Calendário Econômico do MQL5 para negociar, primeiro entendendo suas funcionalidades principais. Em seguida, implementamos funções-chave do Calendário Econômico no MQL5 para extrair dados relevantes de notícias para decisões de negociação. Por fim, concluímos mostrando como utilizar essas informações para aprimorar as estratégias de negociação de forma eficaz.
Redes neurais em trading: Modelos bidimensionais do espaço de conexões (Conclusão) Redes neurais em trading: Modelos bidimensionais do espaço de conexões (Conclusão)
Damos continuidade ao estudo do framework inovador Chimera, um modelo bidimensional do espaço de estados que utiliza tecnologias de redes neurais para análise de séries temporais multidimensionais. Esse método garante alta precisão de previsão com baixo custo computacional.
Redes neurais em trading: Agente multimodal complementado com ferramentas (Conclusão) Redes neurais em trading: Agente multimodal complementado com ferramentas (Conclusão)
Damos continuidade à implementação dos algoritmos do agente multimodal para negociação financeira, o FinAgent, desenvolvido para análise de dados multimodais da dinâmica de mercado e de padrões históricos de trading.