Olá pessoal…
Hoje vou mostrar uma função que desenvolvi para abrir a tela de seleção de arquivos do Windows via AdvPL.
Todos sabemos como a tela padrão do AdvPL para seleção de arquivos (a função cGetFile) não é muito usual, e às vezes acaba confundindo os usuários.
Pensando nisso, criei uma função que você simplesmente passa a máscara desejada para seleção de arquivos, e ele cria a tela para você selecionar.
Testei no Windows 7 e no Windows 10. Abaixo um print da tela.
Abaixo o código fonte desenvolvido:
//Bibliotecas #Include "Protheus.ch" /*/{Protheus.doc} zChooseFile Função que abre a tela padrão do Windows Explorer para escolher um arquivo @author Atilio @since 03/08/2017 @version undefined @param cMascara, characters, Máscara para escolha de arquivos (Descrição *.extensão | *.extensão) @type function @example Exemplos abaixo: //Escolher qualquer arquivo ( *.* ): u_zChooseFile() //Escolher somente arquivos texto ( *.txt ) u_zChooseFile("Arquivos Texto (*.txt)|*.txt") //Escolher arquivos texto ou todos (*.txt ou *.*) u_zChooseFile("Arquivos Texto (*.txt)|*.txt|Todos Arquivos (*.*)|*.*") //Escolher imagens png ou jpg (*.png ou *.jpg) u_zChooseFile("Arquivos Texto (*.png)|*.png|Arquivos Texto (*.jpg)|*.jpg") /*/ User Function zChooseFile(cMascara) Local cResultado := "" Local cComando := "" Local cDir := GetTempPath() Local cNomBat := "zChooseFile.bat" Local cArquivo := "resultado.txt" Local cMac := "" Default cMascara := "Todos Arquivos (*.*)|*.*" //Se o resultado já existir, exclui If File(cDir + cArquivo) FErase(cDir + cArquivo) EndIf //Monta o comando para abrir a tela de seleção do windows cComando += '@echo off' + CRLF cComando += 'setlocal' + CRLF cComando += 'set ps_cmd=powershell "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.OpenFileDialog;$f.Filter=' + "'"+cMascara+"'" + ';$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName"' + CRLF cComando += '' + CRLF cComando += 'for /f "delims=" %%I in (' + "'%ps_cmd%'" + ') do set "filename=%%I"' + CRLF cComando += '' + CRLF cComando += 'if defined filename (' + CRLF cComando += ' echo %filename% > '+cArquivo + CRLF cComando += ')' + CRLF //Gravando em um .bat o comando MemoWrite(cDir + cNomBat, cComando) //Executando o comando através do .bat WaitRun(cDir+cNomBat, 2) //Se existe o arquivo If File(cDir + cArquivo) //Pegando o resultado que o usuário escolheu cResultado := MemoRead(cDir + cArquivo) EndIf Return cResultado
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Sensacional Atílio, utilizando a funcionalidade nativa do Windows. Utilizo PowerShell para scripts de backup, mas nem pensava em mesclar com ADVPL. Parabéns pelo post cara, de verdade! (Só com muita pesquisa mesmo)
Boa noite Fernandão.
Muito obrigado jovem.
Deu um pouco de trabalho descobrir, mas depois ficou dahorinha a função.
Um grande abraço.
Parabéns pela iniciativas de ótima qualidade.
Boa noite mano Súlivan.
Muito obrigado.
Um grande abraço.
Muito legal Atilio.
Estou tentando colocar um multiselect nisso ai agora kkkk.
Boa tarde Felipe, tudo bem?
Eu que agradeço jovem.
Do multiselect, se conseguir algo, mande aqui para gente para mantermos um histórico.
Um grande abraço.
Nunca tinha mexido com batch, nem powershell kkkkk então não sei se está legal, mas funciona kkkk
O comando ficou assim:
cComando += ‘@echo off’ + CRLF
cComando += ‘setlocal’ + CRLF
cComando += ‘set ps_cmd=powershell “Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.OpenFileDialog;$f.Multiselect=$true;$f.Filter=’ + “‘”+cMascara+”‘” + ‘;$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileNames”‘ + CRLF
cComando += ” + CRLF
cComando += ‘ {} > ‘+cArquivo + CRLF
cComando += ‘for /f “delims=” %%I in (‘ + “‘%ps_cmd%'” + ‘) do echo “%%I” >> ‘+cArquivo + CRLF
cComando += ” + CRLF
———————————————————————————————
Dai só removi as aspas e a quebra de linha
cResultado := STRTRAN(cResultado,'”‘,”)
cResultado := STRTRAN(cResultado,’ ‘+chr(13)+chr(10),’|’)
——————————————————————————————–
Depois é só usar a função separa para transformar a string em array
aAnexos := Separa(cResultado,’|’,.f.)
Bom dia Felipe.
Rapaz, muito bom hein, parabéns.
E obrigado por compartilhar.
Um grande abraço.
Fala Dan e Felipe!! Era exatamente isso que eu estava buscando, o multi-select, me ajudou pacas!!
Dan, faz um post disso! Acho que vai ajudar muita gente! Valeu!
Bom dia Ciro.
Opa, vou adicionar aqui na lista de sugestões.
Abraços.
Obrigado por compartilhar. Eu estava com um problema com pastas que contem acentuação, exemplo nota de serviço.
Resolvi usando cResultado := DecodeUTF8(MemoRead(cDir + cArquivo), “cp1252”)
Basta utilizar a função DecodeUTF8
Boa tarde Wagner.
Opa, obrigado pelo comentário e contribuição jovem.
Grande abraço.
Obrigado por compartilhar e pelo ótimo trabalhos
queria deixar uma contribuição para alguém que assim como eu não conseguiu resolver o problema da acentuação só com DecodeUTF8 sitado pelo nosso amigo Wagner de souza.
no meu caso para funcionar tive que acrescentar no script o comando “chcp 65001′”
depois disso funcionou perfeitamente.
cComando += ‘chcp 65001’ + CRLF
cComando += ‘@echo off’ + CRLF
cComando += ‘setlocal’ + CRLF
cComando += ‘set ps_cmd=powershell “Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.OpenFileDialog;$f.Filter=’ + “‘”+cMascara+”‘” + ‘;$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName”‘ + CRLF
cComando += ” + CRLF
cComando += ‘for /f “delims=” %%I in (‘ + “‘%ps_cmd%'” + ‘) do set “filename=%%I”‘ + CRLF
cComando += ” + CRLF
cComando += ‘if defined filename (‘ + CRLF
cComando += ‘ echo %filename% > ‘+cArquivo + CRLF
cComando += ‘)’ + CRLF
//Gravando em um .bat o comando
MemoWrite(cDir + cNomBat, cComando)
//Executando o comando através do .bat
WaitRun(cDir+cNomBat, 2)
//Se existe o arquivo
If File(cDir + cArquivo)
cResultado := MemoRead(cDir + cArquivo)
cResultado :=Upper(Alltrim(FwCutOff(cResultado)))
cDecoRes :=DecodeUTF8(cResultado, ‘cp1252’)//MemoRead(cDir + cArquivo)
If cDecoResNIL
cResultado:=cDecoRes
EndIf
EndIf
Opa, eu que agradeço pelo feedback Reginaldo.
Obrigado pela contribuição.
Grande abraço.
teria como fazer um desse, porém, apenas para selecionar uma pasta e retornar a pasta selecionada?
consegui fazer, aos que quiserem..
@echo off
setlocal
set ps_cmd=powershell “Add-Type -AssemblyName System.windows.forms|Out-Null;$folderBrowser=New-Object System.Windows.Forms.FolderBrowserDialog;$folderBrowser.Description = “Selecione uma pasta”;$folderBrowser.ShowDialog();$folderBrowser.SelectedPath”
for /f “delims=” %%I in (‘%ps_cmd%’) do set “selectedpath=%%I”
if defined selectedpath (
echo %selectedpath% > resultado.txt
)
Opa, muito obrigado pela contribuição jovem.
A título de curiosidade, a TOTVS criou a função TFileDialog – https://tdn.totvs.com/display/tec/tFileDialog , que possui esse e outros recursos, bem melhores que a antiga cGetFile.
Vou fazer um post sobre essa nova funcionalidade nativa futuramente.