CLASSES VISUAIS
TSRCOBJECT
Características
Classe abstrata inicial de todas as classes de interface do Advpl. Não deve ser
instanciada diretamente.
Propriedades
Propriedade Tipo Descrição
nLeft Numérico. Coordenada horizontal em pixels.
nTop Numérico. Coordenada vertical em pixels.
nWidth Numérico. Largura em pixels.
nHeight Numérico. Altura em pixels.
cCaption Caractere. Título ou conteúdo do objeto.
cTooltip Caractere. Mensagem exibida quando objeto exibe seu tooltip.
Flag que ativa .T. ou desativa .F. a exibição do tooltip do
lShowHint Lógico.
objeto.
Mensagem exibida na barra de status da janela principal
cMsg Caractere.
quando o objeto ganha foco.
nClrText Numérico. Cor do texto do objeto.
nClrPane Numérico. Cor do fundo do objeto.
Executado quando há movimentação de foco na [Link]
Bloco de
bWhen retornar .T. o objeto continua habilitado, se retornar .F. o
código.
objeto será desabilitado.
Executado quando o conteúdo do objeto é modificado e
Bloco de
bValid deverá ser validado. Deve retornar .T. se o conteúdo é válido
código.
e .F. se conteúdo inválido.
Bloco de Executado quando acionado click do botão esquerdo do
blClicked
código. mouse sobre o objeto.
Bloco de Executado quando acionado click do botão direito do mouse
brClicked
código. sobre o objeto.
Bloco de Executado quando acionado duplo click do botão esquerdo
blDblClick
código. do mouse sobre o objeto.
oWnd Objeto. Janela onde o objeto foi criado.
lVisible Booleano. Se .T. o objeto é visível, se .F. o objeto é invisível.
Objeto ou
Cargo Conteúdo associado ao objeto.
variável.
Bloco de
bLostFocus Executado quando objeto perde foco.
código.
Bloco de
bGotFocus Executado quando objeto ganha foco.
código.
Métodos
SetFocus
Sintaxe SetFocus( )
Descrição Força o foco de entrada de dados mudar para o objeto.
Retorno NIL
Hide
Sintaxe Hide( )
Descrição Torna objeto invisível.
Retorno NIL
Show
Sintaxe Show( )
Descrição Torna objeto visível.
Retorno NIL
Enable
Sintaxe Enable( )
Descrição Habilita o objeto.
Retorno NIL
Disable
Sintaxe Disable( )
Descrição Desabilita o objeto.
Retorno NIL
Refresh
Sintaxe Refresh( )
Força atualização (sincronia) de propriedades entre o programa e o
Descrição
Protheus Remote.
Características
MSDialog deve ser utilizada como padrão de janela para entrada de dados. MSDialog é
um tipo de janela diálogo modal, isto é, não permite que outra janela ativa receba dados
enquanto esta estiver ativa.
Propriedades
Vide classes ancestrais.
Métodos
New
Descrição Método construtor da classe.
New([anTop], [anLeft], [anBottom], [anRight], [acCaption],
Sintaxe [cPar6], [nPar7], [lPar8], [nPar9], [anClrText], [anClrBack],
[oPar12], [aoWnd], [alPixel], [oPar15], [oPar16], [lPar17])
Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical superior em
anTop
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal esquerda
anLeft
em pixels ou caracteres.
Numérico, opcional. Coordenada vertical inferior em
anBotom
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal direita em
anRight
pixels ou caracteres.
acCaption Caractere, opcional. Título da janela.
cPar6 Reservado.
nPar7 Reservado.
lPar8 Reservado.
Parâmetros
nPar9 Reservado.
anClrText Numérico,opcional. Cor do texto.
anClrBack Numérico,opcional. Cor de fundo.
oPar12 Reservado.
Objeto, opcional. Janela mãe da janela a ser criada,
aoWnd
padrão é a janela principal do programa.
Lógico, opcional. Se .T. considera as coordenadas
alPixel
passadas em pixels, se .F. considera caracteres.
oPar15 Reservado.
oPar16 Reservado.
nPar17 Reservado.
Retorno O Diálogo criado.
Exemplo
#INCLUDE “[Link]”
User Function Teste()
// cria diálogo
Local oDlg:=MSDialog():New(10,10,300,300,”Meu
dialogo”,,,,,CLR_BLACK,CLR_WHITE,,,.T.)
// ativa diálogo centralizado
oDlg:Activate(,,,.T.,{||msgstop(“validou!”),.T.},,{||
msgstop(“iniciando…”) )
Return
Descrição
Utilize a classe tButton para criar um controle visual do tipo botão.
Propriedades
Nome Tipo / Descrição
lProcessing Lógico. Se .T. indica o botão está efetuando uma ação.
bAction Bloco de código. Executado quando o botão é pressionado.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [acCaption], [aoWnd], [abAction],
Sintaxe [anWidth], [anHeight], [nPar8], [aoFont], [lPar10], [alPixel],
[lPar12],[cPar13], [lPar14], [abWhen], [bPar16], [lPar17])
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
carateres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
acCaption Caractere, opcional. Titulo do botão.
Objeto, opcional. Janela ou controle onde o botão
aoWnd
deverá ser criado.
Bloco de código, opcional. Bloco que deverá ser
abAction
acionado quando o botão for pressionado.
anWidth Numérico, opcional. Largura do botão em pixels.
anHeight Numérico, opcional. Altura do botão em pixels.
nPar8 Reservado.
Objeto, opcional. Objeto tipo tFont com propriedades da
aoFont
fonte utilizada para o título do botão.
lPar10 Reservado.
alPixel Lógico, opcional. Se .T. considera as coordenadas
passadas em pixels, se .F. (padrão) considera em
caracteres.
lPar12 Reservado.
cPar13 Reservado.
lPar14 Reservado.
Bloco de código, opcional. Executado quando mudança
de foco de entrada de dados está sendo efetuada na
abWhen janela onde o controle foi criado. O bloco deve
retornar .T. se o controle deve permanecer habilitado ou
.F. se não.
bPar16 Reservado.
lPar17 Reservado.
Exemplo
#include “[Link]”
User Function TesteGet()
Local oDlg, oButton, oCombo, cCombo, aItems:=
{“item1”,”item2”,”item3”}
cCombo:= aItems[2]
DEFINE MSDIALOG oDlg FROM 0,0 TO 300,300 PIXEL TITLE “Meu Combo”
oCombo:= tComboBox():New(10,10,{|u|if(PCount()>0,cCombo:=u,cCombo)},;
aItems,100,20,oDlg,,{||MsgStop(“Mudou item”)},,,,.T.,,,,,,,,,”cCombo”)
// Botão para fechar a janela
oButton:=tButton():New(30,10,”fechar”,oDlg,{||
oDlg:End()},100,20,,,,.T.)
ACTIVATE MSDIALOG oDlg CENTERED
MsgStop( “O valor é ”+cCombo )
Return NIL
Descrição
Utilize a classe tCheckbox quando desejar criar um controle que possua dois estados .T.
ou .F..
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [acCaption], [abSetGet], [aoWnd],
[anWidth], [anHeight], [nPar8], [abClick], [aoFont], [abValid],
Sintaxe
[anClrFore], [anClrBack], [lPar14], [alPixel], [cPar16], [lPar17],
[abWhen])
Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
carateres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
acCaption Caractere, opcional. Texto exibido pelo controle.
Bloco de código, opcional. Bloco de código no formato
{|u| if( Pcount( )>0, <var>:= u, <var> ) } que o controle
abSetGet utiliza para atualizar a variável <var>. <var> deve ser
tipo lógico, se <var> = .T. então o controle aparecerá
checado.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
deverá ser criado.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
nPar8 Reservado.
Bloco de código, opcional. Executado quando o
abClick controle click do botão esquerdo do mouse é acionado
Parâmetros sobre o controle.
Objeto, opcional. Objeto tipo tFont com propriedades
aoFont
da fonte utilizada para o texto do controle.
Bloco de código, opcional. Executado quando o
conteúdo do controle deve ser validado, deve
abValid
retornar .T. se o conteúdo for válido e .F. quando o
conteúdo for inválido.
anClrFore Numérico, opcional. Cor de fundo do controle.
anClrBack Numérico, opcional. Cor do texto do controle.
lPar14 Reservado.
Lógico, opcional. Se .T. as coordenadas informadas são
alPixel
em pixels, se .F. são em caracteres.
cPar16 Reservado.
lPar17 Reservado.
Bloco de código, opcional. Executado quando mudança
de foco de entrada de dados está sendo efetuada na
abWhen janela onde o controle foi criado. O bloco deve
retornar .T. se o controle deve permanecer habilitado ou
.F. se não.
Retorno O objeto construído.
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oButton, oCheck, lCheck:=.F.
DEFINE MSDIALOG oDlg FROM 0,0 TO 300,300 PIXEL TITLE “Meu programa”
oCheck:= tCheckBox():New(10,10,”funcionou?”,;
{|u|if( pcount()>0,lCheck:=u,lCheck)};
,oDlg,100,20,,,,,,,,.T.)
oButton:=tButton():New(30,10,”fechar”,oDlg,{||oDlg:End()},;
100,20,,,,.T.)
ACTIVATE MSDIALOG oDlg CENTERED
If lCheck
MsgStop( “Funcionou!” )
Endif
Return NIL
Descrição
Utilize a classe tComboBox para cria uma entrada de dados com múltipla escolha com
item definido em uma lista vertical, acionada por F4 ou pelo botão esquerdo localizado
na parte direita do controle. A variável associada ao controle terá o valor de um dos
itens selecionados ou no caso de uma lista indexada, o valor de seu índice.
Propriedades
Nome Tipo / Descrição
Array. Lista de itens, caracteres, a serem exibidos. Pode ter os seguintes
aItems formatos: a) Seqüencial, exemplo: {“item1”,”item2”,...,”itemN”} ou b) Indexada,
exemplo: {“a=item1”,”b=item2”, ..., “n=itemN”}.
nAt Numérico. Posição do item selecionado.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [abSetGet], [anItems], [anWidth],
[anHeight], [aoWnd], [nPar8], [abChange], [abValid], [anClrText],
Sintaxe
[anClrBack], [alPixel], [aoFont], [cPar15], [lPar16], [abWhen],
[lPar18], [aPar19], [bPar20], [cPar21], [acReadVar])
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
Bloco de código, opcional. Bloco de código no formato
{|u| if( Pcount( )>0, <var>:= u, <var> ) } que o controle
utiliza para atualizar a variável <var>. <var> deve ser
abSetGet tipo caracter. Se a lista for seqüencial, o controle
atualizará <var> com o conteúdo do item selecionado,
se a lista for indexada, <var> será atualizada com o
valor do índice do item selecionado.
Array, opcional. Lista de items, caracteres, a serem
exibidos. Pode ter os seguintes formatos: a) Seqüencial,
anItems exemplo: {“item1”,”item2”,...,”itemN”} ou b)
Indexada, exemplo: {“a=item1”,”b=item2”, ...,
“n=itemN”}.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
nPar8 Reservado.
Bloco de código, opcional. Executado quando o
abChange
controle modifica o item selecionado.
Bloco de código, opcional. Executado quando o
conteúdo do controle deve ser validado, deve
abValid
retornar .T. se o conteúdo for válido e .F. quando o
conteúdo for inválido.
anClrBack Numérico, opcional. Cor de fundo do controle.
anClrText Numérico, opcional. Cor do texto do controle.
Lógico, opcional. Se .T. as coordenadas informadas são
alPixel
em pixels, se .F. são em caracteres.
Objeto, opcional. Objeto tipo tFont utilizado para
aoFont definir as características da fonte utilizada para exibir o
conteúdo do controle.
cPar15 Reservado.
lPar16 Reservado.
Bloco de código, opcional. Executado quando mudança
de foco de entrada de dados está sendo efetuada na
abWhen janela onde o controle foi criado. O bloco deve retornar
.T. se o controle deve permanecer habilitado ou .F. se
não.
lPar18 Reservado.
aPar19 Reservado.
bPar20 Reservado.
cPar21 Reservado.
acReadVar Caractere, opcional. Nome da variável que o controle
deverá manipular, deverá ser a mesma variável
informada no parâmetro abSetGet, e será o retorno da
função ReadVar( ).
Retorno O objeto criado.
Select
Descrição Muda o item selecionado no combobox.
Sintaxe Select( [anItem] )
Parâmetro Tipo / Descrição
Parâmetros
anItem Numérico, opcional. Posição do item a ser selecionado.
Retorno NIL
Exemplo
#include “[Link]”
User Function TesteGet()
Local oDlg, oButton, oCombo, cCombo, aItems:=
{“item1”,”item2”,”item3”}
cCombo:= aItems[2]
DEFINE MSDIALOG oDlg FROM 0,0 TO 300,300 PIXEL TITLE “Meu Combo”
oCombo:= tComboBox():New(10,10,{|u|if(PCount()>0,cCombo:=u,cCombo)},;
aItems,100,20,oDlg,,{||MsgStop(“Mudou item”)},;
,,,.T.,,,,,,,,,”cCombo”)
// Botão para fechar a janela
@ 40,10 BUTTON oButton PROMPT “Fechar” OF oDlg PIXEL ACTION oDlg:End()
ACTIVATE MSDIALOG oDlg CENTERED
MsgStop( “O valor é ”+cCombo )
Return NIL
Características
tControl é a classe comum entre todos os componentes visuais editáveis.
Propriedades
Nome Tipo / Descrição
Align Numérico. Alinhamento do controle no espaço disponibilizado pelo seu
objeto parente. 0 = Nenhum (padrão), 1= no topo, 2 = no rodapé, 3= a
esquerda, 4 = a direita e 5 = em todo o parente.
Lógico. Se .T. indica que o conteúdo da variável associada ao controle foi
lModified
modificado.
Lógico. Se .T. o conteúdo da variável associada ao controle permanecerá
lReadOnly
apenas para leitura.
Numérico. Handle (identificador) do objeto sobre o qual o controle foi
hParent
criado.
Bloco de código. Executado quando o estado ou conteúdo do controle é
bChange
modificado pela ação sobre o controle.
Métodos
SetFocus
Descrição Força mudança do foco de entrada de dados para o controle.
Sintaxe SetFocus( )
REtorno NIL
Descrição
Utilize objeto tFont para modificar a fonte padrão de controles visuais.
Propriedades
Vide classes ancestrais.
Métodos
New
Descrição Método construtor da classe.
New([acName], [nPar2], [anHeight], [lPar4], [alBold], [nPar6],
Sintaxe
[lPar7], [nPar8], [alItalic], [alUnderline])
Parâmetros Parâmetro Tipo / Descrição
Caractere, opcional. Nome da fonte, o padrão é
acName
“Arial”.
nPar2 Reservado.
Numérico, opcional. Tamanho da fonte. O padrão é -
anHeight
11.
lPar4 Reservado.
alBold Lógico, opcional. Se .T. o estilo da fonte será negrito.
nPar6 Reservado.
lPar7 Reservado.
nPar8 Reservado.
alItalic Lógico, opcional. Se .T. o estilo da fonte será itálico.
Lógico, opcional. Se .T. o estilo da fonte será
alUnderline
sublinhado.
Retorno O objeto criado.
Exemplo
#INCLUDE "[Link]"
User Function Teste()
Local oDlg, oSay
Local oFont:= TFont():New("Courier New",,-14,.T.)
DEFINE MSDIALOG oDlg FROM 0,0 TO 200,200 TITLE "My dialog" PIXEL
// Apresenta o tSay com a fonte Courier New
oSay := TSay():New( 10, 10, {|| "Mensagem"},oDlg,, oFont,,,, .T.,
CLR_WHITE,CLR_RED )
/* o comando abaixo proporciona o mesmo resultado
@ 10,10 SAY oSay PROMPT "Mensagem" FONT oFont COLOR CLR_WHITE,CLR_RED
OF oDlg PIXEL
*/
oSay:lTransparent:= .F.
ACTIVATE MSDIALOG oDlg CENTERED
Return
Descrição
Use tGet para criar um controle que armazene ou altere o conteúdo de uma variável
através de digitação. O conteúdo da variável só é modicado quando o controle perde o
foco de edição para outro controle.
Propriedades
Nome Tipo / Descrição
lPassword Lógico. Se .T. o controle se comporta como entrada de dados de senha,
exibindo asteriscos ‘*’ para esconder o conteúdo digitado.
Picture Caractere. Máscara de formatação do conteúdo a ser exibido.
Métodos
New
Descrição Método construtor do controle.
New([anRow], [anCol], [abSetGet], [aoWnd], [anWidth],
[anHeight], [acPict], [abValid], [anClrFore], [anClrBack], [aoFont],
Sintaxe [lPar12], [oPar13], [alPixel], [cPar15], [lPar16], [abWhen],
[lPar18], [lPar19], [abChange], [alReadOnly], [alPassword],
[cPar23], [acReadVar], [cPar25], [lPar26], [nPar27], [lPar28])
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
Bloco de código, opcional. Bloco de código no
formato {|u| if( Pcount( )>0, <var>:= u, <var> ) } que
abSetGet
o controle utiliza para atualizar a variável <var>.
<var> deve ser tipo caracter, numérico ou data.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Caractere, opcional. Máscara de formatação do
acPict
conteúdo a ser exibido.
Bloco de código, opcional. Executado quando o
conteúdo do controle deve ser validado, deve
abValid
retornar .T. se o conteúdo for válido e .F. quando o
conteúdo for inválido.
anClrFore Numérico, opcional. Cor de fundo do controle.
anClrBack Numérico, opcional. Cor do texto do controle.
Objeto, opcional. Objeto tipo tFont utilizado para
aoFont definir as características da fonte utilizada para exibir
o conteúdo do controle.
lPar12 Reservado.
oPar13 Reservado.
Lógico, opcional. Se .T. as coordenadas informadas
alPixel
são em pixels, se .F. são em caracteres.
cPar15 Reservado.
lPar16 Reservado.
abWhen Bloco de código, opcional. Executado quando
mudança de foco de entrada de dados está sendo
efetuada na janela onde o controle foi criado. O bloco
deve retornar .T. se o controle deve permanecer
habilitado ou .F. se não.
lPar18 Reservado.
lPar19 Reservado.
Bloco de código, opcional. Executado quando o
abChange
controle modifica o valor da variável associada.
Lógico, opcional. Se .T. o controle não poderá ser
alReadOnly
editado.
Lógico, opcional. Se .T. o controle exibirá asteriscos
alPassword “*” no lugar dos caracteres exibidos pelo controle para
simular entrada de senha.
cPar23 Reservado.
Caractere, opcional. Nome da variável que o controle
deverá manipular, deverá ser a mesma variável
acReadVar
informada no parâmetro abSetGet, e será o retorno da
função ReadVar( ).
cPar25 Reservado.
lPar26 Reservado.
nPar27 Reservado.
lPar28 Reservado.
Retorno O controle construído.
Exemplo
#include “[Link]”
User Function TesteGet()
Local oDlg, oGet1, oButton, nGet1:=0
DEFINE MSDIALOG oDlg FROM 0,0 TO 300,300 PIXEL TITLE “Meu Get”
oGet1:= TGet():New(10,10,{|u| if(PCount()>0,nGet1:=u,nGet1}}, oDlg,;
100,20,”@E 999,999.99”,;
{|o|nGet1>1000.00},,,,,,.T.,,,,,,,,,,”nGet1”)
/* Tem o mesmo efeito
@ 10,10 MSGET oGet1 VAR nGet1 SIZE 100,20 OF oDlg PIXEL PICTURE “@E
999,999.99” VALID nGet1>1000.00
*/
// Botão para fechar a janela
@ 40,10 BUTTON oButton PROMPT “Fechar” OF oDlg PIXEL ACTION oDlg:End()
ACTIVATE MSDIALOG oDlg CENTERED
MsgStop( “O valor é ”+Transform(nGet1,”@E 999,999.00”) )
Return NIL
Descrição
Utilize a classe tGroup para criar um painel onde controles visuais podem ser agrupados
ou classificados. É criada uma borda com título em volta dos controles agrupados.
Métodos
New
Descrição Método construtor da classe.
New([anTop], [anLeft], [anBottom], [anRight], [acCaption],
Sintaxe
[aoWnd], [anClrText], [anClrPane], [alPixel], [lPar10])
Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical superior em
anTop
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal esquerda
anLeft
em pixels ou caracteres.
Numérico, opcional. Coordenada vertical inferior em
anBottom
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal direita em
anRight
Parâmetros pixels ou caracteres.
acCaption Caractere, opcional. Título do grupo.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
anClrText Numérico, opcional. Cor do texto.
anClrPane Numérico, opcional. Cor do fundo.
Lógico, opcional. Se .T. as coordenadas informadas são
alPixel
em pixels, se .F. são em caracteres.
lPar10 Reservado.
Retorno O objeto criado.
Exemplo
#include “[Link]”
User function teste()
Local oDlg, oGroup, oGet1, oGet2, cGet1:=Space(10),;
cGet2:= Space(10)
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 TITLE “My test” PIXEL
oGroup:= tGroup():New(10,10,200,200,”grupo de gets”,oDlg,,,.T.)
@ 10,10 MSGET oGet1 VAR cGet1 SIZE 100,10 OF oGroup PIXEL
@ 30,10 MSGET oGet2 VAR cGet2 SIZE 100,10 OF oGroup PIXEL
ACTIVATE MSDIALOG oDlg CENTERED
Return NIL
Descrição
Utilize a classe tListbox para criar uma janela com itens selecionáveis e barra de
rolagem. Ao selecionar um item, uma variável é atualizada com o conteúdo do item
selecionado.
Propriedades
Nome Tipo / Descrição
nAt Numérico. Posição do item selecionado.
aItems Array de items caracteres. Lista do itens selecionáveis.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [abSetGet], [aaItems], [anWidth],
[anHeigth], [abChange], [aoWnd], [abValid], [anClrFore],
Sintaxe [anClrBack], [alPixel], [lPar13], [abLDBLClick], [aoFont],
[cPar16], [lPar17], [abWhen], [aPar19], [bPar20], [lPar21],
[lPar22], [abRightClick] )
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels
anRow
ou caracteres.
Numérico, opcional. Coordenada horizontal em
anCol
pixels ou caracteres.
Bloco de código, opcional. Bloco de código no
formato {|u| if( Pcount( )>0, <var>:= u, <var> )}
abSetGet
que o controle utiliza para atualizar a variável
<var>. <var> deve ser tipo caracter ou numérica.
Array de items caracteres, opcional. Lista de items
aaItems
selecionáveis.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Bloco de código, opcional. Executado quando o
abChange
item selecionado é alterado.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
Bloco de código, opcional. Executado quando o
conteúdo do controle deve ser validado, deve
abValid
retornar .T. se o conteúdo for válido e .F. quando o
conteúdo for inválido.
anClrFore Numérico, opcional. Cor de fundo do controle.
anClrBack Numérico, opcional. Cor do texto do controle.
Lógico, opcional. Se .T. as coordenadas informadas
alPixel
são em pixels, se .F. são em caracteres.
lPar13 Reservado.
Bloco de código, opcional. Executado quando
abLDBLClick acionado duplo click do botão esquerdo do mouse
sobre o controle.
Objeto, opcional. Objeto tipo tFont utilizado para
aoFont definir as características da fonte utilizada para
exibir o conteúdo do controle.
cPar16 Reservado.
lPar17 Reservado.
Bloco de código, opcional. Executado quando
mudança de foco de entrada de dados está sendo
abWhen efetuada na janela onde o controle foi criado. O
bloco deve retornar .T. se o controle deve
permanecer habilitado ou .F. se não.
aPar19 Reservado.
bPar20 Reservado.
lPar21 Reservado.
lPar22 Reservado.
Bloco de código, opcional. Executado quando
abRightClick acionado click do botão direito do mouse sobre o
controle.
Retorno O objeto criado.
Select
Descrição Força a seleção de um item.
Sintaxe Select( [anItem] )
Parâmetro Tipo / Descrição
Parâmetros
nItem Numérico, opcional. Posição do item a ser selecionado.
Retorno NIL
Add
Descrição Insere ou adiciona novo item.
Sintaxe Add( cText, nPos )
Parâmetro Tipo / Descrição
cText Caractere, obrigatório. Texto do item.
Parâmetros Numérico, obrigatório. Se 0 ou maior que o número de
itens, insere o item no final da lista. Se valor entre 1 e
nPos
número de itens, insere o item na posição informada,
empurrando o item anterior para baixo.
Retorno NIL
Modify
Descrição Modifica o texto de um item.
Sintaxe Modify( cText, nPos )
Parâmetro Tipo / Descrição
cText Caractere, obrigatório. Novo texto do item.
Parâmetros
Numérico, obrigatório. Posição a ser modificada deve
nPos
ser maior que 0 e menor ou igual que o número de itens.
Retorno NIL
Del
Descrição Apaga um item.
Sintaxe Del( nPos )
Parâmetro Tipo / Descrição
Parâmetros Numérico, obrigatório. Posição a ser excluida, deve ser
nPos
maior que 0 e menor ou igual que o número de itens.
Retorno NIL
Len
Descrição Retorna o número de itens.
Sintaxe Len( )
Retorno Numérico. Número de itens.
Reset
Descrição Apaga todos os itens.
Sintaxe Reset( )
Retorno NIL
Exemplo
#include “[Link]”
User Funcion Teste()
Local oDlg, oList, nList:= 1, aItems:={}
Aadd(aItems,”Item 1”)
Aadd(aItems,”Item 2”)
Aadd(aItems,”Item 3”)
Aadd(aItems,”Item 4”)
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 PIXEL TITLE “Teste”
oList:= tListBox():New(10,10,{|u|if(Pcount()>0,nList:=u,nList)};
,aItems,100,100,,oDlg,,,,.T.)
ACTIVATE MSDIALOG oDlg CENTERED
Return NIL
Descrição
Utilize a classe tMeter para criar um controle que exibe uma régua (gauge) de
processamento, descrevendo o andamento de um processo atraves da exibição de uma
barra horizontal.
Propriedades
Nome Tipo / Descrição
Numérico. Número total de passos até o preenchimento da régua de
nTotal
processo.
lPercentage Lógico. Se .T. considera o passo de movimentação em porcentagem.
nClrBar Numérico. Cor da barra de andamento.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [abSetGet], [anTotal], [aoWnd], [anWidth],
Sintaxe [anHeight], [lPar8], [alPixel], [oPar10], [cPar11], [alNoPerc],
[anClrPane], [nPar14], [anClrBar], [nPar16], [lPar17])
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
Bloco de código, opcional. Bloco de código no formato
{|u| if( Pcount( )>0, <var>:= u, <var> ) } que o controle
abSetGet
utiliza para atualizar a variável <var>. <var> deve ser
tipo numérico.
Numérico, opcional. Numero total de passos até o
anTotal
preenchimento da régua de processo.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
sera criado.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
lPar8 Reservado.
Lógico, opcional. Se .T. as coordenadas informadas são
alPixel
em pixels, se .F. são em caracteres.
oPar10 Reservado.
cPar11 Reservado.
Lógico, opcional. Se .T. (padrão) não considera os
alNoPerc
passos de atualização em porcentagem.
anClrPane Numérico, opcional. Cor de fundo do controle.
nPar14 Reservado.
anClrBar Numérico, opcional. Cor da barra de andamento.
nPar16 Reservado.
lPar17 Reservado.
Retorno O objeto criado.
Set
Descrição Atualiza a posição da régua de processamento.
Sintaxe Set( [nVal] )
Parâmetro Tipo / Descrição
Parâmetros Numérico, opcional. Novo valor da posição da régua de
nVal
processamento.
Retorno NIL
Exemplo
#include “[Link]”
STATIC lRunning:=.F., lStop:=.F.
User Function Teste()
Local oDlg, oMeter, nMeter:=0, oBtn1, oBtn2
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 TITLE “Teste”
oMeter:= tMeter():New(10,10,{|u|if(Pcount()>0,nMeter:=u,nMeter)};
,100,oDlg,100,20,,.T.) // cria a régua
// botão para ativar andamento da régua
@ 30,10 BUTTON oBtn1 PROMPT “Run” OF oDlg PIXEL ACTION
RunMeter(oMeter)
@ 50,10 BUTTON oBtn2 PROMPT “Stop” OF oDlg PIXEL ACTION lStop:=.T.
ACTIVATE MSDIALOG oDlg CENTERED
Return NIL
STATIC Function RunMeter(oMeter)
If lRunning
Return
Endif
lRunning:= .T.
oMeter:Set(0) // inicia a régua
While .T. .and. !lStop
Sleep(1000) // pára 1 segundo
ProcessMessages() // atualiza a pintura da janela, processa
mensagens do windows
nCurrent:= Eval(oMeter:bSetGet) // pega valor corrente da régua
nCurrent+=10 // atualiza régua
oMeter:Set(nCurrent)
if nCurrent==oMeter:nTotal
Return
endif
Enddo
lRunning:= .F.
lStop:= .F.
Return
Descrição
Utilize a classe tMultiget para criar controle de edição de texto de múltiplas linhas.
Propriedades
Nome Tipo / Descrição
lWordWrap Lógico. Se .T., faz quebra automática de linhas.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [abSetGet], [aoWnd], [anWidth],
[anHeight], [aoFont], [alHScroll], [anClrFore], [anClrBack],
Sintaxe [oPar11], [alPixel], [cPar13], [lPar14], [abWhen], [lPar16],
[lPar17], [alReadOnly], [abValid], [bPar20], [lPar21],
[alNoBorder], [alNoVScroll])
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels
anRow
ou caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
Bloco de código, opcional. Bloco de código no
formato {|u| if( Pcount( )>0, <var>:= u, <var> ) } que
abSetGet
o controle utiliza para atualizar a variável <var>.
<var> deve ser tipo caracter.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Objeto, opcional. Objeto tipo tFont utilizado para
aoFont definir as características da fonte utilizada para exibir
o conteúdo do controle.
Lógico, opcional. Se .T., habilita barra de rolagem
alHScroll
horizontal.
anClrFore Numérico, opcional. Cor de fundo do controle.
anClrBack Numérico, opcional. Cor do texto do controle.
oPar11 Reservado.
Lógico, opcional. Se .T. as coordenadas informadas
alPixel
são em pixels, se .F. são em caracteres.
cPar13 Reservado.
lPar14 Reservado.
Bloco de código, opcional. Executado quando
mudança de foco de entrada de dados está sendo
abWhen efetuada na janela onde o controle foi criado. O bloco
deve retornar .T. se o controle deve permanecer
habilitado ou .F. se não.
lPar16 Reservado.
lPar17 Reservado.
Lógico, opcional. Se .T. o controle so permitira
alReadOnly
leitura.
Bloco de código, opcional. Executado quando o
conteúdo do controle deve ser validado, deve retornar
abValid
.T. se o conteúdo for válido e .F. quando o conteúdo
for inválido.
bPar20 Reservado.
lPar21 Reservado.
alNoBorder Lógico, opcional. Se .T. cria controle sem borda.
Lógico, opcional. Se .T., habilita barra de rolagem
alNoVScroll
vertical.
Retorno O objeto criado.
EnableVScroll
Descrição Habilita a barra de rolagem vertical.
Sintaxe EnableVScroll( lEnable )
Parâmetro Tipo / Descrição
Parâmetros Lógico, obrigatório. Se .T. habilita se .F. desabilita a
lEnable
barra de rolagem.
Retorno NIL
EnableHScroll
Descrição Habilita a barra de rolagem horizontal.
Sintaxe EnableHScroll( lEnable )
Parâmetro Tipo / Descrição
Parâmetros Lógico, obrigatório. Se .T. habilita se .F. desabilita a
lEnable
barra de rolagem.
Retorno NIL
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oMemo, cMemo:= space(50)
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 PIXEL TITLE “My test”
oMemo:= tMultiget():New(10,10,{|u|if(Pcount()>0,cMemo:=u,cMemo)};
,oDlg,100,100,,,,,,.T.)
@ 200,10 BUTTON oBtn PROMPT “Fecha” OF oDlg PIXEL ACTION oDlg:End()
ACTIVATE MSDIALOG oDlg CENTERED
MsgStop(cMemo)
Return NIL
Descrição
Utilize a classe tPanel quando desejar criar um painel estático, onde podem ser criados
outros controles com o objetivo de organizar ou agrupar componentes visuais.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [acText], [aoWnd], [aoFont], [alCentered],
Sintaxe [lPar6], [anClrText], [anClrBack], [anWidth], [anHeight],
[alLowered], [alRaised])
Parâmetros Parâmetro Tipo / Descrição
anRow Numérico, opcional. Coordenada vertical em pixels.
anCol Numérico, opcional. Coordenada horizontal em pixels.
acText Caractere, opcional. Texto a ser exibido ao fundo.
Objeto, opcional. Janela ou controle onde será criado o
aoWnd
objeto.
Lógico, opcional. Se .T. exibe o texto de título ao
alCentered
centro do controle.
lPar6 Reservado.
anClrText Numérico, opcional. Cor do texto do controle.
anClrBack Numérico, opcional. Cor do fundo do controle.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Lógico, opcional. Se .T. exibe o painel rebaixado em
alLowered
relação ao controle de fundo.
Lógico, opcional. Se .T. exibe a borda do controle
alRaised
rebaixada em relação ao controle de fundo.
Retorno O objeto criado.
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oPanel, oBtn1, oBtn2
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 PIXEL TITLE “My test”
oPanel:= tPanel():New(10,10,””,oDlg,,,,,CLR_BLUE,100,100) // cria o
painel
@ 10,10 BUTTON oBtn1 PROMPT “hide” OF oPanel ACTION oPanel:Hide() //
cria botão sobre o painel
@ 200,10 BUTTON oBtn2 PROMPT “show” OF oDlg ACTION oPanel:Show() //
cria botão fora o painel
ACTIVATE MSDIALOG oDlg CENTERED
Return
Descrição
Utilize a classe tRadMenu para criar um controle que possibilita escolha de item através
de uma lista.
Propriedades
Nome Tipo / Descrição
nOption Numérico. Item selecionado.
aItems Array de caracteres. Lista de items selecionáveis.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [aacItems], [abSetGet], [aoWnd], [aPar6],
Sintaxe [abChange], [anClrText], [anClrPan], [cPar10], [lPar11], [abWhen],
[anWidth], [anHeight], [abValid], [lPar16], [lPar17], [alPixel])
Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
aacItems Array de caracteres, opcional. Lista de opções.
Bloco de código, opcional. Bloco de código no formato
{|u| if( Pcount( )>0, <var>:= u, <var> ) } que o controle
abSetGet
utiliza para atualizar a variável <var>. <var> deve ser
tipo numérico.
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
aPar6 Reservado.
Bloco de código, opcional. Executado quando o item
abChange
selecionado é alterado.
anClrText Numérico, opcional. Cor do texto do controle
Parâmetros anClrPan Numérico, opcional. Cor de fundo do controle.
cPar10 Reservado.
lPar11 Reservado.
Bloco de código, opcional. Executado quando mudança
de foco de entrada de dados está sendo efetuada na
abWhen janela onde o controle foi criado. O bloco deve
retornar .T. para que o controle permaneça habilitado,
ou .F. se não.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
Bloco de código, opcional. Executado quando o
abValid conteúdo do controle deva ser validado, retornando .T.
se o conteúdo for válido, e .F. quando inválido.
lPar16 Reservado.
Lpar17 Reservado.
Lógico, opcional. Se .T. as coordenadas informadas são
alPixel
em pixels, se .F. são em caracteres.
Retorno O objeto criado.
EnableItem
Descrição Habilita ou desabilita item.
Sintaxe EnableItem( [nItem], [lEnable])
Parâmetro Tipo / Descrição
nItem Numérico, opcional. Item selecionado.
Parâmetros
Lógico, opcional. Se .T. habilita o item se .F. desabilita
lEnable
o item.
Retorno NIL
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oButton, oRadio, nRadio:=1
Local aOptions:={“escolha1”,”escolha2”}
DEFINE MSDIALOG oDlg FROM 0,0 TO 300,300 PIXEL TITLE “Meu Get”
oRadio:= tRadMenu():New(10,10,aOptions,;
{|u|if(PCount()>0,nRadio:=u,nRadio)},;
oDlg,,,,,,,,100,20,,,,.T.)
@ 40,10 BUTTON oButton PROMPT “Fechar” OF oDlg PIXEL ACTION oDlg:End()
ACTIVATE MSDIALOG oDlg CENTERED
MsgStop(“Escolheu “+aOptions[nRadio] )
Return NIL
Descrição
O objeto tipo tSay exibe o conteúdo de texto estático sobre uma janela ou controle.
Propriedades
Nome Tipo / Descrição
Lógico. Se .T. quebra o texto em várias linhas de maneira a enquadrar o
lWordWrap
conteúdo na área determinada para o controle, sendo o padrão .F.
Lógico. Se .T. a cor de fundo do controle é ignorada assumindo o conteúdo
lTransparent
ou cor do controle ou janela ao fundo, sendo o padrão .T.
Métodos
New
Descrição Método construtor da classe.
New([anRow], [anCol], [abText], [aoWnd], [acPicture], [aoFont],
[lPar7], [lPar8], [lPar9], [alPixels], [anClrText], [anClrBack],
Sintaxe
[anWidth], [anHeight], [lPar15], [lPar16], [lPar17], [lPar18],
[lPar19])
Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical em pixels ou
anRow
caracteres.
Numérico, opcional. Coordenada horizontal em pixels
anCol
ou caracteres.
Codeblock, opcional. Quando executado deve retornar
abText
uma cadeia de caracteres a ser exibida.
Objeto, opcional. Janela ou diálogo onde o controle
aoWnd
será criado.
Caractere, opcional. Picture de formatação do conteúdo
acPicture
a ser exibido.
Objeto, opcional. Objeto tipo tFont para configuração
aoFont do tipo de fonte que será utilizado para exibir o
conteúdo.
Parâmetros lPar7 Reservado.
lPar8 Reservado.
lPar9 Reservado.
Lógico, opcional. Se .T. considera coordenadas
alPixels passadas em pixels se .F., padrão, considera as
coordenadas passadas em caracteres.
anClrText Numérico, opcional. Cor do conteúdo do controle.
anClrBack Numérico, opcional. Cor do fundo do controle.
anWidth Numérico, opcional. Largura do controle em pixels.
anHeight Numérico, opcional. Altura do controle em pixels.
lPar15 Reservado.
lPar16 Reservado.
lPar17 Reservado.
lPar18 Reservado.
lPar19 Reservado.
Retorno O objeto criado.
SetText
Descrição Modifica o conteúdo a ser exibido pelo controle.
Sintaxe SetText( [xVal] )
Parâmetro Tipo / Descrição
Parâmetros Caracter / Numérico / Data, Opcional. Valor a ser
xVal
exibido.
Retorno NIL
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oSay
DEFINE MSDIALOG oDlg FROM 0,0 TO 200,200 TITLE “My dialog” PIXEL
oSay:= tSay():New(10,10,{||”para exibir”},oDlg,,,,;
,,.T.,CLR_WHITE,CLR_RED,100,20)
ACTIVATE MSDIALOG oDlg CENTERED
Return NIL
Descrição
Utilize a classe tScrollbox para criar um painel com scroll deslizantes nas laterais do
controle.
Métodos
New
Descrição Método construtor da classe.
New([aoWnd], [anTop], [anLeft], [anHeight], [anWidth],
Sintaxe
[alVertical], [alHorizontal], [alBorder])
Parâmetro Tipo / Descrição
Objeto, opcional. Janela ou controle onde o controle
aoWnd
será criado.
anTop Numérico, opcional. Coordenada vertical em pixels.
Numérico, opcional. Coordenada horizontal em
anLeft
pixels.
Parâmetros anHeight Numérico, opcional. Altura do controle em pixels.
anWidth Numérico, opcional. Largura do controle em pixels.
Lógico, opcional. Se .T. exibe a barra de scroll
alVertical
vertical.
Lógico, opcional. Se .T. exibe a barra de scroll
alHorizontal
horizontal.
alBorder Lógico, opcional. Se .T. exibe a borda do controle.
Retorno O objeto criado.
Exemplo
#include “[Link]”
User Function Teste()
Local oDlg, oScr, oGet1, oGet2, oGet3
Local cGet1, cGet2, cGet3
cGet1:= Space(10)
cGet2:= Space(10)
cGet3:= Space(10)
DEFINE MSDIALOG oDlg FROM 0,0 TO 400,400 PIXEL “My test”
oScr:= TScrollBox():New(oDlg,10,10,200,200,.T.,.T.,.T.) // cria
controles dentro do scrollbox
@ 10,10 MSGET oGet1 VAR cGet1 SIZE 100,10 OF oScr PIXEL
@ 50,10 MSGET oGet2 VAR cGet2 SIZE 100,10 OF oScr PIXEL
@ 150,100 MSGET oGet3 VAR cGet3 SIZE 100,10 OF oScr PIXEL
ACTIVATE MSDIALOG oDlg CENTERED
Return NIL
Características
Classe de janela principal de programa, deverá existir apenas uma instância deste objeto
na execução do programa.
Propriedades
bInit Bloco de código. Executado quando a janela está sendo exibida.
lEscClose Lógico. Se .T. habilita o <ESC> cancelar a execução da janela.
oCtlFocus Objeto. Objeto contido na janela que está com foco de entrada de dados.
Métodos
New
Descrição Método construtor da janela.
New( [anTop], [anLeft],[anBottom], [anRight], [acTitle], [nPar6],
[oPar7] ,[oPar8],[oPar9], [aoParent], [lPar11], [lPar12],
Sintaxe
[anClrFore], [anClrBack], [oPar15], [cPar16], [lPar17], [lPar18],
[lPar19], [lPar20], [alPixel] );
Parâmetros Parâmetro Tipo / Descrição
Numérico, opcional. Coordenada vertical superior em
nTop
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal esquerda
nLeft
em pixels ou caracteres.
Numérico, opcional. Coordenada vertical inferior em
nBottom
pixels ou caracteres.
Numérico, opcional. Coordenada horizontal inferior em
nRight
pixels ou caracteres.
cTitle Caractere, opcional. Título da janela.
nPar6 Reservado.
oPar7 Reservado.
oPar8 Reservado.
oPar9 Reservado.
oParent Objeto, opcional. Janela mãe da janela corrente.
lPar11 Reservado.
lPar12 Reservado.
nClrFore Numérico, opcional. Cor de fundo da janela.
nClrText Numérico, opcional. Cor do texto da janela.
oPar15 Reservado.
cPar16 Reservado.
lPar17 Reservado.
lPar18 Reservado.
lPar19 Reservado.
lPar20 Reservado.
Lógico, opcional. Se .T. (padrão) considera coordenadas
lPixel
passadas em pixels, se .F. considera caracteres.
Retorno Objeto. A janela construída.
Activate
Descrição Ativa (exibe) a janela. Chamar esse método apenas uma vez.
Activate([acShow], [bPar2], [bPar3], [bPar4], [bPar5], [bPar6],
Sintaxe [ abInit ], [bPar8], [bPar9], [bPar10], [bPar11], [bPar12] ,[bPar13],
[bPar14], [bPar15], [abValid], [bPar17], [bPar18] ).
Parâmetros Parâmetro Tipo / Descrição
Caracter, opcional. “ICONIZED” para janela iconizada
acShow
ou “MAXIMIZED” para janela maximizada.
bPar2 Reservado.
bPar3 Reservado.
bPar4 Reservado.
bPar5 Reservado.
bPar6 Reservado.
Bloco de código. Executado quando janela está sendo
abInit
exibida.
bPar8 Reservado.
bPar9 Reservado.
bPar10 Reservado.
bPar11 Reservado.
bPar12 Reservado.
bPar13 Reservado.
bPar14 Reservado.
bPar15 Reservado.
Bloco de código. Executado quando a janela for
solicitada de fechar. Deverá retornar .T. se o conteúdo
abValid
da janela for válido, ou .F. se não. Se o bloco
retornar .F. a janela não fechará.
bPar17 Reservado.
bPar18 Reservado.
Retorno NIL
End
Descrição Solicita encerramento da janela.
Sintaxe End( )
Retorno Lógico. .T. se encerrou a janela e .F. se não.
Center
Descrição Centraliza a janela.
Sintaxe Center( )
Retorno NIL
Exemplo
#INCLUDE "[Link]"
USER FUNCTION Teste()
Local oWindow
Local abInit:= {||conout("ativando!")}
Local abValid:= {||conout("encerrando!"),.T.}
oWindow:= tWindow():New( 10, 10, 200, 200, "Meu
programa",,,,,,,,CLR_WHITE,CLR_BLACK,,,,,,,.T. )
oWindow:Activate("MAXIMIZED",,,,,,abInit,,,,,,,,,abValid,,)
/* os comandos abaixo proporcionam o mesmo resultado
DEFINE WINDOW oWindow FROM 10, 10 TO 200,200 PIXEL TITLE "Meu
programa" COLOR CLR_WHITE,CLR_BLACK
ACTIVATE WINDOW oWindow MAXIMIZED ON INIT abInit VALID abValid
*/
Return NIL
CLASSES NÃO VISUAIS
Descrição
A TMailManager é uma classe que tem por finalidade criar conexões em servidores
SMTP ou POP
Métodos
Método Descrição
Método CHANGEFOLDER usado apenas para conexão
IMAP.
CHANGEFOLDER O método ChangeFolder() da classe TMailManager tem
como objetivo realizar a mudança de pasta em que estamos
conectados.
Método COPYMSG usado apenas para conexão IMAP.
O método CopyMsg() da classe tMailManager tem como
objetivo Copiar uma determinada mensagem da pasta
corrente em que estamos posicionados no servidor
IMAP para uma outra pasta no servidor, ou até mesmo
para a pasta corrente.
É muito importante entendermos a localização que estamos
no server IMAP, isso quando usamos funçoes que lidam
COPYMSG
com o posicionamento no folder do servidor IMAP como
changeFolder(), createFolder() ou deleteFolder().
Para Copiar uma mensagem devemos informar qual
mensagem queremos mover através do primeiro parametro
da função e a pasta de acordo com o nome no servidor
IMAP, a função irá procurar pelo ID da mensagem apenas
na pasta em que estamos posicionados e tentará mover para
o folder informado(lembrando que o nome deve ser
identico ao criado no servidor)
Método CREATEFOLDER usado apenas para conexão
IMAP
O método CreateFolder() da classe tMailManager tem
como objetivo realizar a criação de uma nova pasta de
mensagens no servidor de emails IMAP.
CREATEFOLDER Para se criar uma pasta no diretório root do servidor IMAP
basta apenas passar o nome da pasta que desejamos, sem
path algum de um device.
Para se criar uma subpasta, devemos informar a hierarquia
de pastas e o nome da pasta. Para se criar uma subpasta de
Inbox, basta chamar a função create folder informando
'Inbox\Teste' e assim por diante.
Método DELETEFOLDER usado apenas para conexão
DELETEFOLDER
IMAP.
O método DeleteFolder() da classe tMailManager, tem
como objetivo deletar uma pasta do servidor de email
IMAP.
Informando a pasta que será deletada por parametro na
função, que deve conter o nome passado idêntico ao da
pasta no sevidor (case sensitive).
Método DELETEMSG
O método DeleteMsg() da classe tMailManager tem como
objetivo deletar uma determinada mensagem do servidor,
DELETEMSG de acordo com o numero da mensagem passada por
parametro para a função.
A função irá retornar true caso tenha sido encontrado a
mensagem e deletada.
Método GETALLFOLDERLIST usado apenas para
conexão IMAP.
O método GetAllFolderList() da classe TMailManager,
tem como objetivo obter todas as pastas de determinada
conta de email, que estão no servidor email IMAP.
O método retorna todas as pastas assinadas(são as pastas
abilitadas ou Subscribe)e não assinadas, esse retorno vem
em forma de array, do seguinte modo:
array[1]
array[1][1]:cNome
GETALLFOLDERLIST
array[1][2]:nNumMsg
array[1][3]:nNumMsgNaoLidas
array[1][4]:cStatus
: :
: :
cStatus: I = NOINFERIOS, N = NOSELECT, M =
MAKED e U = UNMARKED
nNumMsg: Quantidade de mensagens que existem na
pasta.
cNome: O respectivo nome da pasta.
nNumMsgNaoLidas: Numero de mensagens nao lidas na
pasta
Método GETERRORSTRING
O método GetErrorString da classe TMailManager, tem
GETERRORSTRING como objetivo retornar um erro em forma de string,
trazendo sua descrição de acordo com algum erro que
tenha ocorrido durante alguma outra função da classe com
SendMail(), algum connect e assim por diante.
O valor informado por parametro representa erros
definidos por padrão do protocolo de conexão SMTP.
Método GETFOLDER usado apenas para conexão IMAP.
O método getFolder da classe tMailManager tem como
objetivo obter o folder corrente em que estamos
GETFOLDER
posicionados(está em uso) no servidor IMAP.
A função irá retornar o nome do folder, de acordo com o
nome criado no servidor.
Método GETFOLDERLIST usado apenas para conexão
IMAP.
O método GetFolderList() da classe TMailManager, tem
como objetivo obter todas as pastas de determinada conta
de email, que estão no servidor email IMAP.
O método retorna todas as pastas assinadas(são as pastas
abilitadas ou Subscribe), esse retorno vem em forma de
array, do seguinte modo:
array[1]
array[1][1]:cNome
GETFOLDERLIST
array[1][1]:nNumMsgNaoLidas
array[1][1]:nNumMsg
array[1][1]:cStatus
: :
: :
cStatus: I = NOINFERIOS, N = NOSELECT, M =
MAKED e U = UNMARKED
nNumMsg: Quantidade de mensagens que existem na
pasta.
cNome: O respectivo nome da pasta.
nNumMsgNaoLidas: Numero de mensagens nao lidas da
pasta
GETMSGBODY Método GETMSGBODY usado apenas para conexão
IMAP.
O método GetMsgBody() da classe de tMailManager tem
como objetivo obter o conteudo da mensagem indicada de
acordo com o parametro que representa o numero da
mensagem para a função.
O valor informado por parametro é o numero da mensagem
na pasta do servidor. O método irá procurar pela
mensagem no folder que estiver posicionado no server
IMAP.
GETMSGHEADER Método GETMSGHEADER usado apenas para conexão
IMAP.
O método GetMsgHeader() da classe tMailManager tem
como objetivo se comunicar com o server de email IMAP
e obter o cabeçalho da mensagem requerida de acordo com
o parametro informando.
Esse cabeçalho da mensagem contem todos os dados
relativos ao email como : From, To, CC, BCC, etc...
O valor informado por parametro é o numero da mensagem
na pasta do servidor.
Obs.: o servidor IMAP irá procurar pela mensagem apenas
na pasta corrente em uso, caso a pasta em uso seja a 'Inbox'
o mensagem será procurada apenas na nesta pasta.
Método GETNUMMSGS
O método GetNumMsgs() da classe TMailManager tem
como objetivo retornar o numero de mensagens que
existem no servidor.
Devemos informar um numérico no parametro da função
GETNUMMSGS
como referência, indicando o total de mensagens após a
execução da função, o valor retornado pela função é apenas
o status de funcionou ou não.
Obs.: A função retorna o numero de mensagens total da
conta de usuário informada e nao apenas por pasta como
inbox, sent itens, etc..
Método GETPOPTIMEOUT
O método GetPopTimeOut() da classe tMailManager tem
como objetivo retornar o tempo em segundos que
está estabelecido com o servidor POP para que seja
GETPOPTIMEOUT
finalizada a conexão por time-out.
Obs.: caso nao tenha sido estabelecido nenhum tempo de
time-out pela função SETPOPTIMEOUT, será retornado
0(zero).
Método GETSMTPTIMEOUT
O método GetSMTPTimeOut() da classe tMailManager
tem como objetivo retornar o tempo em segundos que
está estabelecido com o servidor SMTP para que seja
GETSMTPTIMEOUT
finalizada a conexão por time-out.
Obs.: caso nao tenha sido estabelecido nenhum tempo de
time-out pela função SETSMTPTIMEOUT, será retornado
0(zero).
GETUSER Método GETUSER
O método usado apenas para conexão IMAP.
A função GetUser() da classe de email tMailManager tem
como objetivo obter o usuario corrente em que estamos
logados no momento.
A função irá retornar uma string contendo o valor da conta
de email do usuario antes do @.
Método IMAPCONNECT usado apenas para conexão
IMAP.
O método IMAPConnect() da classe TMailManager tem
como objetivo realizar a conexão em um IMAP e-mail
server e sincroniza o mailbox folders.
A conexão através de IMAP trata-se de um método de
acesso a mensagens eletrônicas armazenadas em um
servidor local ou remoto.
IMAPCONNECT
O método irá se conectar de acordo com os dados
informados através do método init().
Obs.:Uma característica importante do IMAP é
permitir que a manipulação de mensagens e pastas seja
feita como se estivessem no computador local. Sempre
que for estabelecida uma conexão com servidor IMAP
através da função imapConnect() é importante finalizar
a conexão utilizando a imapDisconnect().
Método IMAPDISCONNECT usado apenas para conexão
IMAP.
O método IMAPDisConnect() da classe TMailManager
tem como objetivo realizar o fim da conexão entre a
IMAPDISCONNECT
aplicação e um IMAP e-mail server.
Obs.: sempre que for estabelecida uma conexão com
servidor IMAP através da função imapConnect() é
importante finalizar a conexão utilizando a disconnect.
Método IMAPSTORE usado apenas para conexão IMAP
O método imapStore() da classe tMailManager tem como
objetivo armazenar uma determinada mensagem em algum
IMAPSTORE folder do servidor IMAP.
Obs.: A função é muito util quando por exemplo
desejamos que ao enviar uma mensagem ela seja salva em
alguma pasta do server IMAP.
INIT Método INIT
Através desse método da classe tMailManager,
iniciamos uma nova conexão com um servidor de
emails POP ou SMTP.
Quando informamos por argumento o servidor pop (Ex.:
[Link]) que siginifica o protocolo usado
na internet para a recebimento de mensagens ao usuário
final e o servidor smtp (Ex.: [Link]) que
siginifica o protocolo usado na internet para a envio de
mensagens ao usuário final, devemos também informar um
usuario que esteja devidamente cadastrado no servidor e
sua senha.
Podemos ainda informar o tempo de timeout para queda da
conexão e ainda o numero de porta, caso a porta do
servidor desejado não seja a default de um smtp
Método MOVEMSG usada apenas para conexão IMAP.
A função MoveMsg() da classe tMailManager tem como
objetivo mover uma determinada mensagem da pasta
corrente em que estamos posicionados no servidor
IMAP para uma outra pasta no servidor.
É muito importante entendermos a localização que estamos
no server IMAP, isso quando usamos funçoes que lidam
MOVEMSG com os folder como changeFolder(), createFolder() ou
deleteFolder().
Para mover uma mensagem devemos informar qual
mensagem queremos mover através do primeiro parametro
da função e a pasta de acordo com o nome no servidor
IMAP, a função irá procurar pelo ID da mensagem apenas
na pasta em que estamos posicionados e tentará mover para
o folder informado(lembrando que o nome deve ser
identico ao criado no servidor)
Contrutor da Classe tMailManager.
Retorna uma nova instância do Objeto da Classe
tMailManager.
NEW
Antes da utilização das funções e/ou propriedades da
classe de email é necessario criarmos uma instancia da
classe através do contrutor New().
POPCONNECT Método POPCONNECT
O método PopConnect() da classe TmailManager se
conecta com o servidor de email, através dos parametros
que foram informados através do método INIT().
Com esse método realizamos a conexão no servidor POP,
ou seja, apenas realizaremos o recebimento das mensagens
existentes na caixa postal do usuario informado.
Método POPDISCONNECT
O método POPDisconnect() da classe TMailManager irá
realizar o fim da conexão com o servidor POP, se
desconectando apenas com o servidor POP.
POPDISCONNECT
Ao solicitar a finalização da conexão com o servidor
POP, a função irá retornar o status da operação, caso tenha
sido bem sucedida retorna 0, outros valores de erro caso
contrário.
Método PURGE usado apenas para conexão IMAP
PURGE
O metodo purge() da classe tMailManager
Método RENAMEFOLDER usado apenas para conexão
IMAP.
RENAMEFOLDER A função RenameFolder() da classe tMailManger tem
como objetivo realizar a mudança entre os nomes da pastas
no servidor de e-mails IMAP.
Método SENDMAIL
O método SendMail() da classe TMailManager tem a
função de mandar um e-mail de acordo com os dados
passados por parametro para a função.
SENDMAIL
Ao informar os parametros que representam os
destinatarios pode-se informar mais de uma conta de email,
porém devidamente separada por ; Ex.:
user1@[Link]; user2@[Link]
Método SETFOLDERSUBSCRIBE usado apenas para
conexão IMAP.
A função setFolderSubscribe da classe tMailManager tem
como objetivo tornar uma pasta do servidor de email
IMAP assinada.
SETFOLDERSUBSCRIBE
Tornar uma pasta assinada, tem um significado parecido
como deixa-lá visivel em nossa caixa de email, as
mensagens para esta pasta serão 'baixadas'.
A pasta Inbox por exemplo, sempre é assinada por default.
SETMSGFLAG Método SETMSGFLAG usado apenas para conexão
IMAP.
A função SetMsgFlag() da classe tMailManager tem como
objetivo indicar o status para uma determinada mensagem
indicada de acordo com o parametro informado para a
função.
Os estados possiveis para setar na mensagem são:
A = ANSWERED, F = FLAGGED, D = DELETED, S = SEEN, R =
DRAFT, C = RECENT, P = SPECIAL
Método SETPOPTIMEOUT
O método SetPopTimeOut() da classe tMailmanager irá
configurar um tempo para que uma conexão
SETPOPTIMEOUT estabelecida com servidor POP seja finalizada por time-
out.
Obs.: O tempo informado pelo método deve ser em
segundos.
Método SETSMTPTIMEOUT
O método SetSMTPTimeOut() da classe tMailmanager irá
configurar um tempo para que uma conexão
SETSMTPTIMEOUT estabelecida com servidor SMTP seja finalizada por time-
out.
Obs.: O tempo informado pelo método deve ser em
segundos.
Método SMTPCONNECT
O método SMTPConnect() da classe TmailManager se
conecta com o servidor de email, através dos parametros
que foram informados através do método INIT().
SMTPCONNECT
Com esse método realizamos a conexão no servidor
SMTP, ou seja, apenas realizaremos o envio de
mensagens para uma determinada conta de usuario,
informados anteriormente pelo metodo INIT().
Método SMTPDISCONNECT
O método SMTPDisconnect() da classe TMailManager irá
realizar o fim da conexão com o servidor SMTP, se
desconectando apenas com o servidor SMTP.
SMTPDISCONNECT
Ao solicitar a finalização da conexão com o servidor
SMTP, a função irá retornar o status da operação, caso
tenha sido bem sucedida retorna 0, outros valores de erro
caso contrário.
SETUSEREALID Método SETUSEREALID usado apenas para conexão
IMAP.
A função SetUseRealID() da classe tMailManager tem
como objetivo definir qual id será usado para busca das
mensagens.
Uma mensagem de email possui dois modos de se
identificada no servidor IMAP:
-Através do seu número(o servidor mantém um
'contador' do numero de mensagens que chegam para
determinada conta e atribui esse numero a mensagem. Ex:
Imagine uma conta que acabou de ser criada, ao receber
sua 1º msg, esta recebera um identificador de numero 1 e
assim por diante..).
-Através de um ID único que o servidor atribui para a
mensagem.
Por default as funçoes usam o numero da mensagem,
podemos usar a função SetUseRealID() para mudar isso,
passando um parametro booleano para a função.
Método ENDGETALLMSGHEADER usado apenas para
conexão IMAP.
A função EndGetAllMsgHeader() da classe tMailManager
é usada após a chamada da função
StartGetAllMsgHeader() que inicia o processo de pegar o
header das mensagens.
ENDGETALLMSGHEADER
A função recebe um array como parametro que deve ser
passado como referência pois os headers das mensagens
irão ser retornados através deste array.
Quando o servidor terminar de baixar as mensagens será
retornado true através da função, enquanto for retornado
false o parametro nao vem populado com as mensagens.
Método STARTGETALLMSGHEADER usado apenas
para conexão IMAP.
A função StartGetAllMsgHeader() da classe tMailManager
tem como objetivo dar inicio ao processo de obtenção de
todos os cabeçalhos(headers) de todas as mensagens de
uma determinada pasta.
STARTGETALLMSGHEADER
A função irá avisar ao servidor IMAP que um processo de
obtenção das mensagens vai ocorrer, definindo qual a
pasta(folder) deve se iniciar o processo e qual as
infomação no header da mensagem deve ser retornada.
obs.: a função apenas inicia o processo, para pegar os
cabeçalhos das mensagens da pasta use a função
EndGetAllMsgHeader().
Este exemplo tem como objetivo principal documentar a classe tMailManager, com
foco nas funçoes que são usadas apenas por conexão IMAP.
Este exemplo irá fazer basicamente manipulação dos folders de uma conta de email,
através de uma conexão com o servidor IMAP. Ex: [Link]
#include "[Link]"
STATIC oMailManager := Nil
User Function tstIMAP()
Local aStPastas := {}
Local sFolder := "TSTIMAP"
Local sErro := ""
if !myConnect( "[Link]", "", "seuNomeAntesDo@",
"senhadoemail", @sErro )
return .F.
endif
//tento ir para o folder TSTIMAP
If ! oMailManager:ChangeFolder( ConvFdlName( sFolder, .F. ) )
//entrei aqui pq o folder nao existe, entao crio ele
CreateFolder( sFolder )
EndIf
//pego os folders(pastas) existentes no servidor, incluido o
TSTIMAP
GetFolderList( @aStPastas )
varinfo("PASTAS", aStPastas)
//Verificamos o folder corrente em uso
GetFolder( @sFolder )
conout("Folder Corrente" + sFolder)
If !oMailManager:DeleteFolder( ConvFdlName( sFolder, .F. ) )
conout("nao foi possivel deletar a pasta" + sFolder)
Return .F.
EndIf
myDisconnect()
return .T.
function myConnect( sSrvIMAP, sSrvSMTP, sLogin, sPass, sErro )
Local nErro := 0
//obtenho uma nova instancia da classe de email.
oMailManager := TMailManager():New()
//uso a função init para setar os dados.
If (nErro := oMailManager:Init( sSrvIMAP, sSrvSMTP, sLogin,
sPass )) != 0
sErro := oMailManager:GetErrorString( nErro )
Conout( sErro )
Return .F.
EndIf
//realizo uma CONEXAO IMAP
If (nErro := oMailManager:IMAPConnect()) != 0
sErro := oMailManager:GetErrorString( nErro )
Conout( sErro )
Return .F.
EndIf
//informo o server que iremos trabalhar com ID real da mensagem
oMailManager:SetUseRealID( .T. )
Return .T.
function myDisconnect()
oMailManager:IMAPDisconnect()
Return .T.
function GetFolderList( aStPastas )
Local nI := 0, nTam := 0
Local aTemp := {}
Local aFolder
aTemp := oMailManager:GetFolderList()
nTam := Len( aTemp )
For nI := 1 To nTam
//crio um array temp {nome, nTotalMensagens,
nMensagensNaoLidas, lAssinada}
aFolder := {}
aAdd(aFolder, ConvFdlName( aTemp[ nI ][1], .T. ))
aAdd(aFolder, aTemp[ nI ][3])
aAdd(aFolder, aTemp[ nI ][5])
aAdd(aFolder, .T.)
//adiciono no array de referencia do parametro
aAdd( aStPastas, aFolder )
aFolder := NIL
Next
Return .T.
// Retorna a pasta que esta em uso, sFolder referencia
function GetFolder( sFolder )
sFolder := ConvFdlName( oMailManager:GetFolder(), .F. )
Return .T.
Function CreateFolder( sFolder )
sFolder := ConvFdlName( sFolder, .F. )
//tento criar o folder no server IMAP
If ! oMailManager:CreateFolder( sFolder )
Return .F.
EndIf
//set o folder como assinado, para aparecer
If ! oMailManager:SetFolderSubscribe( sFolder, .T. )
Return .F.
EndIf
Return .T.
Sintaxe
oObj:CHANGEFOLDER ( < sFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Representa o nome da pasta na qual desejamos nos
sFolder Caracter
mudar(conectar) no servidor IMAP.
Retorno
Tipo Descrição
Retorna true, caso tenha sido possivel mudar de pasta no servidor IMAP,
Lógico
false caso contrario.
Descrição
Método CHANGEFOLDER usado apenas para conexão IMAP.
O método ChangeFolder() da classe TMailManager tem como objetivo realizar a
mudança de pasta em que estamos conectados.
oObj:COPYMSG ( < nMsg > , < sFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Valor numerico da mensagem no servidor de email IMAP
nMsg Numérico
ou seu ID.
Indica o nome da pasta no servidor de email IMAP, no
sFolder Caracter
qual desejamos transferir a mensagem.
Retorno
Tipo Descrição
Lógico Retorna true caso tenha sido possivel encontrar a mensagem requirida e
Copiar para a pasta informada, false caso contrário.
Descrição
Método COPYMSG usado apenas para conexão IMAP.
O método CopyMsg() da classe tMailManager tem como objetivo Copiar uma
determinada mensagem da pasta corrente em que estamos posicionados no servidor
IMAP para uma outra pasta no servidor, ou até mesmo para a pasta corrente.
É muito importante entendermos a localização que estamos no server IMAP, isso
quando usamos funçoes que lidam com o posicionamento no folder do servidor
IMAP como changeFolder(), createFolder() ou deleteFolder().
Para Copiar uma mensagem devemos informar qual mensagem queremos mover através
do primeiro parametro da função e a pasta de acordo com o nome no servidor IMAP, a
função irá procurar pelo ID da mensagem apenas na pasta em que estamos posicionados
e tentará mover para o folder informado(lembrando que o nome deve ser identico ao
criado no servidor)
oObj:COPYMSG ( < nMsg > , < sFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Valor numerico da mensagem no servidor de email IMAP
nMsg Numérico
ou seu ID.
Indica o nome da pasta no servidor de email IMAP, no
sFolder Caracter
qual desejamos transferir a mensagem.
Retorno
Tipo Descrição
Retorna true caso tenha sido possivel encontrar a mensagem requirida e
Lógico
Copiar para a pasta informada, false caso contrário.
Descrição
Método COPYMSG usado apenas para conexão IMAP.
O método CopyMsg() da classe tMailManager tem como objetivo Copiar uma
determinada mensagem da pasta corrente em que estamos posicionados no servidor
IMAP para uma outra pasta no servidor, ou até mesmo para a pasta corrente.
É muito importante entendermos a localização que estamos no server IMAP, isso
quando usamos funçoes que lidam com o posicionamento no folder do servidor
IMAP como changeFolder(), createFolder() ou deleteFolder().
Para Copiar uma mensagem devemos informar qual mensagem queremos mover através
do primeiro parametro da função e a pasta de acordo com o nome no servidor IMAP, a
função irá procurar pelo ID da mensagem apenas na pasta em que estamos posicionados
e tentará mover para o folder informado(lembrando que o nome deve ser identico ao
criado no servidor)
Sintaxe
oObj:DELETEFOLDER ( < cFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Representa o nome da pasta na qual desejamos deletar no
cFolder Caracter
servidor IMAP.
Retorno
Tipo Descrição
Retorna true, caso tenha sido possivel mudar de pasta no servidor IMAP,
Lógico
false caso contrario.
Descrição
Método DELETEFOLDER usado apenas para conexão IMAP.
O método DeleteFolder() da classe tMailManager, tem como objetivo deletar uma pasta
do servidor de email IMAP.
Informando a pasta que será deletada por parametro na função, que deve conter o nome
passado idêntico ao da pasta no sevidor (case sensitive).
Sintaxe
oObj:DELETEMSG ( < nMsg > ) --> lRet
Parâmetros
Argumento Tipo Descrição
nMsg Numérico Numero da mensagem a ser deletada.
Retorno
Tipo Descrição
Retorna true, caso tenha sido possivel deletar a mensagem. Caso contrário
(NULO)
retorna false.
Descrição
Método DELETEMSG
O método DeleteMsg() da classe tMailManager tem como objetivo deletar uma
determinada mensagem do servidor, de acordo com o numero da mensagem passada
por parametro para a função.
A função irá retornar true caso tenha sido encontrado a mensagem e deletada.
Sintaxe
oObj:ENDGETALLMSGHEADER ( < aHeaders > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Array usado como referência para o retorno dos headers das
aHeaders Array
mensagens.
Retorno
Tipo Descrição
Retorna true quando o servidor IMAP terminou de mandar todos os
Lógico
headers das mensagens, false caso contrário.
Descrição
Método ENDGETALLMSGHEADER usado apenas para conexão IMAP.
A função EndGetAllMsgHeader() da classe tMailManager é usada após a chamada da
função StartGetAllMsgHeader() que inicia o processo de pegar o header das mensagens.
A função recebe um array como parametro que deve ser passado como referência pois
os headers das mensagens irão ser retornados através deste array.
Quando o servidor terminar de baixar as mensagens será retornado true através da
função, enquanto for retornado false o parametro nao vem populado com as mensagens.
Sintaxe
oObj:GETALLFOLDERLIST ( ) --> aRet
Retorno
Tipo Descrição
Retorna um Array contendo todas as pastas (Assinadas/Nao Assinadas) e
Array informaçoes sobre a respectiva pasta, como está status, o seu nome e
numero de mensagens existentes nela.
Descrição
Método GETALLFOLDERLIST usado apenas para conexão IMAP.
O método GetAllFolderList() da classe TMailManager, tem como objetivo obter todas
as pastas de determinada conta de email, que estão no servidor email IMAP.
O método retorna todas as pastas assinadas(são as pastas abilitadas ou Subscribe)e não
assinadas, esse retorno vem em forma de array, do seguinte modo:
array[1]
array[1][1]:cNome
array[1][2]:nNumMsg
array[1][3]:nNumMsgNaoLidas
array[1][4]:cStatus
: :
: :
cStatus: I = NOINFERIOS, N = NOSELECT, M = MAKED e U = UNMARKED
nNumMsg: Quantidade de mensagens que existem na pasta.
cNome: O respectivo nome da pasta.
nNumMsgNaoLidas: Numero de mensagens nao lidas na pasta
Sintaxe
oObj:GETERRORSTRING ( < nError > ) --> cRet
Parâmetros
Argumento Tipo Descrição
Representa um valor numérico a ser passado de algum
nError Numérico
erro de acordo como SMTP.
Retorno
Tipo Descrição
Retorna uma cadeia de caracteres com a descrição, de acordo com o valor
Caracter
do erro passado.
Descrição
Método GETERRORSTRING
O método GetErrorString da classe TMailManager, tem como objetivo retornar um erro
em forma de string, trazendo sua descrição de acordo com algum erro que tenha
ocorrido durante alguma outra função da classe com SendMail(), algum connect e assim
por diante.
O valor informado por parametro representa erros definidos por padrão do protocolo de
conexão SMTP.
Sintaxe
oObj:GETFOLDER ( ) --> cFolder
Retorno
Tipo Descrição
Caracter Retorna uma string contendo o nome do folder em uso pela aplicação.
Descrição
Método GETFOLDER usado apenas para conexão IMAP.
O método getFolder da classe tMailManager tem como objetivo obter o folder corrente
em que estamos posicionados(está em uso) no servidor IMAP.
A função irá retornar o nome do folder, de acordo com o nome criado no servidor.
Sintaxe
oObj:GETFOLDERLIST ( ) --> aRet
Retorno
Tipo Descrição
Retorna um Array contendo todas as pastas e informaçoes sobre a
Array respectiva pasta, como se está status, o seu nome e numero de mensagens
existentes nela.
Descrição
Método GETFOLDERLIST usado apenas para conexão IMAP.
O método GetFolderList() da classe TMailManager, tem como objetivo obter todas as
pastas de determinada conta de email, que estão no servidor email IMAP.
O método retorna todas as pastas assinadas(são as pastas abilitadas ou Subscribe), esse
retorno vem em forma de array, do seguinte modo:
array[1]
array[1][1]:cNome
array[1][1]:nNumMsgNaoLidas
array[1][1]:nNumMsg
array[1][1]:cStatus
: :
: :
cStatus: I = NOINFERIOS, N = NOSELECT, M = MAKED e U = UNMARKED
nNumMsg: Quantidade de mensagens que existem na pasta.
cNome: O respectivo nome da pasta.
nNumMsgNaoLidas: Numero de mensagens nao lidas da pasta
Sintaxe
oObj:GETMSGBODY ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método GETMSGBODY usado apenas para conexão IMAP.
O método GetMsgBody() da classe de tMailManager tem como objetivo obter o
conteudo da mensagem indicada de acordo com o parametro que representa o numero
da mensagem para a função.
O valor informado por parametro é o numero da mensagem na pasta do servidor. O
método irá procurar pela mensagem no folder que estiver posicionado no server IMAP.
Sintaxe
oObj:GETMSGHEADER ( < nMsg > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Valor numerico da mensagem no servidor de email
nMsg Numérico
IMAP.
Retorno
Tipo Descrição
Retorna true caso tenha sido possivel encontrar a mensagem requirida e
Lógico
retornar seu cabeçalho, false caso contrário.
Descrição
Método GETMSGHEADER usado apenas para conexão IMAP.
O método GetMsgHeader() da classe tMailManager tem como objetivo se comunicar
com o server de email IMAP e obter o cabeçalho da mensagem requerida de acordo
com o parametro informando.
Esse cabeçalho da mensagem contem todos os dados relativos ao email como : From,
To, CC, BCC, etc...
O valor informado por parametro é o numero da mensagem na pasta do servidor.
Obs.: o servidor IMAP irá procurar pela mensagem apenas na pasta corrente em uso,
caso a pasta em uso seja a 'Inbox' o mensagem será procurada apenas na nesta pasta.
Sintaxe
oObj:GETNUMMSGS ( < nNumMsg > ) --> nRet
Parâmetros
Argumento Tipo Descrição
Parametro passado por referencia, retorna nele o numero
nNumMsg Numérico
de mensagens que estão no servidor.
Retorno
Tipo Descrição
Numérico 0 = Lista recebida com sucesso
Descrição
Método GETNUMMSGS
O método GetNumMsgs() da classe TMailManager tem como objetivo retornar o
numero de mensagens que existem no servidor.
Devemos informar um numérico no parametro da função como referência, indicando o
total de mensagens após a execução da função, o valor retornado pela função é apenas o
status de funcionou ou não.
Obs.: A função retorna o numero de mensagens total da conta de usuário informada e
nao apenas por pasta como inbox, sent itens, etc..
Sintaxe
oObj:GETPOPTIMEOUT ( ) --> nRet
Retorno
Tipo Descrição
Numérico Retorna o tempo em segundos para a finalização por time out da conexao
POP.
Descrição
Método GETPOPTIMEOUT
O método GetPopTimeOut() da classe tMailManager tem como objetivo retornar o
tempo em segundos que está estabelecido com o servidor POP para que seja finalizada
a conexão por time-out.
Obs.: caso nao tenha sido estabelecido nenhum tempo de time-out pela função
SETPOPTIMEOUT, será retornado 0(zero).
Sintaxe
oObj:GETSMTPTIMEOUT ( ) --> nRet
Retorno
Tipo Descrição
Retorna um tempo em segundos, que representa o tempo para a
Numérico
finalização da conexão com o servidor SMTP.
Descrição
Método GETSMTPTIMEOUT
O método GetSMTPTimeOut() da classe tMailManager tem como objetivo retornar o
tempo em segundos que está estabelecido com o servidor SMTP para que seja
finalizada a conexão por time-out.
Obs.: caso nao tenha sido estabelecido nenhum tempo de time-out pela função
SETSMTPTIMEOUT, será retornado 0(zero).
Sintaxe
oObj:GETUSER ( ) --> sRet
Retorno
Tipo Descrição
Retorna uma String contento o nome do usuario da conta de email que
Caracter
estamos conectados.
Descrição
Método GETUSER
O método usado apenas para conexão IMAP.
A função GetUser() da classe de email tMailManager tem como objetivo obter o usuario
corrente em que estamos logados no momento.
A função irá retornar uma string contendo o valor da conta de email do usuario antes do
@.
Sintaxe
oObj:IMAPCONNECT ( ) --> lRet
Retorno
Tipo Descrição
Retorna true caso tenha sido possível realizar a conexão no servidor Imap,
Lógico
false caso contrário.
Descrição
Método IMAPCONNECT usado apenas para conexão IMAP.
O método IMAPConnect() da classe TMailManager tem como objetivo realizar a
conexão em um IMAP e-mail server e sincroniza o mailbox folders.
A conexão através de IMAP trata-se de um método de acesso a mensagens eletrônicas
armazenadas em um servidor local ou remoto.
O método irá se conectar de acordo com os dados informados através do método init().
Obs.:Uma característica importante do IMAP é permitir que a manipulação de
mensagens e pastas seja feita como se estivessem no computador local. Sempre que
for estabelecida uma conexão com servidor IMAP através da função
imapConnect() é importante finalizar a conexão utilizando a imapDisconnect().
Sintaxe
oObj:IMAPDISCONNECT ( ) --> lRet
Retorno
Tipo Descrição
Retorna true caso tenha sido possível realizar a finalização da conexão no
Lógico
servidor Imap, false caso contrário.
Descrição
Método IMAPDISCONNECT usado apenas para conexão IMAP.
O método IMAPDisConnect() da classe TMailManager tem como objetivo realizar o
fim da conexão entre a aplicação e um IMAP e-mail server.
Obs.: sempre que for estabelecida uma conexão com servidor IMAP através da função
imapConnect() é importante finalizar a conexão utilizando a disconnect.
Sintaxe
oObj:IMAPSTORE ( < cFolder > , < oMsg > ) --> nRet
Parâmetros
Argumento Tipo Descrição
Representa uma String que contém o nome da
cFolder Caracter
pasta(folder) no qual desejamos armazenar a mensagem.
Indica um objeto tMailMessage que contem as
oMsg Objeto
informaçoes da mensagem que desejamos armazenar.
Retorno
Tipo Descrição
Retorna um inteiro informando o status da operação, caso retornado 1
Numérico ocorreu erro durante a função, caso contrario retorna outros valores de
informação.
Descrição
Método IMAPSTORE usado apenas para conexão IMAP
O método imapStore() da classe tMailManager tem como objetivo armazenar uma
determinada mensagem em algum folder do servidor IMAP.
Obs.: A função é muito util quando por exemplo desejamos que ao enviar uma
mensagem ela seja salva em alguma pasta do server IMAP.
Sintaxe
oObj:INIT ( < cPopImap > , < cSmtp > , < cUser > , < cPass > , < nTimeOut > , <
nPorta > ) --> NIL
Parâmetros
Argumento Tipo Descrição
Endereço do servidor POP ou IMAP, no caso de conexão
cPopImap Caracter
SMTP passe esse como ""(branco).
Endereço do servidor SMTP, no caso de conexão POP
cSmtp Caracter
passe esse como ""(branco)
cUser Caracter Login no servidor.
cPass Caracter Senha no servidor.
nTimeOut Numérico Time out para a conexão.
nPorta Numérico Porta para se conectar.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método INIT
Através desse método da classe tMailManager, iniciamos uma nova conexão com um
servidor de emails POP ou SMTP.
Quando informamos por argumento o servidor pop (Ex.: [Link]) que
siginifica o protocolo usado na internet para a recebimento de mensagens ao usuário
final e o servidor smtp (Ex.: [Link]) que siginifica o protocolo usado
na internet para a envio de mensagens ao usuário final, devemos também informar um
usuario que esteja devidamente cadastrado no servidor e sua senha.
Podemos ainda informar o tempo de timeout para queda da conexão e ainda o numero
de porta, caso a porta do servidor desejado não seja a default de um smtp
Sintaxe
oObj:MOVEMSG ( < nNumMsg > , < sFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Valor numerico da mensagem no servidor de email
nNumMsg Numérico
IMAP.
Indica o nome da pasta no servidor de email IMAP, no
sFolder Caracter
qual desejamos transferir a mensagem.
Retorno
Tipo Descrição
Retorna true caso tenha sido possivel encontrar a mensagem requirida e
Lógico
mover para a pasta informada, false caso contrário.
Descrição
Método MOVEMSG usada apenas para conexão IMAP.
A função MoveMsg() da classe tMailManager tem como objetivo mover uma
determinada mensagem da pasta corrente em que estamos posicionados no servidor
IMAP para uma outra pasta no servidor.
É muito importante entendermos a localização que estamos no server IMAP, isso
quando usamos funçoes que lidam com os folder como changeFolder(), createFolder()
ou deleteFolder().
Para mover uma mensagem devemos informar qual mensagem queremos mover através
do primeiro parametro da função e a pasta de acordo com o nome no servidor IMAP, a
função irá procurar pelo ID da mensagem apenas na pasta em que estamos posicionados
e tentará mover para o folder informado(lembrando que o nome deve ser identico ao
criado no servidor)
Sintaxe
tMailManager():NEW ( ) --> oObjtMailManager
Retorno
Tipo Descrição
Objeto Retorna uma nova instância do Objeto da Classe tMailManager.
Descrição
Contrutor da Classe tMailManager.
Retorna uma nova instância do Objeto da Classe tMailManager.
Antes da utilização das funções e/ou propriedades da classe de email é necessario
criarmos uma instancia da classe através do contrutor New().
Sintaxe
oObj:POPCONNECT ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método POPCONNECT
O método PopConnect() da classe TmailManager se conecta com o servidor de email,
através dos parametros que foram informados através do método INIT().
Com esse método realizamos a conexão no servidor POP, ou seja, apenas realizaremos
o recebimento das mensagens existentes na caixa postal do usuario informado.
Sintaxe
oObj:POPDISCONNECT ( ) --> nRet
Retorno
Tipo Descrição
Numérico Retorna 0 quando for Disconectado, outro valor caso contrário.
Descrição
Método POPDISCONNECT
O método POPDisconnect() da classe TMailManager irá realizar o fim da conexão com
o servidor POP, se desconectando apenas com o servidor POP.
Ao solicitar a finalização da conexão com o servidor POP, a função irá retornar o status
da operação, caso tenha sido bem sucedida retorna 0, outros valores de erro caso
contrário.
Sintaxe
oObj:PURGE ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método PURGE usado apenas para conexão IMAP
O metodo purge() da classe tMailManager
Sintaxe
oObj:RENAMEFOLDER ( < sOldFolder > , < sNewFolder > ) --> lRet
Parâmetros
Argumento Tipo Descrição
sOldFolder Caracter Representa o nome atual que a pasta tem no servidor de
email IMAP, o valor aqui informado deve ser idêntico ao
gravado no servidor, caso contrário a pasta não será
encontrada.
Indica o novo nome no qual desejamos atribuir para a
sNewFolder Caracter
pasta.
Retorno
Tipo Descrição
Retorna true caso tenha sido possível realizar a mudança de nome das
(NULO)
pastas, false caso contrário.
Descrição
Método RENAMEFOLDER usado apenas para conexão IMAP.
A função RenameFolder() da classe tMailManger tem como objetivo realizar a mudança
entre os nomes da pastas no servidor de e-mails IMAP.
Sintaxe
oObj:SENDMAIL ( < sFrom > , < sTo > , < sSubject > , < sBody > , [ sCC ] ,
[ cBCC ] , [ aAttach ] , [ nNumAttach ] ) --> nRet
Parâmetros
Argumento Tipo Descrição
Indica uma conta de email no qual será usada para
sFrom Caracter representar de quem foi mandado o email. Ex:
Deusuario@[Link]
Indica a conta de email no qual será usada para enviar o
sTo Caracter respectivo email.
Ex: Parausuario@[Link]
Representa o assunto do email ou mensagem, que será
sSubject Caracter
enviado para a conta de email indicada.
sBody Caracter Representa o conteudo da mensagem que será enviada.
Opcional. Parametro para adicionar endereços ao qual
sCC Caracter
será enviado na seção Com Cópia(CC).
Opicional. Parametro para adicionar endereços de email
cBCC Caracter
no qual será enviado na seção Com Cópia Oculta(BCC)
Opcional. Parametro no qual podemos informar um Array
aAttach Array de strings contento de o Path dos arquivos que desejamos
enviar como atachados ao email.
Opicional. Quando desejamos enviar arquivos atachados
devemos informar esse argumento que contem a
nNumAttach Numérico
quandidade de arquivos que serão atachados no email, no
caso a quantidade de elementos do array.
Retorno
Tipo Descrição
Retrona 0, quando o E-mail for enviado com sucesso, outro valor qualquer
(NULO)
caso contrario.
Descrição
Método SENDMAIL
O método SendMail() da classe TMailManager tem a função de mandar um e-mail de
acordo com os dados passados por parametro para a função.
Ao informar os parametros que representam os destinatarios pode-se informar mais de
uma conta de email, porém devidamente separada por ; Ex.: user1@[Link];
user2@[Link]
Sintaxe
oObj:SETFOLDERSUBSCRIBE ( < cFolder > , < lAssinado > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Representa o nome do folder no servidor de email IMAP
cFolder Caracter
que desejamos deixar subscribe ou não.
True caso desejamos que o folder esteja
lAssinado Lógico
assinado(subscribe), falso caso contrário.
Retorno
Tipo Descrição
Retorna true caso a operação tenha sido realizada com sucesso, falso caso
Lógico
contrário.
Descrição
Método SETFOLDERSUBSCRIBE usado apenas para conexão IMAP.
A função setFolderSubscribe da classe tMailManager tem como objetivo tornar uma
pasta do servidor de email IMAP assinada.
Tornar uma pasta assinada, tem um significado parecido como deixa-lá visivel em nossa
caixa de email, as mensagens para esta pasta serão 'baixadas'.
A pasta Inbox por exemplo, sempre é assinada por default.
Sintaxe
oObj:SETMSGFLAG ( < nNumMsg > , < sFlag > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Indica o numero da mensagem que desejamos alterar seu
nNumMsg Array
status(flag).
sFlag Array Informa o novo status que desejamos para a mensagem.
Retorno
Tipo Descrição
Retorna true caso a mensagem tenha sido setada corretamente, caso
Lógico
contrário false.
Descrição
Método SETMSGFLAG usado apenas para conexão IMAP.
A função SetMsgFlag() da classe tMailManager tem como objetivo indicar o status
para uma determinada mensagem indicada de acordo com o parametro informado para a
função.
Os estados possiveis para setar na mensagem são:
A = ANSWERED, F = FLAGGED, D = DELETED, S = SEEN, R = DRAFT, C = RECENT, P =
SPECIAL
Sintaxe
oObj:SETPOPTIMEOUT ( < nTimeOut > ) --> nRet
Parâmetros
Argumento Tipo Descrição
nTimeOut Numérico Tempo para que a conexão seja fechada por Time-Out.
Retorno
Tipo Descrição
Numérico 0 = Time out setado
Descrição
Método SETPOPTIMEOUT
O método SetPopTimeOut() da classe tMailmanager irá configurar um tempo para que
uma conexão estabelecida com servidor POP seja finalizada por time-out.
Obs.: O tempo informado pelo método deve ser em segundos.
Sintaxe
oObj:SETSMTPTIMEOUT ( < nTime > ) --> nRet
Parâmetros
Argumento Tipo Descrição
nTime Numérico Tempo para que a conexão seja fechada por Time-Out.
Retorno
Tipo Descrição
Numérico 0 - Time out configurado
Descrição
Método SETSMTPTIMEOUT
O método SetSMTPTimeOut() da classe tMailmanager irá configurar um tempo para
que uma conexão estabelecida com servidor SMTP seja finalizada por time-out.
Obs.: O tempo informado pelo método deve ser em segundos.
Sintaxe
oObj:SETUSEREALID ( < lOpt > ) --> NIL
Parâmetros
Argumento Tipo Descrição
Indica qual tipo de Identificador deseja-se usar, caso
lOpt Lógico informado true será usado o ID real da mensagem, caso
informado false será usado o numero da mensagem.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método SETUSEREALID usado apenas para conexão IMAP.
A função SetUseRealID() da classe tMailManager tem como objetivo definir qual id
será usado para busca das mensagens.
Uma mensagem de email possui dois modos de se identificada no servidor IMAP:
-Através do seu número(o servidor mantém um 'contador' do numero de mensagens
que chegam para determinada conta e atribui esse numero a mensagem. Ex: Imagine
uma conta que acabou de ser criada, ao receber sua 1º msg, esta recebera um
identificador de numero 1 e assim por diante..).
-Através de um ID único que o servidor atribui para a mensagem.
Por default as funçoes usam o numero da mensagem, podemos usar a função
SetUseRealID() para mudar isso, passando um parametro booleano para a função.
Sintaxe
oObj:SMTPCONNECT ( ) --> nRet
Retorno
Tipo Descrição
Numérico 0 - Conectado
Descrição
Método SMTPCONNECT
O método SMTPConnect() da classe TmailManager se conecta com o servidor de email,
através dos parametros que foram informados através do método INIT().
Com esse método realizamos a conexão no servidor SMTP, ou seja, apenas
realizaremos o envio de mensagens para uma determinada conta de usuario, informados
anteriormente pelo metodo INIT().
Sintaxe
oObj:SMTPDISCONNECT ( ) --> nRet
Retorno
Tipo Descrição
(NULO) 0 = Disconectado
Descrição
Método SMTPDISCONNECT
O método SMTPDisconnect() da classe TMailManager irá realizar o fim da conexão
com o servidor SMTP, se desconectando apenas com o servidor SMTP.
Ao solicitar a finalização da conexão com o servidor SMTP, a função irá retornar o
status da operação, caso tenha sido bem sucedida retorna 0, outros valores de erro caso
contrário.
Sintaxe
oObj:STARTGETALLMSGHEADER ( < sFOlder > , < aHeader > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Indica qual o folder no servidor que desejamos obter os
sFOlder Caracter
cabeçalhos das mensagens.
Array que representa as informaçoes que desejamos serem
aHeader Array
retornadas nos cabeçalhos das mensagens.
Retorno
Tipo Descrição
Retorna true caso tenha sido possivel iniciar o processo de obtenção de
Lógico
cabeçalho das mensagens, false caso contrario.
Descrição
Método STARTGETALLMSGHEADER usado apenas para conexão IMAP.
A função StartGetAllMsgHeader() da classe tMailManager tem como objetivo dar
inicio ao processo de obtenção de todos os cabeçalhos(headers) de todas as mensagens
de uma determinada pasta.
A função irá avisar ao servidor IMAP que um processo de obtenção das mensagens vai
ocorrer, definindo qual a pasta(folder) deve se iniciar o processo e qual as infomação no
header da mensagem deve ser retornada.
obs.: a função apenas inicia o processo, para pegar os cabeçalhos das mensagens da
pasta use a função EndGetAllMsgHeader().
Tmailmessage
Este exemplo tem como objetivo principal mostrar o uso dos métodos da classe
tMailMessage. Para isto usamos a classe tMailManager(responsavel por estabelecer a
conexão de fato).
A classe tMailMessage possuí uma dependencia direta com a classe tMailManager,
devemos imaginar a classe tMailMessage como a mensagem que será enviada de fato
e tendo através dos métodos e propriedades a forma que iremos preencher os dados
necessários para um email como: Assunto, Corpo da Mensagem, 'Com Cópia', etc..
Assim através da classe podemos customizar também a mensagem que queremos
enviar. Acompanhe o exemplo abaixo.
#include "[Link]"
user Function EMail()
Local oServer
Local oMessage
Local nNumMsg := 0
Local nTam := 0
Local nI := 0
//Crio a conexão com o server STMP ( Envio de e-mail )
oServer := TMailManager():New()
oServer:Init( "", "[Link]", "[Link]",
"rica4758", 0, 25 )
//seto um tempo de time out com servidor de 1min
If oServer:SetSmtpTimeOut( 60 ) != 0
Conout( "Falha ao setar o time out" )
Return .F.
EndIf
//realizo a conexão SMTP
If oServer:SmtpConnect() != 0
Conout( "Falha ao conectar" )
Return .F.
EndIf
//Apos a conexão, crio o objeto da mensagem
oMessage := TMailMessage():New()
//Limpo o objeto
oMessage:Clear()
//Populo com os dados de envio
oMessage:cFrom := "Microsiga "
oMessage:cTo :=
"microsiga@[Link];microsiga@[Link]"
oMessage:cCc := "microsiga@[Link]"
oMessage:cBcc := "microsiga@[Link]"
oMessage:cSubject := "Teste de Email"
oMessage:cBody := "Conteudo do e-mail"
//Adiciono um attach
If oMessage:AttachFile( "[Link]" ) < 0
Conout( "Erro ao atachar o arquivo" )
Return .F.
Else
//adiciono uma tag informando que é um attach e o nome
do arq
oMessage:AddAtthTag( 'Content-Disposition: attachment;
filename=[Link]')
EndIf
//Envio o e-mail
If oMessage:Send( oServer ) != 0
Conout( "Erro ao enviar o e-mail" )
Return .F.
EndIf
//Disconecto do servidor
If oServer:SmtpDisconnect() != 0
Conout( "Erro ao disconectar do servidor SMTP" )
Return .F.
EndIf
//Crio uma nova conexão, agora de POP
oServer := TMailManager():New()
oServer:Init( "[Link]", "", "SeunomeAntesDo@",
"senhaDoEmail", 0, 110 )
If oServer:SetPopTimeOut( 60 ) != 0
Conout( "Falha ao setar o time out" )
Return .F.
EndIf
If oServer:PopConnect() != 0
Conout( "Falha ao conectar" )
Return .F.
EndIf
//Recebo o número de mensagens do servidor
oServer:GetNumMsgs( @nNumMsg )
nTam := nNumMsg
For nI := 1 To nTam
//Limpo o objeto da mensagem
oMessage:Clear()
//Recebo a mensagem do servidor
oMessage:Receive( oServer, nI )
//Escrevo no server os dados do e-mail recebido
Conout( oMessage:cFrom )
Conout( oMessage:cTo )
Conout( oMessage:cCc )
Conout( oMessage:cSubject )
Conout( oMessage:cBody )
Next
//Deleto todas as mensagens do servidor
For nI := 1 To nTam
oServer:DeleteMsg( nI )
Next
//Diconecto do servidor POP
oServer:POPDisconnect()
Return .T.
Sintaxe
oObj:ADDATTHTAG ( < cTag > ) --> NIL
Parâmetros
Argumento Tipo Descrição
Representa os dados que desejamos informa no caso de
cTag Caracter
um arquivo atachado.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método ADDATTHTAG
O método addAttTag() da classe tMailMessage tem como objetivo setar alguma
informação especial quando é passado algum arquivo atachado para a mensagem que
será enviada.
Ex: AddAtthTag( 'Content-Disposition: attachment; filename=[Link]')
adiciono uma tag informando que é um attach e o nome do arquivo.
Sintaxe
oObj:ATTACHFILE ( < cArq > ) --> NIL
Parâmetros
Argumento Tipo Descrição
cArq Caracter Indica o nome do arquivo a ser adicionado no e-mail.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método ATTACHFILE
O método AttachFile() da classe tMailMessage tem como objetivo adicionar um arquivo
ao objeto de e-mail, 'um Attach'.
Sintaxe
oObj:CLEAR ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método CLEAR
O método clear() da classe tMailMessage tem como objetivo limpar o conteudo do
objeto, assim podemos receber varias mensagem no mesmo objeto, apenas limpando o
seu conteudo antes.
Usando a função clear, nao precisamos criar varias vezes o mesmo objeto, para receber
mais de uma mensagem.
Sintaxe
oObj:GETATTACH ( < cNumMsg > ) --> sRet
Parâmetros
Argumento Tipo Descrição
Representa o Id(numero da mensagem) que desejamos
cNumMsg Numérico
obter informações.
Retorno
Tipo Descrição
Retorno uma String(cadeia de caracteres) contendo o conteudo do arquivo
Caracter
atachado na mensagem.
Descrição
Método GETATTACH
O método getAttach da classe tMailMessage tem como objetivo obter o conteudo do
arquivo atachado e retornar esse conteudo através de uma String.
Devemos informar o numero da mensagem que desejamos obter o attach.
Sintaxe
oObj:GETATTACHCOUNT ( ) --> nRet
Retorno
Tipo Descrição
Numérico Retorna o numero de anexos a mensagem.
Descrição
Método GETATTACHCOUNT
O método getAttachCount() da classe tMailMessage tem como objetivo informar qual a
quantidade de arquivos anexados a mensagem.
Sintaxe
oObj:GETATTACHINFO ( < nMsg > ) --> NIL
Parâmetros
Argumento Tipo Descrição
nMsg Numérico Indica o numero da mensagem que desejamos verificar.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método GETATTACHINFO
O método getAttachInfo() da classe tMailMessage tem como objetivo trazer todas
informaçoes sobre um attachment em alguma mensagem.
Devemos informar o numero da mensagem que desejamos trazer as informaçoes sobre
os attachments, o método irá retornar as seguintes informações:
ShortName: O nome do attachment
Type: O tipo do attachment, podendo ser FILE e TEXT por exemplo.
Disposition: Tipo do arquivo
DispositionName: informa o nome do tipo de arquivo
Id: Identificação do attachment
Location: Local fisico do attachment
Sintaxe
tMailMessage():NEW ( ) --> oObjtMailMessage
Retorno
Tipo Descrição
Objeto Retorna uma nova instância do Objeto da Classe tMailMessage.
Descrição
Contrutor da Classe tMailMessage.
Retorna uma nova instância do Objeto da Classe tMailMessage, representa uma
mensagem
Sintaxe
oObj:RECEIVE ( < oServer > , < nMsg > ) --> nRet
Parâmetros
Argumento Tipo Descrição
Indica o Objeto do servidor POP, criado atraves no
oServer Memo
obejeto TMailManager.
Indica o Número da mensagem a ser criada, recebido
nMsg Numérico
atraves do metodo TMailManager:GetNumMsgs.
Retorno
Tipo Descrição
Retorna 0(zero) quando o E-mail foi recebido com sucesso, outro valor
Numérico
caso contrário.
Descrição
Método RECEIVE
O método receive() da classe tMailMessage, tem como objetivo receber uma nova
mensagem do servidor populando o objeto da mensagem.
Sintaxe
oObj:SAVE ( < cNumMsg > ) --> NIL
Parâmetros
Argumento Tipo Descrição
cNumMsg Array Representa o numero da mensagem que desejamos salvar.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método SAVE
O método save() da classe tMailMessage tem como objetivo obter todo o conteudo de
uma determinada mensagem, que será encontrada através do parametro informado, que
repesenta o Id(numero da mensagem) e salvar a mensagem.
Sintaxe
oObj:SEND ( < oServer > ) --> NIL
Parâmetros
Argumento Tipo Descrição
Indica o objeto da classe tMailManager para o envio da
oServer Objeto
mensagem.
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Método SEND
O método Send() da classe TMailMessage tem a função de enviar um e-mail de acordo
com os dados passados pelo objeto da classe tMailManager por parametro para a
função.
Para que a função seja usada corretamente é preciso antes popular algumas das
propriedades da classe tMailMessage basicas para o envio como:
cFrom: Email de quem está mandando.
cTo: Email(s) para o qual desejamos enviar a mensagem.
cCc: Email(s) para o qual desejamos enviar a mensagem na seção "com cópia".
cBcc: Email(s) para o qual desejamos enviar a mensagem na seção "com cópia Oculta".
cSubject: Assunto da mensagem que será enviada.
cBody: Conteudo da mensagem.
Descrição
Esta classe permite estabelecer uma conexão cliente de socket do tipo TCP genérica.
Enviar e receber dados através de uma socket genérico e também pode ser usada como
base para implementação de protocolos não suportados pelo protheus.
Métodos
Método Descrição
CloseConnection Finaliza a conexão TCP genérica (socket ) do objeto corrente.
Connect Estabelece um conexão TCP genérica (socket ).
IsConnected Verifica se existe conexão valida no objeto corrente.
New Cria o objeto tSocketClient, sem conexão ativa.
Recebe os dados pela conexão ativa do objeto, qualquer tipo de
Receive
dado pode ser recebido.
Finaliza anormalmente a conexão, não avisa o outro lado que a
Reset conexão será finalizada.
Deve ser utilizado apenas em casos extremos.
Send Transmite o buffer pela conexão TCP Genérica ativa.
O Exemplo abaixo exemplifica a utilização de um cliente socket, note que para o
programa funcionar corretamente, deve-se alterar os parametros da conexão.
user function MySocket
Local oObj := tSocketClient():New()
nResp := oObj:Connect( 999, "[Link]", 1000 )
if(nResp == 0 )
Conout( "Conexão OK!" )
else
Conout( "Erro na Conexão OK! ", nResp )
return
endif
cSend = "Ola!!!! Estou transmitindo um dado!"
nResp := oObj:Send( cSend )
if( nResp != len( cSend ) )
conout( "Erro! Dado nao transmitido" )
else
conout( "Dado Enviado" )
endif
cBuffer := ""
nQtd = oObj:Receive( cBuffer, 10000 )
if( nQtd >= 0 )
conout( "Dados Recebidos " + Str( nQtd, 4, 0 ), cBuffer )
else
conout( "Nao recebi nada" )
endif
cSend = "Dados que será transmitido!!!"
nResp := oObj:Send( cSend )
if( nResp != len( cSend ) )
conout( "Erro! Dado nao transmitido" )
else
conout( "Dado Enviado" )
endif
if( oObj:IsConnected() )
conout( "OK! Estou conectado" )
else
conout( "Ops! Nao estou conectado" )
endif
oObj:CloseConnection()
if( !oObj:IsConnected() )
conout( "Desconectei" )
else
conout( "Ainda estou conectado, erro na desconexao" )
endif
return
Sintaxe
oObj:CloseConnection ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Finaliza a conexão TCP genérica (socket ) do objeto corrente.
Sintaxe
oObj:CloseConnection ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Finaliza a conexão TCP genérica (socket ) do objeto corrente.
Abrangência
Versão 6.09 Versão 7.10 Versão 8.11
Sintaxe
oObj:IsConnected ( ) --> lLogico
Retorno
Tipo Descrição
Retorna True se a conexão esta ativa e false caso esteja
Lógico
inválida/desconectado.
Descrição
Verifica se existe conexão valida no objeto corrente.
Sintaxe
tSocketClient():New ( ) --> oSocket
Retorno
Tipo Descrição
Objeto Retorna um Objeto do tipo tSocketClient
Descrição
Cria o objeto tSocketClient, sem conexão ativa.
Sintaxe
oObj:Receive ( < @cBuffer > , < nTimeout > ) --> nQtdRecebida
Parâmetros
Argumento Tipo Descrição
cBuffer Caracter Buffer que conterá os dados a serem recebidos.
tempo em milisegundos que a função receive espera até
nTimeout Numérico
receber algum dado pela conexão.
Retorno
Tipo Descrição
Numérico Qtde de bytes recebidos, se houver algum erro nQtdRecebida será menor
que zero.
Descrição
Recebe os dados pela conexão ativa do objeto, qualquer tipo de dado pode ser recebido.
Sintaxe
oObj:Reset ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Retorno nulo.
Descrição
Finaliza anormalmente a conexão, não avisa o outro lado que a conexão será finalizada.
Deve ser utilizado apenas em casos extremos.
Sintaxe
oObj:Send ( [ cBuffer ] ) --> nQtdTrasmitido
Parâmetros
Argumento Tipo Descrição
cBuffer Caracter Buffer com os dados a serem transmitidos pela conexão.
Retorno
Tipo Descrição
Numero de bytes transmitidos, caso o numero seja diferente do tamanho
Numérico
de cBuffer, algum erro aconteceu.
Descrição
Transmite o buffer pela conexão TCP Genérica ativa.
BANCO DE DADOS
Copy
Sintaxe
COPY [ FIELDS <campo,...> ] TO xcFile [ escopo ] [ WHILE <lCondicao> ] [ FOR
<lCondicao> ] [ SDF | DELIMITED [WITH <xcDelimiter>] ] [ VIA <xcDriver> ]
Parâmetros
Argumento Tipo Descrição
FIELDS <campo,...> especifica um ou mais campos,
FIELDS separados por vírgula, a serem copiados para a tabela de
Caracter
<campo,...> destino. Caso não especificado este parâmetro, serão
copiados todos os campos da tabela de origem.
TO <xcFile> especifica o nome do arquivo de destino. O
nome do arquivo de destimno pode ser especificado de
forma literal direta, ou como uma expressão Advpl, entre
parênteses.
TO xcFile Caracter
Caso sejam especificadas as cláusulas SDF ou
DELIMITED, é gerado um arquivo ASCII, com
extensão .txt por default.
<escopo> define a porção de dados da tabela atual a ser
coipiada. Por default, são copiados todos os registros
(ALL). Os escopos possíveis de uso são:
ALL - Copia todos os registros.
REST - Copia, a partir do registro atualmente posicionado,
escopo Caracter até o final da tabela.
NEXT <n> - Copia apenas <n> registros, iniciando a partir
do registro atualmente posicionado.
OBSERVAÇÃO : Vale a pena lembrar que o escopo é
sensível também às demais condições de filtro ( WHILE /
FOR ).
WHILE <lCondicao> permite especificar uma condição
para realização da cópia, a partir do registro atual,
WHILE
Lógico executada antes de inserir cada registro na tabela de
<lCondicao>
destino, sendo realizada a operação de cópia enquanto esta
condição for verdadeira.
FOR <lCondicao> especifica uma condição para cópia de
registros, executada antes de inserir um registro na tabela
FOR <lCondicao> Lógico
de destino, sendo a operação realizada apenas se
lCondicao ser verdadeira ( .T. )
[ SDF | Caracter [ SDF | DELIMITED [WITH <xcDelimiter>] ]
DELIMITED
[WITH SDF especifica que o tipo de arquivo de destino gerado é
<xcDelimiter>] ] um arquivo no formato "System Data Format" ASCII,
onde registros e campos possuiem tamanho fixo no
arquivo de destino.
DELIMITED especifica que o arquivo ASCII de destino
será no formato delimitado, onde os campos do tipo
Caractere são delimitados entre aspas duplas ( delimitador
Default ). Registros e campos têm tamanho variável no
arquivo ASCII.
DELIMITED WITH <xcDelimiter> permite especificar
um novo caractere, ou sequência de caracteres, a ser
utilizada como delimitador, ao invés do default ( aspas
duplas ). O caractere delimitador pode ser escrito de forma
literal, ou como uma expressão entre parênteses.
Nas Tabelas complementares A e B, na documentação do
comando, são detalhadas as especificações dos formatos
SDF e DELIMITED.
VIA <xcDriver> permite especificar o driver utilizado
para criar a tabela de destino dos dados a serem copiados.
VIA <xcDriver> Caracter
O Driover deve ser especificado como uma expressão
caractere. Caso especificado como um valor literal direto,
o mesmo deve estar entre aspas.
Descrição
COPY TO é um comando de banco de dados, que permite a cópia de todos ou parte
dos registros da tabela atualmente selecionada na área de trabalho atual, para um novo
arquivo. Os registros considerados para a cópia podem ser limitados pela cláusula
<escopo>, através de expressões FOR / WHILE , e/ou através de um filtro.
Se o filtro para registros deletados ( SET DELETED ) estiver desligado (OFF),
registros deletados ( marcados para deleção ) são copiados para o arquivo de destino,
mantendo este status. Caso contrário, nenhum registro deletado é copiado. Da mesma
maneira, caso exista uma condição de filtro na tabela atual ( SET FILTER ), apenas os
registros que satisfaçam a condição de fintro serão copiados.
Os registros são lidos na tabela atual, respeitando a ordem de índice setada. Caso não
hajam índices abertos, ou a ordem de navegação nos índices (SET ORDER ) seja 0
(zero), os registros são lidos em orden natural ( ordem de RECNO ) .
A tabela de destino dos dados copiados é criada, e aberta em modo exclusivo, antes
da operação de cópia efetiva ser iniciada.
Tabela A : Especificação do formato SDF ( System Data Format )
Elemento do Arquivo Formato
Campos 'C' Caractere Tamanho fixo, ajustado com espaços em branco
Campos 'D' Data Formato aaaammdd ( ano, mês, dia )
Campos 'L' lógicos T ou F
Campos 'M' Memo (campo ignorado)
Campos 'N' Numéricos Ajustados à direita, com espaços em branco.
Delimitador de Campos Nenhum
Separador de Registros CRLF ( ASCII 13 + ASCII 10 )
Marca de final de arquivo
Nenhum
(EOF)
Tabela B : Especificação do formato delimitado ( DELIMITED / DELIMITED WITH
<xcDelimiter> )
Elemento do Arquivo Formato
Campos 'C' Caractere Delimitados, ignorando espaços à direita
Campos 'D' Data Formato aaaammdd ( ano, mês, dia )
Campos 'L' lógicos T ou F
Campos 'M' Memo (campo ignorado)
Campos 'N' Numéricos sem espaços em branco.
Delimitador de Campos Vírgula
Separador de Registros CRLF ( ASCII 13 + ASCII 10 )
Marca de final de arquivo
Nenhum
(EOF)
Observações
A Linguagem Advpl, antes do Protheus, suportava a geração de uma tabela
delimitada diferenciada, obtida através do comando COPY TO (...) DELIMITED
WITH BLANK . No Protheus este formato não é suportado. Caso utilize-se este
comando com a sintaxe acima, o arquivo ASCII gerado será delimitado,
utilizando-se a sequência de caracteres 'BLANK' como delimitadora de campos
Caractere.
COPY STRUCTURE
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Sintaxe
COPY STRUCTURE TO <xcDataBase>
Parâmetros
Argumento Tipo
Descrição
Deve ser especificado em xcDatabase o nome da tabela a
TO <xcDataBase> Caracter
ser criada.
Descrição
COPY STRUCTURE é um comando de banco de dados, que cria uma nova tabela,
vazia, com a estrutura da tabela ativa na área de trabalho atual. Se a tabela a ser criada já
exista, a mesma é sobrescrita. A tabela de destino criada utiliza o mesmo RDD da tabela
de origem ( tabela ativa na área de trabalho atual ).
Observações
A Linguagem Advpl, antes do Protheus, suportava a parametrização de uma lista
de campos da tabela atual, para compor a estrutura da tabela de destino, através
da cláusula FIELDS <campo,...>. Esta opção não é suportada no Protheus. Caso
seja utilizada, o programa será abortado com a ocorrência de erro fatal :
'DBCopyStruct - Parameter <Fields> not supported in Protheus'
FUNÇÕES GENÉRICAS
Sintaxe
EXISTDIR ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função ExistDir tem como objetivo determinar se um path de diretório existe e é
valido.
Exemplo no server a partir do rootPath:
ExistDir('\teste')
Exemplo no client, passando o fullPath:
ExistDir('c:\APO')
Sintaxe
FTPVERSION ( ) --> cRet
Retorno
Tipo Descrição
Caracter Retorna uma String contendo o valor da versão de FTP.
Descrição
A função FtpVersion tem como objetivo determinar qual a versão do Protocolo de
Transferência de Arquivos.
Sintaxe
GETCOMPUTERNAME ( ) --> Nome da máquina
Retorno
Tipo Descrição
Caracter Nome da máquina
Descrição
Retorna o nome da máquina (HOSTNAME) que está executando o Protheus Remote
Sintaxe
GETENV ( < cVariavel > ) --> cRet
Parâmetros
Argumento Tipo Descrição
Nome da variavel de ambiente do sistema que desejamos
cVariavel Caracter
obter.
Retorno
Tipo Descrição
Retorna o conteúdo da varivavel de ambiente, se encontrada na tabela de
Caracter
variaveis de sistema. Caso contrário, retorna NIL.
Descrição
A função GetEnv() têm como objetivo determinar o valor de uma
variável do environment da plataforma(Sistema Operacional) em uso, no ambiente do
Protheus Server.
O valor de retorno da função será NIL se o parametro varname informado não for
encontrado na tabela das variáveis de ambiente do Sistema Operacional.
Exemplo:
cSysPath := GetEnv('PATH')
Sintaxe
GETENVSERVER ( ) --> cRet
Retorno
Tipo Descrição
Caracter String contendo o nome do environment em execução.
Descrição
A função GetEnvServer() tem como objetivo retornar uma string que nos permite
determinar o nome do Environment que está rodando atualmente no Server Protheus.
Um exemplo interessante da função é quando desejamos rodar um programa e nao
sabemos em qual environment estaremos.
StartJob('Teste', GetEnvServer(), .T., '99', '01' )
Sintaxe
GETREMOTETYPE ( ) --> nRmtType
Retorno
Tipo Descrição
Numérico nRmtType corresponde ào número correspondente à interface utilizada.
Descrição
Através da função GetRemoteType(), é possível identificar sob qual interface o
programa atual está em execução.
Esta função está disponível a partir do Protheus 8, Build 7.00.040308a
Pode-se utilizar as constantes abaixo, para avaliar o retorno da função.
NO_REMOTE -1 // Job, Web ou Working Thread ( Sem remote )
REMOTE_QT_WIN32 1 // Remote em ambiente Windows
REMOTE_QT_LINUX 2 // Remote em ambiente Unix/Linux
Sintaxe
GETSCREENRES ( ) --> Resolução[2]
Retorno
Tipo Descrição
Retorno da função onde:
Array Resolução[1] = Resolução horizontal
Resolução[2] = Resolução vertical
Descrição
Retorna Array com a resolução de tela da máquina executando o Protheus Remote
Sintaxe
IPCCount ( < cSemaforo > ) --> nRet
Parâmetros
Argumento Tipo Descrição
Indica o local ou Semafora em que as Threads foram
cSemaforo Caracter
iniciados.
Retorno
Tipo Descrição
A função retorna um inteiro indicando oo numero de Threads LIVRES de
Numérico
acordo com o semaforo indicado por parametro.
Descrição
A função IPCCount tem como objetivo obter todas as Threads que estão no ar em um
determinado ambiente indicado pelo semaforo.
A função irá retornar um inteiro indicando o total de threads livres que estão esperando
um IPCGo.
Sintaxe
IPCGo ( < cSemaforo > ) --> Nil
Parâmetros
Argumento Tipo Descrição
Indica o local ou Semaforo em que as Threads foram
cSemaforo Caracter
iniciados.
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função IPCGo tem como objetivo mandar uma chamada para uma Thread, na qual
nao precisa ser necessariamente em mesmos ambientes, que esteja em wait.
A IPCGo devemos através de um primeiro argumento da função, especificar o semaforo
que desejamos, a função irá pegar a primeira Thread Livre que encontrar em
IPCWait.
A função recebe mais 15 argumentos opcionais para passagem de dados, porém este
valor não pode ser um Boolean ou um CodeBlock.
Sintaxe
IPCWait ( < nTimeOut > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Numerico que Indica um tempo de timeOut em
nTimeOut Numérico
milissegundos, para a thread sair do ar.
Retorno
Tipo Descrição
Lógico Retorna true caso tenha recebido uma chamada da IPCGo, false caso nao
recebeu nehuma chamada ou saiu por timeOut.
Descrição
A função IPCWait() tem como objetivo colocar em modo de espera uma Thread que
acabou de ser carregada e fica aguardando oo chamado de uma IPCGo(). A função
recebe um parametro numérico que indica o timeOut em milissegundos de tempo para
que a Thread seja derrubada.
A IPCWait() recebe mais 15 parametros opcionais - que indica os parametros passados
pela IPCGo() -
Retorna true caso tenha chegado um chamado da IPCGo(), false não recebeu nenhum
IPCGo ou saiu por timeOut.
obs: note que nao foi indicado um valor de semaforo para a função, pois está
implicito o programa que iniciou a Thread.
Sintaxe
IPCWaitEx ( < cSemaforo > , < nTimeOut > ) --> nRet
Parâmetros
Argumento Tipo Descrição
cSemaforo Caracter Indica o nome do Semaforo que estamos trabalhando.
Numerico que Indica um tempo de timeOut em
nTimeOut Numérico
milissegundos, para a thread sair do ar.
Retorno
Tipo Descrição
Retorna true caso tenha recebido uma chamada da IPCGo, false caso nao
Lógico
recebeu nehuma chamada ou saiu por timeOut.
Descrição
A função IPCWaitEx() tem como objetivo colocar em modo de espera uma Thread que
acabou de ser carregada e fica aguardando oo chamado de uma IPCGo(). Na
IPCWaitEx() devemos indicar o nome do semaforo que queremos.
A função recebe como segundo parametro numérico que indica o timeOut em
milissegundos de tempo para que a Thread seja derrubada.
A IPCWaitEx() recebe mais 15 parametros opcionais - que indica os parametros
passados pela IPCGo() -
Retorna true caso tenha chegado um chamado da IPCGo(), false não recebeu nenhum
IPCGo ou saiu por timeOut.
Obs: note que na IPCWaitEx foi indicado um valor de semaforo para a função.
Sintaxe
ISSRVUNIX ( ) --> lisUnix
Retorno
Tipo Descrição
Se .T. o servidor está sendo executado em ambiente Unix(r) ou Linux(r)
Lógico
Se .F. o servidor está sendo executado em ambiente Windows(r)
Descrição
Informa se o servidor Advanced Protheus está sendo executado em ambiente UNIX ou
Linux.
Exemplo das funções IsSrvUnix e GetRemoteIniName
Revisão: 12/06/2003
Abrangência
Versão 6.09 Versão 7.10 Versão 8.11
Através do exemplo abaixo, podemos obter o path de execução do AP Remote.
#include "[Link]"
Function TstRmtPath()
Local cIniName:= GetRemoteIniName()
Local lUnix:= ISSRVUNIX()
Local nPos:= Rat( IIf(lUnix,"/","\"),cIniName )
Local cPathRmt
if nPos!=0
cPathRmt:= Substr( cIniName,1,nPos-1 )
else
cPathRmt:=""
endif
QOut( cPathRmt )
Return
Sintaxe
KILLAPP ( [ lKill ] ) --> lRet
Parâmetros
Argumento Tipo Descrição
Parametro opcional indicando se Thread corrente deve ser
lKill Lógico
finalizada.
Retorno
Tipo Descrição
retorna se thread corrente já recebeu algum aviso para ser finalizada(true),
Lógico
caso contrário retorna false.
Descrição
A função KillApp pode ser usada com dois objtivos diferentes de acordo com a
passagem de parametro.
Quando for feita uma chamada da funçao KillApp sem valor de parametro nenhum
informado, a função tem como objetivo retornar se a thread recebeu uma chamada para
ser finalizada. Um exemplo dessa situação é quando através do monitor de tarefas do
Protheus queremos derrubar uma determinada Thread porém esperamos o final da sua
utilização.
Exemplo:
//Thread irá ser finalizada
If KillApp()
/*tratamento de finalização*/
Endif
Quando for realizada a chamada da Função, passando um parametro booleano, ela tem
como objetivo finalizar a Thread no qual foi realizada a chamada da KillApp.
KillApp( .T. )
MSAPPBRINGTOFRONT ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Se o Protheus Remote está sendo executado em background (abaixo de outras janelas de
outros programas no desktop do usuário), a função MSAPPBRINGTOFRONT( ) pode
ser utilizada para avisar ao sistema operacional para que mude a disposição das janelas
ativas no desktop para que exiba a janela do Protheus Remote acima de todas as janelas
das outras aplicações em execução.
Nos sistemas operacionais Windows, se o sistema operacional não conseguir executar o
comando para movimentar as janelas, a barras de janelas do Windows ficará piscando
sobre a ocorrência do Protheus Remote para avisar o usuário sobre a intenção do
programa (Protheus Remote) ser visualizado.
Sintaxe
MSCRC32 ( < cString > ) --> nCRC
Parâmetros
Argumento Tipo Descrição
String de onde será calculado um CRC32, é garantido que
para a mesma string sempre se obterá um mesmo número,
cString Caracter
porém, não é garantido que para strings diferentes, os
números sejam sempre diferentes.
Retorno
Tipo Descrição
Um número inteiro , com até 10 (dez) dígitos , correspondente ao CRC da
Numérico
string informada como parâmetro.
Descrição
Calcula um CRC de uma string. A função MSCRC32() calcula um CRC de uma string
informada e retorna um número com esse cálculo.
Note que strings iguais retornam CRC iguais, porém, nem sempre strings diferentes
retornam CRC diferentes.
Através do exemplo abaixo , calculamos o CRC das strings informadas.
// Le o arquivo [Link] no ambiente do servidor
// e calcula o CRC do mesmo.
cString := memoread('\[Link]')
nCRC1 := MSCRC32(cString)
MsgStop('CRC = '+str(nCRC1,10))
Sintaxe
MSCRC32STR ( < cString > ) --> cCRC32
Parâmetros
Argumento Tipo Descrição
String a partir da qual será calculado o CRC32. É
garantido que para a mesma string sempre será obtido um
cString Caracter
mesmo CRC , mas não é garantido que para strings
diferentes os CRCs sejam sempre diferentes.
Retorno
Tipo Descrição
Caracter Uma string com o CRC da string informada.
Descrição
MSCRC32STR() calcula um CRC de uma string informada , retornando uma string com
esse cálculo.
Note que strings iguais retornam CRC iguais, porém nem sempre strings diferentes
retornam CRC diferentes.
Através do exemplo abaixo , calculamos o CRC das string informada.
// Le o arquivo [Link] no ambiente do servidor
// e calcula o CRC32 do mesmo.
cString := memoread('\[Link]')
cCRC32 := MSCRC32STR(cString)
MsgStop('CRC = ['+cCRC32+']')
Sintaxe
PROCESSMESSAGES ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Muitas vezes desenvolvemos rotinas de duração longa que quando chamadas através de
uma ação no Protheus Remote (Exemplo: Opção acionada no menu) provocam um
'congelamento' temporário nas telas do Protheus Remote.
Para minimizar esse efeito, podemos utilizar a função PROCESSMESSAGES( ) para
que o Protheus Remote possa renovar a pintura de suas janelas ou reagir a ação do
mouse durante um processamento longo sendo executado no Protheus Server. Como o
exemplo a seguir :
while nRecs<1000
ProcessMessages( )
// Processo Longo
DoSomethingLongTime( )
nRec--
enddo
Cuidado: O uso intensivo da função ProcessMessages( ) provocará tráfego elevado
de rede entre o Protheus Remote e Protheus Server comprometendo o uso dos
recursos de rede na rede inteira da Empresa. Portanto a função deve ser utilizada
com muita cautela. Código como o abaixo deve ser evitado:
for i:=1 to 10
ProcessMessages( )
next i
Sintaxe
RANDOMIZE ( < nMinimo > , < nMaximo > ) --> nAleatorio
Parâmetros
Argumento Tipo Descrição
nMinimo Numérico Corresponde ao menor numero a ser gerado pela função.
Corresponde ao maior número ( menos um ) a ser gerado
nMaximo Numérico
pela função.
Retorno
Tipo Descrição
Numérico Numero randômico , compreendido no intervalo entre (nMinimo) e
(nMaximo-1) : O numero gerado pode ser maior ou igual à nMinimo e
menor ou igual a nMaximo-1 .
Descrição
Através da função randomize() , geramos um numero inteiro aleatório, compreendido
entre a faixa inferior e superior recebida através dos parâmetros nMinimo e nMaximo,
respectivamente.
Observação :
O limite inferior recebido através do parâmetro nMinimo é "maior ou igual a ", podendo
ser sorteado e fazer parte do retorno; porém o limite superior é "menor que", de modo a
nunca será atingido ou devolvido no resultado. Por exemplo , a chamada da função
randomize(1,2) sempre retornará 1 .
Sintaxe
SENDTOFORE ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Esta função não retorna valor
Descrição
Esta função torna a aplicação do Remote foreground na estação em que está sendo
executado.
Faz com que a janela ativa do Remote fique acima de todas as janelas de outras
aplicações executadas na estação.
Extremamente dependente do sistema operacional em uso, as vezes pode falhar devido
ao sistema operacional não suportar o comando ou devido a carga excessiva do sistema,
o sistema operacional pode ignorar o comando.
Sintaxe
SOCKETCONN ( < cIP > , < nPort > , < cReq > , < nTimeOut > ) --> Nil
Parâmetros
Argumento Tipo Descrição
cIP Caracter Representa uma String com o endereço IP ou nome da
máquina do destino desejado.
Indica o número da porta pelo qual será realizada a
nPort Numérico
conexão.
Representa a requisição que será feita para a maquina
cReq Caracter
desejada, assim que a conexão for estabelecida.
Indica o valor de tempo em segundos no qual a conexão
nTimeOut Numérico
será encerrada por tempo de inatividade(time out).
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função SocketConn é usada para criar uma conexão com um determinado destino,
através da conexão de um Socket Client.
Para Realizar esta conexão informamos o destino, no qual pode ser informado em forma
de IP ou através de um nome de máquina. Em seguida informamos o numero de
porta na qual será realizado um bind através dessa porta.
Em seguida informamos através de string o tipo de requisição que iremos realizar, pois
quando a conexão ao socket destino é completada com sucesso, a função irá enviar e
receber dados de acordo com a requisição que fizemos.
Por último informamos o total de tempo em segundos que a função irá ficar esperando
por uma resposta do destino informado.
Sintaxe
XMLERROR ( ) --> nXmlStatus
Retorno
Tipo Descrição
Retorna o status da ultima operação de Criação de Objeto XML realizado
Caracter
pelo comando CREATE oXml ...
Descrição
A funcao XmlError() retorna um status da execução da ultima rotina de criação de
Objeto XML realizada pelo comando CREATE oXML. Podemos utilizar-nos das
constantes definidas no arquivo #INCLUDE "[Link]" para realizar o tratamento
de erro. Vide tabelas de constantes abaixo :
----------------------------------------
Constante Valor
----------------------------------------
XERROR_ONLYFIRSTNODE -1
XERROR_SUCCESS 0
XERROR_FILE_NOT_FOUND 1
XERROR_OPEN_ERROR 2
XERROR_INVALID_XML 3
----------------------------------------
#INCLUDE "[Link]"
Local oXml , nXmlStatus
CREATE oXML XMLFILE "\[Link]"
nXmlStatus := XMLError()
If ( nXmlStatus != XERROR_SUCCESS )
Alert("Falha ("+str(nXmlStatus,3)+") na criação do XMLl")
Else
//processamento dop XML ....
Endif
Sintaxe
compress ( < @cBufferOut > , < @nLenghtOut > , < @cBufferIn > , < @nLengthIn > )
--> bOk
Parâmetros
Argumento Tipo Descrição
Retorna o buffer compactado, a variável deverá ser do
cBufferOut Caracter tipo caracter. O Retorno compactado conterá caracteres
binários, incluindo zero binário.
Retorna o tamanho do buffer compactado, quando os
nLenghtOut Numérico dados compactados são pequenos, o buffer de saída pode
ser maior que o buffer original.
Buffer que deverá ser compactado, podem conter
cBufferIn Code-Block
caracteres binários, o buffer pode ter no máximo 1Mb.
nLengthIn Numérico Tamanho do buffer a ser compactado.
Retorno
Tipo Descrição
Retorna .T., caso o buffer foi compactado com sucesso.
Lógico
Retorna .F., caso não seja possível compactar o buffer.
Descrição
Compacta um buffer recebido, através do algoritmo proprietário.
Na maioria dos casos o buffer recebido será menor do que o buffer original, em casos
onde o buffer original é muito pequeno, menos de 128 bytes, o buffer de saída poderá
ser maior do que o o buffer original.
Essa função aceita e retorna caracteres binários de vários tipos, incluindo o zero binário.
O Resultado dessa função não deverá ser gravado em banco de dados, especialmente
TopConnect.
Exemplos
user function TSTComp
Local cNaoComp := replicate( 'A', 1024 )
Local cComp := '', cResult := ''
Local nTamNaoComp := len( cNaoComp )
Local nTamComp := 0
Local bResp
bResp := compress( @cComp, @nTamComp, cNaoComp, nTamNaoComp )
If( bResp )
Alert( "Buffer Compactado - Tamanho Compactado" + str( nTamComp
) )
else
Alert( "Falha ao compactar o Buffer!" )
return
endif
bResp := uncompress( @cResult, @nTamNaoComp, cComp, nTamComp )
If( !bResp )
Alert( "Falha ao descompactar o Buffer!" )
return
endif
if( cResult != cNaoComp )
Alert( "Buffer descompactado diferente do buffer original" )
else
Alert( "Buffer descompactado igual ao buffer original" )
endif
return .t.
Sintaxe
uncompress ( < @cBufferOut > , < @nLengthOut > , < cBufferIn > , < @nLengthIn > )
--> bOK
Parâmetros
Argumento Tipo Descrição
Buffer descompactado, exatamente o buffer que foi
cBufferOut Caracter
passado pela função compress.
nLengthOut Numérico Tamanho do buffer descompactado
cBufferIn Caracter Buffer compactado pela função compress.
Tamanho do buffer compacto, informação fundamental
nLengthIn Numérico
para a correta descompactação do buffer.
Retorno
Tipo Descrição
Retorna .t., caso o buffer foi descompacto com sucesso.
Lógico
Retorna .F., caso não seja possível descompactar o buffer.
Descrição
Descompacta um buffer recebido, através do algoritmo proprietário.
Este buffer devera ser gerado pela função compress.
Essa função aceita e retorna caracteres binários de vários tipos, incluindo o zero binário.
FUNÇÕES DE IMPRESSÃO
Sintaxe
GETIMPWINDOWS ( < lServer > ) --> aPrinters
Parâmetros
Argumento Tipo Descrição
Informar .T. se a lista de impressoras deve ser obtida do
lServer Lógico Protheus Server ou .F. para obter lista de imporessoras da
estação Remota. Este parâmetro é obrigatório.
Retorno
Tipo Descrição
Array com nome das impressoras disponíveis. Vale lembrar que esta
Array
função não verifica o status atual da(s) impressora(s) encontrada(s).
Descrição
GETIMPWINDOWS( ) retorna uma lista de impressoras disponíveis no spool do Server
ou Remote. Se o Server está em ambiente Unix, a GETIMPWINDOWS() retornará a
lista com os nomes de impressoras cadastradas na chave PRINTERSNAME do arquivo
de configuração do Protheus Server.
Caso não seja encontrada nenhuma impressora , é retornado um array com 1 elemento ,
contendo a String "Nenhuma Impressora Disponivel".
Observação : Caso a função seja passada com o argumento .F. ( buscar
impressoras da estação Remote ) , porém a função seja executada a partir de um
JOB ( programa sem a interface Remota ) , o array retornado terá apenas 1
elemento , contendo a String "Nenhuma Impressora Disponivel".
Exemplos
No exemplo abaixo , determinamos as impressoras disponíveis na estação Remote e no
Server , respectivamente. E , mostramos no Console do Server a(s) impressora(s)
encontrada(s).
aImpRemote := GetImpWindows(.F.)
conout('Impressoras na estação remota')
aeval(aImpRemote , { |x| conout(x) })
aImpServer := GetImpWindows(.T.)
conout('Impressoras no Servidor')
aeval(aImpServer , { |x| conout(x) })
Sintaxe
GETPORTACTIVE ( < lServer > ) --> aPortImp
Parâmetros
Argumento Tipo Descrição
CAso especificado .T. , a lista de impressoras será obtida
lServer Lógico
do Server, caso .F. a lista será obtida da estação (Remote).
Retorno
Tipo Descrição
Array Array com as portas de impressão disponíveis.
Descrição
Retorna lista de portas de impressão disponíveis. A função GETPORTACTIVE( )
retorna uma lista de portas de impressão disponíveis do Protheus Server ou Remote. Se
o Protheus Server está em ambiente Unix, a GETPORTACTIVE() retornará uma lista
com os nomes de devices possíveis para impressão.
Caso não sejam encontradas portas para impressão , é retornado um array com apenas
um elemento , contendo a string "Nao existem portas disponiveis".
Observação : Caso a função seja chamada com o parâmetro .F. , para obter as
portas de impressão da estação remota , porém a função seja chamada através de
um JOB ( programa sem a interface Remote ) , a mesma retornará um array com
um elemento , contendo a string "Nao existem portas disponiveis".
[RELEASE] Builds superiores a 7.00.041130p
Ao verificar os devices de impressão disponíveis no SERVER, os devices especificados
na configuração de bloqueio de portas de impressão ( DisableDevicePort ) no server
não são listados por esta função.
Quando executada em ambiente Linux, os devices de impressão disponíveis no
SERVER, a função deixa de retornar os devices como /dev/lp0 e /dev/ttys0 ... e passa a
retorná-los a nomenclatura LPT1:...COM1:... , limitando o retorno em no máximo
4 portas paralelas e 4 portas seriais.
Exemplos
No exemplo abaixo, determinamos as portas de impressão disponíveis na estação
Remote e no Server, respectivamente. E mostramos no Console do Server a(s) porta(s)
encontrada(s).
aPortRemote := GetPortActive(.F.)
conout('Impressoras na estação remota')
aeval(aPortRemote , { |x| conout(x) })
aPortServer := GetPortActive(.T.)
conout('Impressoras no Servidor')
aeval(aPortServer , { |x| conout(x) })
Veja abaixo um exemplo do que foi mostrado no console do Protheus Server, apos a
execução da rotina.
Impressoras na estação remota
COM1:
COM2:
COM3:
COM4:
FILE:
LPT1:
LPT2:
LPT3:
\\prnserver\prx-lp1
Impressoras no Servidor
COM1:
COM2:
COM3:
COM4:
FILE:
LPT1:
LPT2:
LPT3:
FUNÇÕES INTERFACE http
ENCRYPTRSA ( < cFileKey > , < cInfo > , [ lEncode64 ] ) --> cRet
Parâmetros
Argumento Tipo Descrição
Representa o nome do arquivo, que contém a chave para
cFileKey Caracter
criptografar a informação, o arquivo deve ser do tipo .pem
Representa a informação que desejamos ser criptografada
cInfo Caracter
usando RSA.
Caso desejamos que a saída dos dados venha encodado em
lEncode64 Lógico
base 64 informamos true, caso contrário false.
Retorno
Tipo Descrição
Retorna as informações passadas através do argumento, criptografadas em
Caracter
RSA.
Descrição
A função EncryptRSA tem como objetivo realizar a criptografia de dados, para isso usa
um tipo de criptografia denominada RSA.
O RSA é um algoritmo de Criptografia Assimétrica, isto significa que possuímos uma
chave pública e privada, RSA é o mais usado algoritmo de chave pública, pois provê
confidencialidade e assinatura digital.
A chave pública é a que serve para cifrar a mensagem (Confidencialidade) e decifrar a
mensagem (Autenticidade). Todos que desejarem lhe enviar uma mensagem devem
conhecê-la.
Chave privada, que serve para decifrar a mensagem (Confidencialidade) e cifrar a
mensagem (Autenticidade). Somente uma pessoa deve conhecê-la.
Em nossa função informamos o local onde se encontra a chave que será usada, em
seguida passamos como string os dados que queremos criptografar, podemos ainda
informar se desejamos o retorno em base 64 ou nao.
Sintaxe
GETWEBJOB ( ) --> cJobName
Retorno
Tipo Descrição
cJobName corresponde ào nome do job que configura a working Thread
atual em uso. Caso a chamada da função seja realizada a partir de uma
Caracter thread que não seja uma Working Thread ( como por exemplo , uma
thread iniciada a partir de um ApxRemote ) , a função GetWebJob()
retornará uma string vazia ("").
Descrição
Através desta função , é possível recuperar o nome da configuração de Working
Threads ( Job ) que está sendo utilizada pela Working Thread atual.
Observação : Esta função está disponível a partir dos Build's Ap6 gerados a partir
de 05/09/2002.
Sintaxe
GetEnvHost ( ) --> cHost
Retorno
Tipo Descrição
Quando em ambiente web retorna o host que foi utilizado para chamar a
Caracter
função.
Descrição
Retorna quando em ambiente web, por qual host a página foi chamada.
Exemplo:
web function retHost
return getenvhost() // Retorna o nome do host que chamou essa funcao ( Ex:
[Link] )
Sintaxe
HTTPCACHE ( < cCacheControl > ) --> cLastCache
Parâmetros
Argumento Tipo Descrição
Define o novo conteúdo da etiqueta do Header de Retorno
cCacheControl Caracter
HTTP Cache-Control.
Retorno
Tipo Descrição
Esta função retorna a definição atualmente utilizada para a etiqueta
Caracter
Cache-Control do Header HTTP.
Descrição
Através desta função , podemos redefinir a etiqueta CACHE-CONTROL do Header de
Resposta de requisição HTTP , sobrepondo à definição defaut de retorno CACHE-
CONTROL , opcionalmente definida na configuração do HOST HTTP no Arquivo de
configuração do Protheus Server.
Tabela A - Definições CACHE-CONTROL
Conteúdo Aplicação
Nenhuma informação deve ser guardada em Cache pelo servidor e/ou
no-store
proxie(s).
Observação : A definição de um novo conteúdo para o CACHE-CONTROL do
Header HTTP apenas será possível caso esta função Advpl seja executada
antes de qualquer envio parcial de html ao browser , realizado pela
função HttpSend().
Sintaxe
HTTPCOUNTSESSION ( ) --> nCount
Retorno
Tipo Descrição
nCount corresponde ao número de usuários que possuem variáveis de
Numérico
session em uso no Server PRotheus.
Descrição
Esta função retorna o número de Sessions de usuários que estão atualmente em uso na
memória.
** ATENÇÃO : Devemos atentar ao fato que esta função apenas terá o efeito
desejado caso o ambiente atual em uso pelo Projeto WEB seja WEBEX ( Web
Extended ) **
OBSERVAÇÃO : Esta função foi implementada na Ferramenta Ap6 Server , sendo
necessário adquirir um Build de Protheus Server com data igual ou superior a
22/04/2002.
Sintaxe
HTTPCTDISP ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função tem o objetivo de prover informações sobre como apresentar uma mensagen
ou como parte de um pacote.
Quando uma parte de um pacote Http é para ser tratada como um arquivo atachado, a
função irá setar essa parte do cabeçalho http(Content-Disposition) como um nome de
arquivo sugerido de acordo com o parâmetro.
Obs.: Caso ocorra a necessidade de verificar os tipos de parâmetros usados pelo
protocolo Http das opções possíveis para Content-Disposition:
[Link]
Obs.: A função fuciona somente em Links APW
Exemplos
Neste exemplo criamos uma função STATIC getFile(). Para usarmos a função devemos
apenas informar o endereço fisico em disco de um aquivo.
Criamos um pequeno buffer, para ir mandando o pacote ao browser, em seguida
abrimos o arquivo com a função FOpen() e pegamos o tamanho do arquivo com a
função FSeek().
Definimos com a função HttpCTType o tipode arquivo que iremos carregar, em nosso
exemplo apenas arquivos texto. Usamos a HttpCTDisp informando ao browser que
estamos carregando um attachment, no caso está linha irá fazer aparecer a tela de
download de um aquivo do seu Browser default e informamos o local do arquivo.
Em seguida informamos ao browser qual o tamanho desse arquivo, retornado da função
FSeek(), e começamos a enviar o arquivo em pequenos pedaços de 1024bytes.
static Function GetFile( cFile )
Local cHtml := ''
Local cBuffer := space(1024)
Local hArq
Local nTam
If !file(cFile)
cHtml += '
Arquivo '+cFile+' não encontrado.
'
ElseIf (hArq := FOpen(cFile)) < 0
cHtml += '
Falha na Abertura do Arquivo '+cFile+' ( FERROR '+str(ferror(),4)+' )
'
Else
// Le o arquivo e manda p/ o browse
nTam := FSeek(hArq, 0, 2)
FSeek(hArq, 0, 0 )
HttpSetPart(.T.)
HttpCTType("text/plain")
HttpCTDisp('attachment; filename="'+cFile+'"')
HttpCTLen(nTam)
While FRead(hArq, @cBuffer, 1024)>0
HttpSend(cBuffer)
EndDo
FClose(hArq)
Endif
Return cHtml
Sintaxe
HTTPEXITPROC ( < cFunction > ) --> Nil
Parâmetros
Argumento Tipo Descrição
String que indica o nome da função a ser chamada quando
cFunction Caracter
a Session for finalizada por time-out.
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A httpExitProc tem o objetivo de setar uma função que será chamada quando uma
Session for Finalizada por Time-Out.
A função que será chamada para tratamento da session finalizada, deve estar compilada
no repositório de dados corrente.
Muito útil quando se deseja encaminhar todas 'quedas' de Session para uma única
função de tratamento.
Sintaxe
HTTPFREESESSION ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Esta função sempre retorna NIL
Descrição
Através da função HttpFreeSession , eliminamos da memória do Servidor Protheus
todas as variáveis de Session do usuário atual. Normalmente utilizamos esta função em
operações de LOGOFF , onde necessitamos limpar todas os conteudos relacionados à
Session deste usuário.
** ATENÇÃO : Devemos atentar ao fato que esta função apenas terá o efeito
desejado caso o ambiente atual em uso pelo Projeto WEB seja WEBEX ( Web
Extended ) **
OBSERVAÇÃO : Esta função foi implementada na Ferramenta Ap6 Server , sendo
necessário adquirir um Build do Servidor Protheus Server com data igual ou superior a
22/04/2002.
Sintaxe
HTTPGET ( < cUrl > , [ cGETParms ] , [ nTimeOut ] ) --> cHttp
Parâmetros
Argumento Tipo Descrição
cUrl corresponde ao endereço http , juntamente com a
cUrl Caracter
pasta e o documento solicitados.
cGETParms corresponde à StringList de parâmetros a
cGETParms Caracter serem enviados ao servidor http através da URl . Caso não
especificado , este parâmetro é considerado vazio ("")
Em nTimeOut especificamos o tempo em segundos
máximo de inatividade permitido durante a recepção do
nTimeOut Numérico
documento . Caso não especificado , o valor default
assumido é 120 segundos ( 2 minutos).
Retorno
Tipo Descrição
Caracter String Html correspondendo ao documento solicitado.
Descrição
A função HttpGet() permite a emulação de um Client HTTP através de uma função
Advpl, acessando um determinado documento html publicado em um servidor Web,
utiliando o método GET , permitindo a passagem de parâmetros via URL, aguardando
por um tempo determinado (time-out) pela resposta do servidor solicitado.
Observações :
--- Na passagem de parâmtros GET , devemos atentar ao formato da string a ser passada
como parâmetros , pois a mesma segue o formato URI (Uniform Resource Identifiers) :
Query Component.
--- Caso nao seja retornado o documento antes do término do Time-out especificado na
chamada da função; ou caso não seja possível localizar o servidor ; seja por falha de
resolução de DNS , ou por erro de sintaxe ao especificar a URL , a função retornará
Nulo (NIL).
--- Caso nao seja possível o acesso ao documento , como por exemplo o documento não
exista , será retornado uma string html com a mensagem de erro html enviada pelo
servidor correspondente.
OBSERVACAO : Esta funcão está disponivel apenas em Builds Ap6 gerados a partir de
10/07/2002
Sintaxe
HTTPGETPART ( ) --> bPartEnabled
Retorno
Tipo Descrição
Lógico Retorna .t. se o envio parcial do conteúdo HTML está habilitado.
Descrição
Esta função retorna se o envio parcial de conteúdo ao browser está ou não habilitado.
Sintaxe
HTTPGETSTATUS ( ) --> nStatus
Retorno
Tipo Descrição
Numérico Retorna o status da conexão HTTP atual requerida
Descrição
A função tem o objetivo de retornar qual o status da conexão HTTP requisitada.
Para tal tarefa a função retorna valores de acordo com o protocolo HTTP, entre eles os
mais comuns e importantes são:
Error codes
500 - 'Internal Server Error'
501 - 'Not Implemented'
502 - 'Bad Gateway'
403;14 - 'Forbidden - Directory Listing Denied'
200 - 'Sucess Connection'
Exemplos
Neste exemplo usamos a função HttpGetStatus para termos certeza de que não temos
uma conexão HTTP válida, para isto verificamos o código retornado pela função.
Estando tudo correto, realizamos uma emulação de post para a função no inicio do fonte
- ExHTTPPost() - retornando uma simples tabela com os dados postados.
Em seguida ainda verificamos a conexão após o Post.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
Web Function ExHTTPPost()
Local cHtml := ""
if (HttpPost->login != Nil .AND. HttpPost->pass != Nil)
conout("Post com Sucesso\nlogin: "+HttpPost->login + "\
nPass: "+ HttpPost->pass)
cHtml := "<h3>HttpPost</h3><br><br>"
cHtml += "<table width=200 border=1>"
cHtml +=
"<tr><td>Login</td><td>"+HttpPost->login+"</td></tr>"
cHtml +=
"<tr><td>Senha</td><td>"+HttpPost->pass+"</td></tr>"
cHtml += "</table>"
endif
Return cHtml
web Function loginMK()
Local cHtml := ""
if HttpGetStatus() == 0
cHtml := HTTPPOST( "[Link] "",
"login=Teste&pass=123", 120 , NIL )
conout( HttpGetStatus() )
if HttpIsConnected()
conout("isConnected")
endif
endif
Return cHtml
Sintaxe
HTTPLEAVESESSION ( ) --> NIL
Retorno
Tipo Descrição
(NULO) A função HttpLeaveSession() sempre retorna NIL
Descrição
Esta função , uma vez executada , libera o processamento de requisição de atualizãção
de conteúdos de variáveis tipo HttpSession para requisições de consulta e/ou
atualizações simultâneas para o usuário atual.
** ATENÇÃO : Devemos atentar ao fato que esta função apenas terá o efeito
desejado caso o ambiente atual em uso pelo Projeto WEB seja WEBEX ( Web
Extended ) **
OBSERVAÇÃO : Esta função foi implementada na Ferramenta Ap6 Server , sendo
necessário adquirir um build de Server PRotheus com data igual ou superior a
22/04/2002.
Sintaxe
HTTPLOGONUSER ( ) --> cLogonUser
Retorno
Tipo Descrição
Caracter String contendo o login do usuário, no formato DOMINIO\login. Caso a
função não seja executada em uma thread iniciada em uma interface http ,
ou o acesso anônimo ào site no IIS esteja habilitado , a função retornará
uma string em branco ("").
Descrição
Através da Função HttpLogonUser() , quando utilizamos o AP Server ISAPI
( [Link]) , em conjunto com o Microsoft IIS (Internet Information Services ) ,
obtemos o login do usuário atual.
Observação : Para que o usuário seja obrigado a informar um login individual ,
deve ser desabilitado no IIS a configuração que permite acesso anônimo ao site.
Caso esta configuração não seja alterada , todos os usuários serão identificados
como "anônimos" pelo IIS, e a função retornará uma String em branco.
Sintaxe
HTTPOTHERCONTENT ( ) --> cContent
Retorno
Tipo Descrição
cContent é a string correspondendo ao conteúdo do corpo do pacote
Caracter
HTML postado no Server.
Descrição
A função HttpOtherContent() , quando utilizada em uma thread montada e/ou
inicializada para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo do
pacote html proveniente de uma operação de POSTagem de dados, se e somente se a
operacão de POSTagem especificou no HEader HTTP um content-disposition ou
content-type não tratados automaticamente pelo Server PRotheus.
Caso a requisição não tenha sido realizada por um client HTTP através do método de
postagem , ou a postagem já possua tratamento nativo no Server Protheus , ou a função
seja chamada em um ambiente que não esteja atendendo à uma requisição Http ( como
um JOB , por exemplo) , a função retornará uma string em branco ("").
Sintaxe
HTTPPOST ( < cUrl > , [ cGETParms ] , [ cPOSTParms ] , [ nTimeOut ] ,
[ aHeadStr ] ) --> cHtml
Parâmetros
Argumento Tipo Descrição
cUrl Caracter cUrl corresponde ao endereço http , juntamente com a
pasta e o documento solicitados.
cGETParms corresponde à StringList de parâmetros a
cGETParms Caracter serem enviados ao servidor http através da URl . Caso não
especificado , este parâmetro é considerado vazio ("")
cPostParms corresponde à StringList de parâmetros a
serem enviados ao servidor http através do pacote HTTP .
cPOSTParms Caracter
Caso não especificado , este parâmetro é considerado
vazio ("")
Em nTimeOut especificamos o tempo em segundos
máximo de inatividade permitido durante a recepção do
nTimeOut Numérico
documento . Caso não especificado , o valor default
assumido é 120 segundos ( 2 minutos).
Através deste parametro , podemos especificar um array
aHeadStr Array com strings a serem acrescentadas ao Header da
requisição HTTP a ser realizada.
Retorno
Tipo Descrição
Através de cHtml será retornada a String Html correspondendo ao
Caracter
documento solicitado.
Descrição
A função HttpPost() permite a emulação de um Client HTTP através de uma função
Advpl, postando um bloco de informações para um determinado documento publicado
em um servidor Web, utiliando o método POST , permitindo a passagem de parâmetros
adicionais via URL e aguardando por um tempo determinado (time-out) pela resposta
do servidor solicitado.
Observações :
Na passagem de parâmtros GET e POST , devemos atentar ao formato da string
a ser passada como parâmetros , pois a mesma segue o formato URI (Uniform
Resource Identifiers) : Query Component.
Caso nao seja retornado o documento antes do término do Time-out especificado
na chamada da função; ou caso não seja possível localizar o servidor ; seja por
falha de resolução de DNS , ou por erro de sintaxe ao especificar a URL , a
função retornará Nulo (NIL).
Caso nao seja possível o acesso ao documento , como por exemplo o documento
não exista ,será retornado uma string html com a mensagem de erro html
enviada pelo servidor correspondente.
Quando utilizamos a função HttpPost() , podemos especificar um Content-Type
diferenciado para o conteúdo postado. Caso não seja especificado um Content-
Type , alguns servidores tratam a informação postada como sendo um dado do
tipo 'application/x-www-form-url' , seria o equivalente a um formulário HTML
postado via Browser, outros servidores poderão não reconhecer tal informação
postada dessa forma. Para especificar que o conteúdo postado deve ser tratado
como um POST de formulário HTTP , devemos passar no parâmetro aHeadStr ,
um elemento contendo 'Content-Type: application/x-www-form-url'.
ATENÇÃO
1. Esta funcão está disponivel apenas em Builds Ap6 gerados a partir de
10/07/2002 .
2. O parametro aHeadStr apenas está disponível em Build's Ap6 e posteriores
gerados apos 01/10/2002.
Exemplos
Neste exemplo usamos a função HttpGetStatus para termos certeza de que não temos
uma conexão HTTP válida, para isto verificamos o código retornado pela função.
Estando tudo correto, realizamos uma emulação de post para a função no inicio do fonte
- ExHTTPPost() - retornando uma simples tabela com os dados postados.
Em seguida ainda verificamos a conexão após o Post.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
Web Function ExHTTPPost()
Local cHtml := ""
if (HttpPost->login != Nil .AND. HttpPost->pass != Nil)
conout("Post com Sucesso\nlogin: "+HttpPost->login + "\
nPass: "+ HttpPost->pass)
cHtml := "<h3>HttpPost</h3><br><br>"
cHtml += "<table width=200 border=1>"
cHtml +=
"<tr><td>Login</td><td>"+HttpPost->login+"</td></tr>"
cHtml +=
"<tr><td>Senha</td><td>"+HttpPost->pass+"</td></tr>"
cHtml += "</table>"
endif
Return cHtml
web Function loginMK()
Local cHtml := ""
if HttpGetStatus() == 0
cHtml := HTTPPOST( "[Link] "",
"login=Teste&pass=123", 120 , NIL )
conout( HttpGetStatus() )
if HttpIsConnected()
conout("isConnected")
endif
endif
Return cHtml
Sintaxe
HTTPPOSTXML ( < cURL > , [ cParam ] , < cFile > , < nTimeOut > ) --> lRet
Parâmetros
Argumento Tipo Descrição
cURL Caracter Indica o endereço para qual será feito o POST dos dados.
bloco de informações, que utiliando o método POST será
cParam Caracter
feita a passagem de parâmetros adicionais.
Indica um path de um arquivo local armazenado em
cFile Caracter
disco.
Representa o tempo(timeout) de inatividade em que a
nTimeOut Numérico
requisição irá aguardar em segundos.
Retorno
Tipo Descrição
Retorna se foi possível realizar o PostXml. Caso seja realizado retorna
Lógico
true, caso contrário false.
Descrição
A função HttpPostXml() permite a emulação de um Client HTTP através de uma função
Advpl.
Postando um bloco de informações e um documento XML indicado por uma
string path, para um determinado documento publicado em um servidor Web, utiliando
o método POST , permitindo a passagem de parâmetros adicionais e aguardando por um
tempo determinado (time-out) pela resposta do servidor solicitado.
Sintaxe
HTTPPRAGMA ( < cPragma > ) --> cOldPragma
Parâmetros
Argumento Tipo Descrição
cPragma corresponde ao conteudo do PRAGMA a ser
cPragma Caracter definido no Header de retorno HTTP. Veja tabela "A" de
definições PRAGMA.
Retorno
Tipo Descrição
A função HttpPragma retornará a definição anterior de PRAGMA
Caracter
utilizada.
Descrição
Através desta função , podemos redefinir a etiqueta PRAGMA do Header de Resposta
de requisição HTTP , sobrepondo à definição defaiut de retorno PRAGMA ,
opcionalmente definida na configuração do HOST HTTP no Arquivo de configuração
do Protheus Server.
Tabela A - Definições Pragma
Conteúdo Aplicação
Informa ao Client HTTP ( Browser ) que a página retornada não deve ser
no-cache
colocada em Cache, independente da configuração de Cache do Browser.
Observação : A definição de um novo conteúdo para o PRAGMA do Header
HTTP apenas será possível caso esta função Advpl seja executada antes
de quaqlquer envio parcial de html ao browser , realizado pela função
HttpSend().
Sintaxe
HTTPRCTDISP ( ) --> cCtDisp
Retorno
Tipo Descrição
cCtDisp corresponde ào conteudo do identificador Content-disposition ,
Caracter recebido quando um Web Browser realiza uma requisição via HTTP ao
servidor.
Descrição
A função HttpRCtDisp() , quando utilzada em uma thread montada e/ou inicializada
para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo do identificador
Content-disposition do Header HTTP .
Caso a requisição tenha sido realizada por um client HTTP que não enviou este
identificador no Header HTTP , ou a função seja chamada em um ambiente que não
esteja atendendo à uma requisição Http ( como um JOB , por exemplo) , a função
retornará uma String em branco ("").
Sintaxe
HTTPRCTLEN ( ) --> nCtLen
Retorno
Tipo Descrição
nCtLen corresponde ào conteudo do identificador Content-length ,
Numérico recebido quando um Web Browser realiza uma requisição via HTTP ao
servidor.
Descrição
A função HttpRCtLen() , quando utilizada em uma thread montada e/ou inicializada
para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo do identificador
Content-length do Header HTTP , como um dado numérico .
Caso a requisição tenha sido realizada por um client HTTP que não enviou este
identificador no Header HTTP , ou a função seja chamada em um ambiente que não
esteja atendendo à uma requisição Http ( como um JOB , por exemplo) , a função
retornará 0 ( Zero ) .
Sintaxe
HTTPRCTTYPE ( ) --> cCtType
Retorno
Tipo Descrição
cCtType corresponde ào conteudo do identificador Content-type ,
Caracter recebido quando um Web Browser realiza uma requisição via HTTP ao
servidor.
Descrição
A função HttpRCtType() , quando utilzada em uma thread montada e/ou inicializada
para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo do identificador
Content-type do Header HTTP .
Caso a requisição tenha sido realizada por um client HTTP que não enviou este
identificador no Header HTTP , ou a função seja chamada em um ambiente que não
esteja atendendo à uma requisição Http ( como um JOB , por exemplo) , a função
retornará uma String em branco ("").
Sintaxe
HTTPRCTTYPE ( ) --> cCtType
Retorno
Tipo Descrição
cCtType corresponde ào conteudo do identificador Content-type ,
Caracter recebido quando um Web Browser realiza uma requisição via HTTP ao
servidor.
Descrição
A função HttpRCtType() , quando utilzada em uma thread montada e/ou inicializada
para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo do identificador
Content-type do Header HTTP .
Caso a requisição tenha sido realizada por um client HTTP que não enviou este
identificador no Header HTTP , ou a função seja chamada em um ambiente que não
esteja atendendo à uma requisição Http ( como um JOB , por exemplo) , a função
retornará uma String em branco ("").
Sintaxe
HTTPSEND ( < cHtmlStr > ) --> cHtmlNoSend
Parâmetros
Argumento Tipo Descrição
cHtmlStr corresponde à string a ser enviada ao Browser
cHtmlStr Caracter
solicitante de um processamento .
Retorno
Tipo Descrição
Caso a função obtenha sucesso em enviar a String cHtmlStr para o
Browse solicitante , o retorno será uma string vazia ("").
Caracter Caso não seja possível o envio da string , devido ào recurso de envio
simultâneo estar desabilitado ; ou ocorra uma falha de comunicação, ou a
função HttpSend() seja executada a partir de uam thread que não uma
Working Thread , a função irá retornar a string passada como parâmetro.
Descrição
Através desta função, é possivel retornar uma string Html à um browser durante o
processamento de uma requisição realizada através de um link .APW , utilizando
Working Threads , durante o processamento da mesma.
Observação : Este recurso não funciona em requisições de procesamento
realizadas a partir de um link .apl . É necessário que a requisição seja para um
link .apw , atendida por uma Working Thread.
Sintaxe
HTTPSETPART ( < lHttpSend > ) --> NIL
Parâmetros
Argumento Tipo Descrição
lHttpSend é um valor booleano que habilita o envio parcial
lHttpSend Lógico
( caso .T. ) ou desabilita o envio parcial de HTML ( .F. )
Retorno
Tipo Descrição
(NULO) Esta função sempre retorna NIL
Descrição
Essa função permite desabilitar o envio parcial do HTML, esse é um recurso disponivel
para os programas escritos para APW ( Utilizando Working Thread ).
Esse recurso é util para começarmos a mandar conteúdo ao browser antes de
terminarmos de processar totalmente a página, ele pode aumentar em muito o
desempenho do transmissão da página em caso de páginas grandes.
A Função HTTPSend é utilizada para esse envio temporário.
Sintaxe
HTTPSETPASS ( < cUser > , < cPass > ) --> Nil
Parâmetros
Argumento Tipo Descrição
Cadeia de caracteres que representa o usuário a ser setado
cUser Caracter
uma senha.
Indica a senha informada para autenticação de acordo com
cPass Caracter
o usuário informado.
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Em alguns momentos trabalhamos com protocolo Http autenticado, isso nos indica que
para nos conectar a determinada URL devemos informar um usuário e senha que
tenham permisão para conexão com a URL.
A função HttpSetPass() tem o objetivo de setar uma senha para um determinado
usuário, quando uma requisição HTTP necessita de autenticação.
Informando através de parametro o usuário e a senha que deverá ser usada para
autenticação do usuário infromado.
Sintaxe
HttpCountSession ( ) --> nQtde
Retorno
Tipo Descrição
Numérico Quantidade de usuários com sessões web extended ativas
Descrição
Esta função retorno o número de sessões de usuários ativas no servidor, é util para saber
quantos usuários de Web estão utilizando os servidores neste momento.
Sintaxe
HttpFreeSession ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
Libera a sessão do usuário corrente, todos os dados armazenado nas sessões deste
usuário será perdida.
Função utilizada para efetuar o log off do usuário do site.
Sintaxe
HttpIsAPW ( ) --> bIsAPW
Retorno
Tipo Descrição
Retorna .T. no caso do ambiente em execução ser um APW, .F. em todas
Lógico
as outras situações.
Descrição
Informa se o ambiente web em execução é um APW, caso não seja retorna .F.
Essa função é util na criação de funções genéricas ou na consistência da configuração
do ambiente.
Sintaxe
HttpIsConnected ( ) --> bConnected
Retorno
Tipo Descrição
Lógico Retorna .t. se o browser ainda está conectado aguardando a resposta.
Descrição
Informa se o browser está conectado ainda esperando a resposta do Protheus!
Funcionalidade não disponível quando utilizado o ISAPI para integração com IIS
Sintaxe
ISSECURE ( ) --> lRet
Retorno
Tipo Descrição
(NULO) true caso a conexão é uma conexão SSL, false caso contrário.
Descrição
A função IsSecure() tem como objetivo retornar um valor booleano informando se a
conexão HTTP corrente, é uma conexão segura, ou não.
Uma conexão HTTP segura, é uma conexão que usa criptografia SSL, podemos
observar esse tipo de conexão quando a URL modifica-se de HTTP para HTTPS em um
browser.
Sintaxe
SOAPRACTION ( ) --> cSoapAction
Retorno
Tipo Descrição
cSoapAction corresponde ào conteudo do identificador soapaction ,
Caracter recebido quando um Web Browser realiza uma requisição via HTTP ao
servidor.
Descrição
A função SoapRAction() , quando utilizada em uma thread montada e/ou inicializada
para atender à uma requisição Http ( .apl , .apw ) , retorna o conteúdo string do
identificador soapaction do Header HTTP .
Caso a requisição tenha sido realizada por um client HTTP que não enviou este
identificador no Header HTTP , ou a função seja chamada em um ambiente que não
esteja atendendo à uma requisição Http ( como um JOB , por exemplo) , a função
retornará uma string em branco ("").
FUNÇÃO DE DISCO E ARQUIVO
Sintaxe
ADIR ( [ ] , [ ] , [ ] , [ ] , [ ] , [ ] ) --> nArquivos
Parâmetros
Argumento Tipo Descrição
<cEspecArq> Caracter <cEspecArq> é a especificaçao dos arquivos a serem
incluidos na pesquisa do diretório padrao. É uma
especificaçao de arquivo padrao que pode incluir os
caracteres coringa do tipo * e ?, bem como referência a
diretório e path. Caso nao seja especificado, o padrao
assumido é *.*.
<aNomesArq> é o vetor a ser preenchido com os nomes
de arquivo que correspondem a <cEspecArq>. Cada
<aNomesArq> Array
elemento contém o nome do arquivo e extensao na forma
de uma cadeia de caracteres em letras maiúsculas.
<aTamanhos> é o vetor a ser preenchido com os tamanhos
<aTamanhos> Array dos arquivos correspondentes no vetor <aNomesArq>.
Cada elemento é numérico.
<aDatas> é o vetor a ser preenchido com as datas dos
<aDatas> Array arquivos correspondentes no vetor <aNomesArq>. Cada
elemento é uma data.
<aHoras> é o vetor a ser preenchido com as horas dos
arquivos correspondentes no vetor <aNomesArq>. Cada
<aHoras> Array
elemento preenchido contém uma cadeia de caracteres da
forma: hh:mm:ss.
<aAtributos> é o vetor a ser preenchido com os atributos
dos arquivos correspondentes no vetor <aFilenames>.
Cada elemento é uma cadeia de caracteres. Caso
<aAtributos> Array <aAtributos> seja especificado, os arquivos de diretório,
sistema, e escondidos sao incluidos, assim como os
arquivos normais. Se <aAtributos> nao for especificado,
somente os arquivos normais sao incluidos.
Retorno
Tipo Descrição
ADIR() retorna a quantidade de arquivos que correspondem ao esqueleto
Numérico
de diretório especificado.
Descrição
ADIR() é uma funçao de tratamento de vetor que executa duas operaçoes básicas.
Primeiro, ele retorna a quantidade de arquivos que correspondem à especificaçao de
arquivo. Segundo, preenche uma série de vetores com nomes de arquivos, tamanhos,
datas, horas e atributos.
ADIR() é uma funçao de compatibilidade e portanto desaconselhada. Ele está superado
pela funçao DIRECTORY(), que retorna todas as informaçoes de arquivo em um vetor
multi-dimensional.
OBSERVAÇÃO
Diretórios: Caso o argumento <aAtributos> seja especificado e <cEspecArq> seja
especificado como *.*, os diretórios serao incluidos em <aNomesArq>. No vetor
<aAtributos>, os diretórios sao indicados com um valor atributo de "D." Se ADIR() for
executado dentro de um subdiretório, as duas primeiras entradas do vetor
<aNomesArq> sao "." e "..", os "alias" dos diretórios corrente e raiz. A data e hora da
última atualizaçao sao informadas para diretórios, mas o tamanho de um diretório é
sempre zero.
Exemplos
Este exemplo cria um vetor que conterá os nomes de todos os arquivos (.txt) no
diretório DEFAULT corrente, e os relaciona no console utilizando a funçao AEVAL() :
LOCAL aFiles[ADIR("*.TXT")]
ADIR("*.TXT", aFiles)
AEVAL(aFiles, { |element| conout(element) })
Sintaxe
CPYS2T ( < cOrigem > , < cDestino > , [ lCompacta ] ) --> lSucess
Parâmetros
Argumento Tipo Descrição
Nome(s) dos arquivos a serem copiados, aceita apenas
cOrigem Caracter arquivos
no servidor, WildCards ( * e ? ) são aceitos normalmente.
cDestino Caracter Diretório com o destino dos arquivos no Client ( Remote )
Indica se a cópia deve ser feita compactando o arquivo
lCompacta Lógico
antes do envio.
Retorno
Tipo Descrição
lSucess retorna .T. caso o arquivo seja copiado com sucesso , ou .F. em
Lógico
caso de falha na cópia.
Descrição
Copia um arquivo, do servidor para o cliente ( Remote ). .Caso a compactação seja
habilitada (lCompacta ), os dados serão transmitidos de maneira compactada e
descompactados antes do uso.
Exemplo :
CpyS2T( "\BKP\[Link]", "C:\TEMP", .T. ) // Copia arquivos do
servidor para o remote local, compactando antes de transmitir
CpyS2T( "\BKP\[Link]", "C:\TEMP", .F. ) // Copia arquivos do
servidor para o remote local, sem compactar antes de transmitir
Sintaxe
CPYT2S ( < cOrigem > , < cDestino > , [ lCompacta ] ) --> lSucess
Parâmetros
Argumento Tipo Descrição
Nomes dos arquivos a serem copiados, aceita apenas
cOrigem Caracter arquivos locais ( Cliente ), WildCards ( * e ? ) são aceitos
normalmente.
cDestino Caracter Diretório com o destino dos arquivos no Servidor
lCompacta indica se o(s) arquivo(s) deve(m) ser enviados
lCompacta Lógico
em formato compactado.
Retorno
Tipo Descrição
lSucess indica , caso verdadeiro , que a cópia foi realizada com sucesso.
Lógico
Caso retorne .F. , houve erro na copia do arquivo.
Descrição
Copia um arquivo, do cliente ( Remote ) para o servidor,. Caso a compactação seja
habilitada ( lCompacta ), os dados serão transmitidos de maneira compacta e
descompactados antes do uso.
Exemplo
CpyT2S( "C:\TEMP\[Link]","\BKP", .T. ) // Copia arquivos do
cliente( remote ) para o Servidor compactando antes de transmitir
CpyT2S( "C:\TEMP\[Link]", "\BKP" ) // Copia arquivos do
cliente( remote ) para o Servidor sem compactar.
Sintaxe
CURDIR ( [ cNovoPath ] ) --> cPathAtual
Parâmetros
Argumento Tipo Descrição
Caminho relativo , com o novo diretório que será ajustado
cNovoPath Caracter
como corrente.
Retorno
Tipo Descrição
Caracter Diretório corrente, sem a primeira barra.
Descrição
Retorna o diretório corrente do servidor. O caminho retornado é sempre relativo ào
RootPath definido na configuração do Environment no .INI do Protheus Server.
Inicialmente , o diretório atual da aplicação é o constante na chave StartPath , também
definido na configuração do Environment no .INI do Protheus Server.
Caso seja passado o parâmetro cNovoPath , este path é assumido como sendo o Path
atual. Caso o path recebido como parÂmetro não exista , seja inválido , ou seja um path
absoluto ( iniciado com uma letra de drive ou caimnho de rede ) , a função não irá setar
o novo path , mantendo o atual .
No exemplo abaixo , conferimos o path atual e tentamos setar um novo path atual ,
verificando se a operação foi realizada com sucesso.
cOldDir := curdir()
cNewDir := '\webadv\xis'
curdir(cNewDir) // Troca o path
If cNewDir <> '\'+curdir() // E verifica se trocou mesmo
conout('Falha ao Trocar de Path de '+cOldDir + ' para '+cNewDir)
Else
conout('Path de '+cOldDir + ' trocado para '+cNewDir+' com
sucesso.')
Endif
Sintaxe
DIRECTORY ( < cDirSpec > , [ ] ) --> aDiretorio
Parâmetros
Argumento Tipo Descrição
<cDirSpec> especifica o drive, diretório e arquivo para a
pesquisa no diretório. Caracteres do tipo coringa sao
permitidos na especificaçao de arquivos. Caso <cDirSpec>
cDirSpec Caracter seja omitido, o valor padrao é *.*.
O caminho especificado pode estar na estação (remote) ,
ou no servidor , obedecendo às definicões de Path
Absoluto / Relativo de acesso
<cAtributos> especifica que arquivos com atributos
especiais devem ser incluidos na informaçao retornada.
<cAtributos> Caracter <cAtributos> consiste em uma cadeia de caracteres que
contém um ou mais dos seguintes caracteres, contidos na
tabela adicional A , especificada abaixo:
Retorno
Tipo Descrição
DIRECTORY() retorna um vetor de sub-vetores, sendo que cada sub-
Array vetor contém informaçoes sobre cada arquivo que atenda a
<cDirSpec>.Veja maiores detalhes na Tabela B, abaixo discriminada.
Descrição
DIRECTORY() é uma funçao de tratamento de ambiente que retorna informaçoes a
respeito dos arquivos no diretório corrente ou especificado. É semelhante a ADIR(),
porém retorna um único vetor ao invés de adicionar valores a uma série de vetores
existentes passados por referência.
DIRECTORY() pode ser utilizada para realizar operaçoes em conjuntos de arquivos.
Em combinaçao com AEVAL(), você pode definir um bloco que pode ser aplicado a
todos os arquivos que atendam a <cDirSpec> especificada.
Para tornar as referências aos vários elementos de cada sub-vetor de arquivo mais
legíveis, é fornecido o arquivo header [Link], que contém os #defines para os
subarray subscripts.
TABELA A: Atributos de DIRECTORY()
Atributo Significado
H Incluir arquivos ocultos
S Incluir arquivos de sistema
D Incluir diretórios
V Procura pelo volume DOS e exclui outros arquivos
Arquivos normais sao sempre incluidos na pesquisa, a nao ser que V seja especificado.
TABELA B: Estrutura dos Subvetores de DIRECTORY()
Posiçao Metasímbolo [Link]
1 cNome F_NAME
2 cTamanho F_SIZE
3 dData F_DATE
4 cHora F_TIME
5 cAtributos F_ATT
Exemplos
Através do exemplo abaixo , obtemos no array aDirectory todos os diretórios no
ambiente do servidor a partir do path atual.
#INCLUDE "[Link]"
aDirectory := DIRECTORY("*.*","D")
AEVAL( aDirectory, {|aFile| CONOUT(aFile[F_NAME])} )
Sintaxe
DIRREMOVE ( < cDiretorio > ) --> lSucesso
Parâmetros
Argumento Tipo Descrição
cDiretorio Caracter Nome do diretório a ser removido.
Retorno
Tipo Descrição
lSucesso será .T. caso o diretório tenha sido eliminado , ou .F. caso não
seja possível excluir o diretório. Quando a função DirRemove
Lógico
retornar .F. , é possível obter mais detalhes da ocorrência recuperando o
código do Erro através da função FError().
Descrição
DIRREMOVE() elimina um diretório especifico. Caso especifiquemos um path sem a
unidade de disco , ele será considerado no ambiente do Servidor , a partir do RootPath
do ambiente ( caso o path começe com \ ) , ou a partir do diretório corrente ( caso o path
não seja iniciado com \ ) . E , quando especificado um path absoluto ( com unidade de
disco preenchida ) , a função será executada na estação onde está sendo executado o
Protheus Remote. Quando executamos a função DirRemove() em JOB ( processo
isolado no Server , sem interface ) , não é possível especificar um Path absoluto de
disco. Caso isto seja realizado , a função retornará .F. e FError() retornará -1 ( Syntax
Error ) .
Note que é necessário ter direitos suficientes para remover um diretório, e o
diretório a ser eliminado precisa estar vazio, sem subdiretórios ou arquivos dentro
do mesmo.
Exemplos
No exemplo abaixo , executado a partir do Protheus Remoite , tentamos excluir a pasta
c:\TmpFiles , verificando se houve sucesso nesta operação.
cDelPath := 'c:\TmpFiles'
lRemoveOk := DIRREMOVE(cDelPath)
IF !lRemoveOk
MsgStop('Falha ao remover a pasta '+cDelPath+' ( File Error
'+str(Fewrror(),4)+' ) ')
Else
MsgStop('Pasta '+cDelPath+' removida com sucesso.')
Endif
Sintaxe
DISKSPACE ( [ nDrive ] ) --> nBytesFree
Parâmetros
Argumento Tipo Descrição
Número do drive, onde 0 é o espaço na unidade de disco
nDrive Numérico corrente, e 1 é o drive A: do cliente, 2 é o drive B: do
cliente, etc.
Retorno
Tipo Descrição
Numérico Número de bytes disponíveis no disco informado como parâmetro.
Descrição
DISKSPACE() é uma função de ambiente que determina quantos bytes estão
disponíveis em uma determinada uinidade de disco. Esta função obtém a informação
sempre relativa à estação onde está sendo executado o Protheus Remote. Através do
parâmetro nDRive , selecionamos qual a unidade de disco que desejamos obter a
informação do espaço livre , onde:
0 : Unidade de disco atual da estação (DEFAULT).
1 : Drive A: da estação remota.
2 : Drive B: da estação remota.
3 : Drive C: da estação remota.
4 : Drive D: da estação remota ... e assim por diante.
Caso a função DiskSpace seja executada através de um Job ( processo isolado no
Servidor , sem interface Remota ) , ou seja passado um argumento de unidade de
disco inexistente ou indisponível , a função DISKSPACE() retornará -1
Exemplo da função DISKSPACE
Revisão: 01/05/2003
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
No exemplo abaixo , obtemos os espaços em disco da unidade de disco da estação local
e do drive A: da estação local, verificando se houve sucesso na operação.
nBytesLocal := DISKSPACE( ) // Retorna o espaço disponivel na unidade
de disco local ( remote ).
IF nBytesLocal < 1048576
MsgStop('Unidade de Disco local possui menos de 1 Mb livre.')
Else
MsgStop('Unidade de disco local possui '+str(nBytes_A,12)+' bytes
livres.')
Endif
nBytes_A := DISKSPACE( 1 ) // Retorna o espaço disponivel no drive A:
local ( remote ).
If nBytes_A == -1
MsgStop('Unidade A: não está disponível ou não há disco no Drive')
ElseIf nBytes_A < 8192
MsgStop('Não há espaço disponível no disco. Substitua o disco na
Unidade A:')
Else
MsgStop('Unidade A: Verificada . '+str(nBytes_A,12)+' bytes
livres.')
Endif
Sintaxe
FCLOSE ( < nHandle > ) --> lError
Parâmetros
Argumento Tipo Descrição
<nHandle> é o handle do arquivo obtido previamente
nHandle Numérico
através de FOPEN() ou FCREATE().
Retorno
Tipo Descrição
FCLOSE() retorna falso (.F.) se ocorre um erro enquanto os buffers estao
Lógico
sendo escritos; do contrário, retorna verdadeiro (.T.).
Descrição
FCLOSE() é uma funçao de tratamento de arquivos de baixo nível utilizada para fechar
arquivos binários e forçar que os respectivos buffers do DOS sejam escritos no disco.
Caso a operaçao falhe, FCLOSE() retorna falso (.F.). FERROR() pode entao ser usado
para determinar a razao exata da falha. Por exemplo, ao tentar-se usar FCLOSE() com
um handle (tratamento dado ao arquivo pelo sistema operacional) inválido retorna falso
(.F.) e FERROR() retorna erro 6 do DOS, invalid handle. Consulte FERROR() para
obter uma lista completa dos códigos de erro.
Aviso
Esta funçao permite acesso de baixo nível aos arquivos e dispositivos do DOS. Ela deve
ser utilizada com extremo cuidado e exige que se conheça a fundo o sistema operacional
utilizado.
Exemplos
O exemplo a seguir utiliza FCLOSE() para fechar um arquivo binário recém criado e
exibe uma mensagem de erro caso o fechamento falhe:
#include "[Link]"
nHandle := FCREATE("Testfile", FC_NORMAL)
If !FCLOSE(nHandle)
conout( "Erro ao fechar arquivo, erro numero: ", FERROR() )
EndIf
Sintaxe
FCREATE ( < cArquivo > , [ nAtributo ] ) --> nHandle
Parâmetros
Argumento Tipo Descrição
Nome do arquivo a ser criado , podendo ser especificado
um path absoluto ou relativo , para criar arquivos no
cArquivo Caracter
ambiente local ( Remote ) ou no Servidor ,
respectivamente .
Atributos do arquivo a ser criado (Vide Tabela de
nAtributo Numérico atributos abaixo). Caso não especificado , o DEFAULT é
FC_NORMAL.
Retorno
Tipo Descrição
A função retornará o Handle do arquivo para ser usado nas demais
funções de manutenção de arquivo. O Handle será maior ou igual a zero.
Numérico Caso não seja possível criar o arquivo , a função retornará o handle -1 , e
será possível obter maiores detalhes da ocorrencia através da função
FERror()
Descrição
FCREATE() é uma função de baixo-nível que permite a manipulação direta dos
arquivos textos como binários. Ao ser executada FCREATE() cria um arquivo ou
elimina o seu conteúdo, e retorna o handle (manipulador) do arquivo, para ser usado nas
demais funções de manutenção de arquivo. Após ser utilizado , o Arquivo deve ser
fechado através da função FCLOSE().
Na tabela abaixo , estão descritos os atributos para criação do arquivo , definidos no
arquivo header [Link]
Constante Valor Descrição
FC_NORMAL 0 Criação normal do Arquivo (default/padrão).
FC_READONLY 1 Cria o arquivo protegido para gravação.
FC_HIDDEN 2 Cria o arquivo como oculto.
FC_SYSTEM 4 Cria o arquivo como sistema.
Caso desejemos especificar mais de um atributo , basta somá-los . Por exemplo , para
criar um arquivo protegiro contra gravação e escondido , passamos como atributo
FC_READONLY + FC_HIDDEN .
ATENÇÃO : Caso o arquivo já exista , o conteúdo do mesmo será ELIMINADO ,
e seu tamanho será truncado para 0 ( ZERO ) bytes.
Sintaxe
FERASE ( < cArquivo > ) --> nStatus
Parâmetros
Argumento Tipo Descrição
Nome do arquivo a ser apagado . Pode ser especificado um
cArquivo Caracter path absoluto ou relativo , para apagar arquivos na estação
local ( Remote ) ou no Servidor , respéctivamente .
Retorno
Tipo Descrição
A função retornará 0 caso o arquivop seja apagado com sucesso , e -1 caso
Numérico não seja possível apagar o arquivo. Caso a função retorne -1 , é possível
obter mauires detalhes da ocorrência através da função fError()
Descrição
Através da função Ferase , é possível apagar um arquivo no disco . O Arquivo pode
estar no Servidor ou na estação local (Remote).
O Arquivo para ser apagado deve estar fechado. Não é permitido a utilização de
caracteres coringa (wildcards).
Exemplos
// Este exemplo apaga todos os arquivos .BAK do diretório corrente no Servidor
#include '[Link]'
aEval(Directory("*.BAK"), { |aFile| FERASE(aFile[F_NAME]) })
// Este exemplo apaga um arquivo no cliente ( Remote ) , informando o status da
operação
IF FERASE("C:\[Link]") == -1
MsgStop('Falha na deleção do Arquivo ( FError'+str(ferror(),4)+
')')
Else
MsgStop('Arquivo deletado com sucesso.')
ENDIF
Sintaxe
FILE ( < cArquivo > ) --> lExiste
Parâmetros
Argumento Tipo Descrição
Nome do arquivo , podendo ser especificado um path
(caminho ) . Caminhos locais (Remote) ou caminhos de
cArquivo Caracter
servidor são aceitos , bem como wildcards ( Caracteres * e
?)
Retorno
Tipo Descrição
O retorno será .T. caso o arquivo especificado exista. Caso o mesmo não
Lógico
exista no path especificado , a função retorna .F.
Descrição
Verifica se existe um arquivo ou um padrão de arquivos, no diretório. Pordemos
especificar caminhos absolutos ( arquivos na estação - Remote ) ou relativos ( A partir
do RootPath do Protheus Server) . Os caracteres * e ? ( wildcards). são aceitos.
Exemplos
FILE("[Link]") // Verifica no diretório corrente do servidor se
existe o arquivo [Link]
FILE("\SIGAADV\[Link]") // Verifica no diretório Sigaadv do
servidor se existe o arquivo [Link]
FILE("C:\TEMP\[Link]") // // Verifica no diretório Temp do cliente
(Remote) se existe o arquivo [Link]
Observação : Caso a função File() seja executada em Job ( programa sem interface
remota ) , sendo passado um caminho absoluto de arquivo ( exemplo c:\[Link]) , a
função retornará .F. e FERROR() retornará -1 )
Sintaxe
FOPEN ( < cArq > , [ nModo ] ) --> nRet
Parâmetros
Argumento Tipo Descrição
Nome do arquivo a ser aberto que inclui o path caso haja
cArq Caracter
um.
Modo de acesso DOS solicitado que indica como o
arquivo aberto deve ser acessado. O acesso é de uma das
categorias relacionadas na tabela A e as restrições de
compartilhamento relacionada na Tabela B. O modo
nModo Numérico
padrao é zero, somente para leitura, com
compartilhamento por Compatibilidade. Ao definirmos o
modo de acesso , devemos somar um elemento da Tabela
A com um elemento da Tabela B.
Retorno
Tipo Descrição
FOPEN() retorna o handle de arquivo aberto na faixa de zero a 65.535.
Numérico
Caso ocorra um erro, FOPEN() retorna -1.
Descrição
Abre um arquivo binário.
FOPEN() é uma funçao de tratamento de arquivo de baixo nível que abre um arquivo
binário existente para que este possa ser lido e escrito, dependendo do argumento
<nModo>. Toda vez que houver um erro na abertura do arquivo, FERROR() pode ser
usado para retornar o código de erro do Sistema Operacional. Por exemplo, caso o
arquivo nao exista, FOPEN() retorna -1 e FERROR() retorna 2 para indicar que o
arquivo nao foi encontrado. Veja FERROR() para uma lista completa dos códigos de
erro.
Caso o arquivo especificado seja aberto, o valor retornado é o handle (manipulador) do
Sistema Operacional para o arquivo. Este valor é semelhante a um alias no sistema de
banco de dados, e ele é exigido para identificar o arquivo aberto para as outras funçoes
de tratamento de arquivo. Portanto, é importante sempre atribuir o valor que foi
retornado a uma variável para uso posterior, como mostra o exemplo desta função.
Aviso
Esta funçao permite acesso de baixo nível a arquivos e dispositivos. Ela deve ser
utilizada com extremo cuidado e exige que se conheça a fundo o sistema operacional
utilizado.
Notas
FOPEN procura o arquivo no diretório corrente e nos diretórios configurados na
variável de pesquisa do Sistema Operacional, a nao ser que um path seja
declarado explicitamente como parte do argumento <cArq>.
Por serem executadas em um ambiente cliente-servidor, as funções de
tratamento de arquivos podem trabalhar em arquivos localizados no cliente
(estação) ou no servidor. O ADVPL identifica o local onde o arquivo será
manipulado através da existência ou não da letra do drive no nome do arquivo
passado em <cArq>. Ou seja, se o arquivo for especificado com a letra do drive,
será aberto na estação. Caso contrário, será aberto no servidor com o diretório
configurado como rootpath sendo o diretório raíz para localização do arquivo.
Tabela A: Modos de Acesso a Arquivos Binários
Modo Constante ([Link]) Operação
0 FO_READ Aberto para leitura (padrão assumido)
1 FO_WRITE Aberto para gravação
2 FO_READWRITE Aberto para leitura e gravação
Tabela B: Modos de Acesso de Compartilhamento a Arquivos Binários
Constante
Modo Operação
([Link])
0 FO_COMPAT Modo de Compatibilidade (Default)
16 FO_EXCLUSIVE Acesso total exclusivo
Acesso bloqueando a gravação de outros processos ao
32 FO_DENYWRITE
arquivo.
48 FO_DENYREAD Acesso bloqueando a leitura de outros processos ao arquivo.
Acesso compartilhado. Permite a leitura e gravação por
64 FO_DENYNONE
outros processos ao arquivo..
64 FO_SHARED Igual à FO_DENYNONE
No exemplo abaixo , tentamos abrir o arquivo [Link] para escrita e gravação
compartilhada.
#include '[Link]'
...
nH := fopen('\sigaadv\[Link]' , FO_READWRITE + FO_SHARED )
If nH == -1
MsgStop('Erro de abertura : FERROR '+str(ferror(),4))
Else
MsgStop('Arquivo aberto com sucesso.')
...
fclose(nH)
Endif
...
Sintaxe
FREAD ( < nHanvle > , < cBuffer > , < nQtdBytes > ) --> nBytesLidos
Parâmetros
Argumento Tipo Descrição
É o manipulador (Handle) retornado pelas funções
FOPEN(),
nHanvle Numérico
FCREATE(), FOPENPORT(), que faz referência ao
arquivo a ser lido.
É o nome de uma variável do tipo String , a ser utilizada
como buffer de leitura , onde os dados lidos
deverão ser armazenados. O tamanho desta variável deve
ser maior ou igual ao tamanho informado em nQtdBytes.
cBuffer Caracter
Esta variável deve ser sempre passada por referência. ( @
antes do nome da variável ), caso contrário os dados lidos
não serão retornados.
Define a quantidade de Bytes que devem ser lidas do
nQtdBytes Numérico
arquivo a partor posicionamento do ponteiro atual.
Retorno
Tipo Descrição
Quantidades de bytes lidos. Caso a quantidade seja menor que a
Numérico solicitada, isto indica erro de leitura ou final de arquivo, Verifique a
função FERROR() para maiores detalhes.
Descrição
FREAD() lê os dados a partir um arquivo aberto, através de FOPEN(), FCREATE()
e/ou FOPENPORT(), e armazena os dados lidos por referência no buffer informado.
FREAD() lerá até o número de bytes informado em nQtdBytes; caso aconteça algum
erro ou o arquivo chegue ao final, FREAD() retornará um número menor que o
especificado em nQtdBytes. FREAD() lê normalmente caracteres de controle (ASC 128,
ASC 0, etc.).
A variável String a ser utiilzada como buffer de leitura deve ser sempre pré-alocado e
passado como referência. Caso contrário, os dados não poderão ser retornados.
FREAD() lê a partir da posição atual do ponteiro atual do arquivo , que pode ser
ajustado ou modificado pelas funções FSEEK() , FWRITE() ou FREADSTR().
Sintaxe
FREADSTR ( < nHandle > , < nQtdBytes > ) --> cLidos
Parâmetros
Argumento Tipo Descrição
É o manipulador retornado pelas funções FOPEN(),
nHandle Numérico
FCREATE(), FOPENPORT().
nQtdBytes Numérico Número máximo de bytes que devem ser lidos.
Retorno
Tipo Descrição
Retorna uma string contendo os caracteres
Caracter
lidos.
Descrição
Lê caracteres de um arquivo binário.
FREADSTR() lê de um arquivo aberto, através de FOPEN(), FCREATE(),
FOPENPORT().
FREADSTR() lerá até o número de bytes informado em nQtdBytes ou até encontrar um
CHR(0). Caso aconteça algum erro ou o arquivo chegue ao final, FREADSTR()
retornará uma string menor do que nQdBytes e colocará o erro em FERROR().
FREADSTR() lê a partir da posição atual do ponteiro, que pode ser ajustado pelo
FSEEK(), FWRITE( ) ou FREAD().
Sintaxe
FRENAME ( < cOldFile > , < cNewFile > ) --> nStatus
Parâmetros
Argumento Tipo Descrição
Nome do arquivo será renomeado, aceita caminhos do
servidor e caminhos do cliente. Caso não seja especificado
cOldFile Caracter
nenhuma unidade de disco e path, é considerado o path
atual no servidor.
Novo nome do arquivo, aceita também caminho do
cNewFile Caracter
servidor, e caminho do cliente.
Retorno
Tipo Descrição
Se o status retornado for -1 , ocorreu algum erro na mudança de nome :
Verifique se os dois caminhos estão no mesmo ambiente, verifique a
Numérico existência do arquivo de origem, se ele não está em uso no momento por
outro processo , e verifique se o nome do arquivo de destino já não existe
no path de destino especificado.
Descrição
Através da função FRENAME() é possível renomear um arquivo para outro nome, tanto
no servidor como na estação. Ao renomear um arquivo não esqueça que esta arquivo
deverá
estar fechado ( isto é , não pode estar em uso por nenhum outro processo ou estação).
Caso o arquivo esteja aberto por outro processo , a operação de renomear o arquivo não
é possível. A função fRename() não aceita wildcards ( * e/ou ? ).
Vale lembrar que não é possível renomear um arquivo especificando nos parâmetros
simultaneamente um caminho de servidor e um de estação remota, bem como
especificar dois arquivos remotos e executar a função fername() através de um JOB.
Caso isto ocorra, a função retornará -1 , e fError() retornará também -1.
Importante : Quando especificamos um path diferente nos arquivos de origem e
destino , a função fRename() realiza a funcionalidade de MOVER o arquivo para o
Path especificado.
Exemplos
// Renomeando um arquivo no Client de [Link] para [Link] , na
pasta c:\Temp
nStatus1 := frename('c:\Temp\[Link]' , 'c:\Temp\[Link]' )
IF nStatus1 == -1
MsgStop('Falha na operação 1 : FError '+str(ferror(),4))
Endif
// Renomeando um arquivo no Server, na pasta sigaadv , de [Link]
para [Link]
nStatus2 := frename('\sigaadv\[Link]' , '\sigaadv\[Link]' )
IF nStatus2 == -1
MsgStop('Falha na operação 2 : FError '+str(ferror(),4))
Endif
// Movendo um arquivo no client , da pasta Raiz para a pasta c:\Temp ,
alterando também o nome do arquivo.
nStatus3 := frename('c:\[Link]','c:\Temp\[Link]')
IF nStatus3 == -1
MsgStop('Falha na operação 3 : FError '+str(ferror(),4))
Endif
Sintaxe
FSEEK ( < nHandle > , [ nOffSet ] , [ nOrigem ] ) --> nPos
Parâmetros
Argumento Tipo Descrição
Manipulador obtido através das funções
nHandle Numérico
FCREATE,FOPEN.
nOffSet corresponde ao número de bytes no ponteiro de
posicionamento do arquivo a ser movido. Pode ser um
nOffSet Numérico
numero positivo , zero ou negativo, a ser considerado a
partir do parâmetro passado em nOrigem.
Indica a partir de qual posição do arquivo, o nOffset será
nOrigem Numérico
considerado.
Retorno
Tipo Descrição
FSEEK() retorna a nova posiçao do ponteiro de arquivo com relaçao ao
início do arquivo (posiçao 0) na forma de um valor numérico inteiro. Este
Numérico
valor nao leva em conta a posiçao original do ponteiro de arquivos antes
da execução da função FSEEK().
Descrição
FSEEK() posiciona o ponteiro do arquivo para as próximas operações de leitura ou
gravação. As movimentações de ponteiros são relativas à nOrigem que pode ter os
seguintes valores, definidos em [Link]:
Tabela A: Origem a ser considerada para a movimentação do ponteiro de
posicionamento do Arquivo.
Origem Constante Operação
0 FS_SET Ajusta a partir do inicio do arquivo. (Default)
1 FS_RELATIVE Ajuste relativo a posição atual do arquivo.
2 FS_END Ajuste a partir do final do arquivo.
Sintaxe
FT_FEOF ( ) --> lRet
Retorno
Tipo Descrição
Retorna true caso o ponteiro do arquivo tenha chegado ao final, false caso
Lógico
contrário.
Descrição
Indica se o ponteiro esta posicionado no fim do arquivo texto.
A função FT_FEof() retorna verdadeiro (.t.) se o arquivo texto aberto pela FT_FUSE
estiver posicionado no final do arquivo, similar à função Eof (), usada em tabelas de
dados.
Exemplos
O exemplo abaixo realiza a leitura de um arquvio texto, utilizando-se das funções
FT_F*
FT_FUse('[Link]') // Abre o arquivo
conout("Linhas no arquivo ["+str(ft_flastrec(),6)+"]")
FT_FGOTOP()
While !FT_FEof()
conout("Ponteiro ["+str(FT_FRECNO(),6)+"] Linha ["+FT_FReadln()
+"]")
FT_FSkip()
Enddo
FT_FUse() // Fecha o arquivo
Sintaxe
FT_FGOTO ( < nPos > ) --> NIL
Parâmetros
Argumento Tipo Descrição
Indica a posição que será colocado o ponteiro para leitura
nPos Numérico
dos dados no arquivo.
Retorno
Tipo Descrição
(NULO) Esta função sempre retorna NIL
Descrição
A função tem como objetivo mover o ponteiro, que indica a leitura do arquivo texto,
para a posição absoluta especificada pelo argumento <nPos>.
Sintaxe
FT_FGOTOP ( ) --> NIL
Retorno
Tipo Descrição
(NULO) Esta função sempre retorna NIL
Descrição
A função FT_FGoTop tem como objetivo posicionar o arquivo texto aberto pela
FT_FUse na
posição inicial do arquivo.
Entende-se como posição inicial do arquivo, o primeiro caracter da primeira linha do
arquivo texto.
Sintaxe
FT_FLASTREC ( ) --> nRet
Retorno
Tipo Descrição
Retorna a quantidade de linhas existentes no arquivo. Caso o arquivo
Numérico
esteja vazio, ou não exista arquivo aberto, a função retornará 0 (zero)
Descrição
A função tem o objetivo de retornar o número de linhas existentes do arquivo texto.
A função FT_FLastRec retorna o número total de linhas do arquivo texto aberto pela
FT_FUse. As linhas são delimitadas pela sequência de caracteres CRLF ou LF (*).
(*) Verifique maiores informações sobre formato do arquivo e tamanho máximo da
linha de texto na função FT_FREADLN()
Exemplos
O exemplo abaixo realiza a leitura de um arquvio texto, utilizando-se das funções
FT_F*
FT_FUse('[Link]') // Abre o arquivo
conout("Linhas no arquivo ["+str(ft_flastrec(),6)+"]")
FT_FGOTOP()
While !FT_FEof()
conout("Ponteiro ["+str(FT_FRECNO(),6)+"] Linha ["+FT_FReadln()
+"]")
FT_FSkip()
Enddo
FT_FUse() // Fecha o arquivo
Sintaxe
FT_FREADLN ( ) --> cRet
Retorno
Tipo Descrição
Retorna a linha inteira na qual está posicionado o ponteiro para leitura de
Caracter
dados.
Descrição
A função tem como objetivo ler uma linha do arquivo texto.
A função FT_FREADLN() retorna uma linha de texto do arquivo aberto pela FT_FUse.
As linhas são delimitadas pela sequência de caracteres CRLF ( chr(13) + chr(10) ) , ou
apenas LF ( chr(10 ), e o tamanho máximo de cada linha é 1022 bytes
Observações
A utilização desta função não altera a posição do ponteiro para leitura dos
dados, o ponteiro do arquivo não é movido. A movimentação do ponteiro é
realizada através da função FT_FSKIP()
O limite de 1022 bytes por linha inclui os caracteres delimitadores de final de
linha. Deste modo, quando utilizados os separadores CRLF, isto nos deixa 1020
bytes de texto, e utilizando LF, 1021 bytes. A tentativa de leitura de arquivos
com linhas de texto maiores do que os valores especificados acima resultará na
leiitura dos 1023 primeiros bytes da linha, e incorreta identificação das quebras
de linha posteriores.
As funções FT_F* foram projetadas para ler arquivos com conteúdo texto
apenas. A utilização das mesmas em arquivos binários pode gerar
comportamentos inesperados na movimentação do ponteiro de leitura do
arquivo, e incorretas identificações nos separadores de final de linha.
Release
Quando utilizado um Protheus Server, com build superior a 7.00.050713P, a função
FT_FREADLN() também é capaz de ler arquivos texto / ASCII, que utilizam também o
caractere LF ( chr(10) ) como separador de linha.
Exemplos
Sintaxe
FT_FRECNO ( ) --> cRet
Retorno
Tipo Descrição
Caracter Retorna a posição corrente do ponteiro do arquivo texto.
Descrição
A função tem o objetivo de retornar a posição do ponteiro do arquivo texto.
A função FT_FRecno retorna a posição corrente do ponteiro do arquivo texto aberto
pela FT_FUse.
Sintaxe
FT_FSKIP ( [ nLinhas ] ) --> NIL
Parâmetros
Argumento Tipo Descrição
nLinhas corresponde ao número de linhas do arquivo
nLinhas Numérico
TXT ref. movimentação do ponteiro de leitura do arquivo.
Retorno
Tipo Descrição
(NULO) Esta função sempre retorna NIL.
Descrição
Move o ponteiro do arquivo texto para uma nova posição.
A função FT_FSkip move o ponteiro do arquivo texto aberto pela FT_FUse para a
próxima linha, similar ao DbSkip usado para tabelas de dados.
Sintaxe
FT_FUSE ( [ cTXTFile ] ) --> nHnd
Parâmetros
Argumento Tipo Descrição
Corresponde ào nome do arquivo TXT a ser aberto. Caso o
cTXTFile Caracter nome não seja passado, e já exisa um arquivo aberto. o
mesmo é fechado.
Retorno
Tipo Descrição
A função retorna o Handle de controle do arquivo. Em caso de falha de
Numérico
abertura, a função retornará -1
Descrição
Abre ou fecha um arquivo texto para uso das funcoes FT_F*
As funções FT_F* são usadas para para ler arquivos texto, onde as linhas são
delimitadas pela sequência de caracteres CRLF ou LF (*) e o tamanho máximo de cada
linha é 1022 bytes.. O arquivo é aberto em uma área de trabalho, similar à usada pelas
tabelas de dados.
(*) Maiores detalhes sobre a especificação do arquivo na função FT_FREADLN()
Sintaxe
FWRITE ( < nHandle > , < cBuffer > , [ nQtdBytes ] ) --> nBytesEscritos
Parâmetros
Argumento Tipo Descrição
É o manipulador de arquivo ou device retornado pelas
nHandle Numérico
funções FOPEN(), FCREATE(), ou FOPENPORT().
<cBuffer> é a cadeia de caracteres a ser escrita no arquivo
especificado. O tamanho desta variável deve ser maior ou
cBuffer Caracter
igual ao tamanho informado em nQtdBytes (caso
seja informado o tamanho).
nQtdBytes Numérico <nQtdBytes> indica a quantidade de bytes a serem
escritos a partir da posiçao corrente do ponteiro de
arquivos. Caso seja omitido, todo o conteúdo de
<cBuffer> é escrito.
Retorno
Tipo Descrição
FWRITE() retorna a quantidade de bytes escritos na forma de um valor
numérico inteiro. Caso o valor retornado seja igual a <nQtdBytes>, a
operaçao foi bem sucedida. Caso o valor de retorno seja menor que
Numérico
<nBytes> ou zero, ou o disco está cheio ou ocorreu outro erro. Neste
caso , utilize a função FERROR() para obter maiores detalhes da
ocorrência.
Descrição
Você pode escrever todo ou parte do conteúdo do buffer , limitando a quantidade de
Bytes através do parâmetro nQtdBytes. A escrita começa a partir da posição corrente do
ponteiro de arquivos, e a função FWRITE retornará a quantidade real de bytes escritos.
Através das funções FOPEN(), FCREATE(), ou FOPENPORT(), podemos abrir ou
criar um arquivo ou abrir uma porta de comunicação , para o qual serão gravados ou
enviados os dados do buffer informado. Por tratar-se de uma função de manipulação de
conteúdo binário , são suportados na String cBuffer todos os caracteres da tabela
ASCII , inclusive caracteres de controle ( ASC 0 , ASC 12 , ASC 128 , etc... ).
Caso aconteça alguma falha na gravação , a função retornará um número menor que o
nQtdBytes. Neste caso , a função FERROR() pode ser utilizada para determinar o erro
específico ocorrido. A gravação no arquivo é realizada a partir da posição atual do
ponteiro , que pode ser ajustado através das funções FSEEK() , FREAD() ou
FREADSTR().
Exemplo da função FWRITE
Revisão: 27/05/2003
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Este exemplo realiza uma cópia de um arquivo Texto chamado [Link] , para
um arquivo chamado [Link] , no ambiente do Protheus Server.
#INCLUDE "[Link]"
#DEFINE F_BLOCK 1024 // Define o bloco de Bytes a serem lidos
/ gravados por vez
User Function TestCopy()
Local cBuffer := SPACE(F_BLOCK)
Local nHOrigem , nHDestino
Local nBytesLidos , nBytesFalta , nTamArquivo
Local nBytesLer , nBytesSalvo
Local lCopiaOk := .T.
// Abre o arquivo de Origem
nHOrigem := FOPEN("[Link]", FO_READ)
// Testa a abertura do Arquivo
If nHOrigem == -1
MsgStop('Erro ao abrir origem. Ferror =
'+str(ferror(),4),'Erro')
Return .F.
Endif
// Determina o tamanho do arquivo de origem
nTamArquivo := Fseek(nHOrigem,0,2)
// Move o ponteiro do arquivo de origem para o inicio do arquivo
Fseek(nHOrigem,0)
// Cria o arquivo de destino
nHDestino := FCREATE("[Link]", FC_NORMAL)
// Testa a criação do arquivo de destino
If nHDestino == -1
MsgStop('Erro ao criar destino. Ferror =
'+str(ferror(),4),'Erro')
FCLOSE(nHOrigem) // Fecha o arquivo de Origem
Return .F.
Endif
// Define que a quantidade que falta copiar é o próprio tamanho do
Arquivo
nBytesFalta := nTamArquivo
// Enquanto houver dados a serem copiados
While nBytesFalta > 0
// Determina quantidade de dados a serem lidos
nBytesLer := Min(nBytesFalta , F_BLOCK )
// lê os dados do Arquivo
nBytesLidos := FREAD(nHOrigem, @cBuffer, nBytesLer )
// Determina se não houve falha na leitura
If nBytesLidos < nBytesLer
MsgStop( "Erro de Leitura da Origem. "+;
Str(nBytesLer,8,2)+" bytes a
LER."+;
Str(nBytesLidos,8,2)+" bytes
Lidos."+;
"Ferror =
"+str(ferror(),4),'Erro')
lCopiaOk := .F.
Exit
Endif
// Salva os dados lidos no arquivo de destino
nBytesSalvo := FWRITE(nHDestino, cBuffer,nBytesLer)
// Determina se não houve falha na gravação
If nBytesSalvo < nBytesLer
MsgStop("Erro de gravação do Destino. "+;
Str(nBytesLer,8,2)+" bytes a
SALVAR."+;
Str(nBytesSalvo,8,2)+" bytes
gravados."+;
"Ferror =
"+str(ferror(),4),'Erro')
lCopiaOk := .F.
EXIT
Endif
// Elimina do Total do Arquivo a quantidade de bytes copiados
nBytesFalta -= nBytesLer
Enddo
// Fecha os arquivos de origem e destino
FCLOSE(nHOrigem)
FCLOSE(nHDestino)
If lCopiaOk
MsgStop('Cópia de Arquivos finalizada com sucesso. '+;
str(nTamArquivo,12,0)+' bytes
copiados.','Final')
Else
MsgStop( 'Falha na Cópia. Arquivo de Destino incompleto. '+;
'Do total de '+str(nTamArquivo,12,0)+'
bytes, faltaram '+str(nBytesFalta,12,0)+' bytes.','Final')
Endif
Return
Sintaxe
GETCLIENTDIR ( ) --> cPath
Retorno
Tipo Descrição
Caracter Retona o path onde está instalado o Protheus Remote.
Descrição
Retorna o diretório completo onde o Remote está instalado, informando inclusive a
unidade de disco.
Observação : Esta função apenas retornará um resultádo válido caso seja
executada em um programa através do Protheus Remote . Caso esta função seja
chamada em JOB , a mesma ocasionará um erro de execução ( Error to
comunicate with Remote ) .
Exemplos
No exemplo abaixo , obtemos o drive e diretório onde estão instalados o Remote .
MsgStop('Protheus Remote instalado em '+ GetClientDir())
Sintaxe
GETREMOTEININAME ( ) --> cArqConf
Retorno
Tipo Descrição
Caracter Path e nome do arquivo de configuração
Descrição
Retorna o nome do arquivo de configuração do AP Remote.
Exemplo das funções IsSrvUnix e GetRemoteIniName
Revisão: 12/06/2003
Abrangência
Versão 6.09 Versão 7.10 Versão 8.11
Através do exemplo abaixo, podemos obter o path de execução do AP Remote.
#include "[Link]"
Function TstRmtPath()
Local cIniName:= GETREMOTEININAME()
Local lUnix:= IsSrvUnix()
Local nPos:= Rat( IIf(lUnix,"/","\"),cIniName )
Local cPathRmt
if nPos!=0
cPathRmt:= Substr( cIniName,1,nPos-1 )
else
cPathRmt:=""
endif
QOut( cPathRmt )
Return
Sintaxe
GETSRVPROFSTRING ( < cChave > , < cDefault > ) --> cConteudo
Parâmetros
Argumento Tipo Descrição
cChave Caracter Chave do INI do environment a ser lida,
cDefault é o conteudo da chave a ser retornado caso a
cDefault Caracter
chave não seja encontrada no .ini
Retorno
Tipo Descrição
Caracter Conteudo da chave especificada
Descrição
Através da função GetSrvProfString , podemos obter o conteúdo de uma chave de
configuração do environment atual em uso no arquivo de Inicialização do Server
Protheus ( [Link] ) .
Sintaxe
MAKEDIR ( < cNovoDir > ) --> nResultado
Parâmetros
Argumento Tipo Descrição
Nome do diretório a ser criado, incluindo opcionalmente o
cNovoDir Caracter
caminho (path).
Retorno
Tipo Descrição
Retorno zero ( 0 ),o diretório foi criado com sucesso. Caso contrário,
Numérico
houve erro na criação do diretório.
Descrição
Cria um diretório na estação ou no servidor APx.
Caso o diretório comece com um drive ( Ex: C:, X: ) o diretório será criado na estação,
caso contrário será criado no servidor.
MAKEDIR("c:\teste\um") // Cria um diretório na estacao
nResult := MAKEDIR("\teste\um") // Cria o diretorio no servidor
Advanced protheus
IF nResult != 0
Conout( "Impossivel Criar o diretório no servidor Protheus", nResult
)
ENDIF
MAKEDIR( "teste" ) // Exemplo também válido ( Criando o diretório no
servidor ) dentro do diretório corrente
Sintaxe
MSCOMPRESS ( < cArq | aArquivos > , [ cDestino ] , [ cSenha ] ) --> cFileName
Parâmetros
Argumento Tipo Descrição
Arquivo(s) a ser(em) compactado(s). Pode ser do tipo
String , para especificar um único arquivo , ou do tipo
cArq | aArquivos (Qualquer)
Array , contendo um ou mais arquivo(s) a ser(em)
compatado(s).
Nome do Arquivo destino, caso a extensão seja omitida
será assumido .MZP, se não for informado assumirá o
cDestino Caracter
mesmo nome do cArq com extensão .MZP ou o nome do
1º. Arquivo no Array <aArquivos>.
Senha a ser utilizada para criptografar o arquivo
cSenha Caracter
compactado.
Retorno
Tipo Descrição
Caso a compactação seja executada com sucesso , a função retornará uma
sring contendo o nome do arquivo gerado . Caso não seja possível a
Caracter compactação , por falta de espaço em disco ou erro de acesso a algum dos
arquivos a ser(em) compactado(s), a função retornará uma string em
branco ("").
Descrição
Compacta um ou vários arquivos em um único arquivo com extensão .MZP.
MSCOMPRESS() compacta os arquivos informados em um único arquivo com
extensão default .MZP. O formato é proprietário e multiplataforma.
Caso a senha seja informada apenas com a senha poderemos descompactar os arquivos.
Tanto arquivos no local ( Remote ) como no Servidor são aceitos.
Exemplos
// Exemplo 1 à Compacta apenas um arquivo
lRes := MSCOMPRESS( "[Link]", "[Link]" )
// Exemplo 2 à Compacta um diretório com senha
aNome := {}
ADIR( "*.DBF", aNome )
lRes := MSCOMPRESS( aNome, "[Link]", "SENHA" )
Sintaxe
MSDECOMP ( < cArq > , [ cPathDestino ] , [ cSenha ] ) --> lSucess
Parâmetros
Argumento Tipo Descrição
cArq Caracter Nome do Arquivo no formato MZP a ser descompactado.
Path de destino onde serão gravados o(s) arquivo(s)
cPathDestino Caracter descompactado(s). Note que podem ser incluídos
caminhos do servidor como caminhos locais.
Caso o arquivo tenha sido compactado com senha , esta
cSenha Caracter deve ser especificada ñeste parâmetro para ser poss;ivel a
descompactação do arquivo.
Retorno
Tipo Descrição
Caso a descompactação foi executada com sucesso, a função
retornará .T. , Em caso de erro durante a descompactação, a função
retrornará .F. Verifique o espaço disponível na unidade de disco para
Lógico
descompactar o(s) arquivo(s) e/ou se existe amgum arquivo a ser
descompactado no pacote que já exista na unidade de disco , atribuído
como "REad-Only".
Descrição
MSDECOMP() descompacta o arquivo informado em um diretório. O Formato é
proprietário, e multi-plataforma, suporta apenas arquivos compactados pela função
MSCOMPRESS().
Caso o arquivo seja protegido por senha, apenas com a senha poderemos descompactá-
lo.
Tanto arquivos no local ( Remote ) como no Servidor são aceitos.
Sintaxe
MSDECOMP ( < cArq > , [ cPathDestino ] , [ cSenha ] ) --> lSucess
Parâmetros
Argumento Tipo Descrição
cArq Caracter Nome do Arquivo no formato MZP a ser descompactado.
Path de destino onde serão gravados o(s) arquivo(s)
cPathDestino Caracter descompactado(s). Note que podem ser incluídos
caminhos do servidor como caminhos locais.
cSenha Caracter Caso o arquivo tenha sido compactado com senha , esta
deve ser especificada ñeste parâmetro para ser poss;ivel a
descompactação do arquivo.
Retorno
Tipo Descrição
Caso a descompactação foi executada com sucesso, a função
retornará .T. , Em caso de erro durante a descompactação, a função
retrornará .F. Verifique o espaço disponível na unidade de disco para
Lógico
descompactar o(s) arquivo(s) e/ou se existe amgum arquivo a ser
descompactado no pacote que já exista na unidade de disco , atribuído
como "REad-Only".
Descrição
MSDECOMP() descompacta o arquivo informado em um diretório. O Formato é
proprietário, e multi-plataforma, suporta apenas arquivos compactados pela função
MSCOMPRESS().
Caso o arquivo seja protegido por senha, apenas com a senha poderemos descompactá-
lo.
Tanto arquivos no local ( Remote ) como no Servidor são aceitos.
Sintaxe
SPLITPATH ( < cArq > , [ @cDrive ] , [ @cCaminho ] , [ @cNome ] , [ @cExt ] ) -->
NIL
Parâmetros
Argumento Tipo Descrição
Nome do Arquivo a ser quebrado. Opcionalmente, pode
cArq Caracter
incluir caminho e drive.
Nome do Drive. Exemplo ( C: ). Caso o Arquivo
cDrive Caracter informado não possua drive ou o caminho refira-se ao
servidor, o retorno será uma string em branco.
Nome do Caminho. Caso o Arquivo informado não possua
cCaminho Caracter
caminho, será uma string em branco.
Nome do Arquivo sem a extensão. Caso em cArq não seja
cNome Caracter especificado um nome do Arquivo, será retornada uma
string em branco.
Extensão do arquivo informado em cArq , prefizada com
cExt Caracter um ponto ".". Caso a extensão em cArq não seja
especificada , o retorno será uma string em branco.
Retorno
Tipo Descrição
Caracter Esta função sempre retorna NIL.
Descrição
A função SplitPath() divide um caminho completo em todas as suas subpartes ( Drive ,
Caminho , Nome e Extensão ) .
Tanto arquivos locais ( Remote ) quanto arquivos no servidor, podem ser informados.
O caminho, caso informado, incluirá uma barra como último caracter. A extensão ,
quando retornada , inclui sempre o ponto ( . ) antes da extensão.
Todos os parâmetros , a partir do segundo , quando passados devem ser por referência.
Observação : Vale lembrar que a função SplitPath não valida a sintaxe do caminho
e/ou arquivo digitados , nem a existência do mesmo . Esta função é utilizada para
determinar em uma string os elementos que compõe um caminho para a
localização de um arquivo.
Exemplos
No exemplo abaixo , exemplificamos o funcionamento da função SplitPath , usando
combinações de nomes de arquivos com ou sem drive , caminho , nome de arquivo e/ou
extensão.
User Function TSTSplit()
Local aArq := {} , cDrive, cDir, cNome, cExt
aadd(aArq,'c:\path\[Link]')
aadd(aArq,'c:\path\arquivo')
aadd(aArq,'c:\path\')
aadd(aArq,'c:\arquivo')
aadd(aArq,'\path\[Link]')
aadd(aArq,'path\arquivo')
aadd(aArq,'\\servidor\pasta\')
aadd(aArq,'\\servidor\pasta\[Link]')
aadd(aArq,'')
For nI := 1 to len(aArq)
SplitPath( aArq[nI], @cDrive, @cDir, @cNome, @cExt )
conout( aArq[nI] + ' ['+cDrive+'] ['+ cDir +'] ['+ cNome +'] ['+
cExt + ']')
Next
Após executado o programa acima, deve ser exibido no console do Protheus Server o
texto abaixo :
c:\path\[Link] [c:] [\path\] [arquivo] [.ext]
c:\path\arquivo [c:] [\path\] [arquivo] []
c:\path\ [c:] [\path\] [] []
c:\arquivo [c:] [\] [arquivo] []
\path\[Link] [] [\path\] [arquivo] [.ext]
path\arquivo [] [path\] [arquivo] []
\\servidor\pasta\ [] [\\servidor\pasta\] [] []
\\servidor\pasta\[Link] [] [\\servidor\pasta\] [arquivo] [.ext]
[] [] [] []
Sintaxe
WRITEPPROSTRING ( < cSecao > , < cChave > , < cConteudo > , < cArqIni > ) -->
lSucess
Parâmetros
Argumento Tipo Descrição
cSecao corresponde ào nome da seção do íni a ser
cSecao Caracter
utilizada. Caso a seção não exista , a mesma será criada.
Chave da seção do ini a ter seu conteúco alterado . Caso a
cChave Caracter chave não esxista na seção especificada, a mesma será
criada.
cConteudo corresponde ào conteúdo da chave a ser
cConteudo Caracter
atualizado.
cArqIni corresponde ao nome do arquivo de inicialização
a ser alterado. Caso o arquivo não exista , ele será criado .
Caso o path do arquivo não seja informado , o mesmo será
cArqIni Caracter criado/atualizado no diretório onde está instalado o
Protheus Server, no servidor. Caso especificado um path
absoluto , com unidade de disco , o arquivo .ini será criado
e/ou atualizado na estação remota , no path informado.
Retorno
Tipo Descrição
Caso a chave seja incluida e/ou alterada com sucesso , a função
retornatá .T. (true) , e caso ocorra alguma falha ou impossibilidade de
Lógico acesso ao arquivo .ini , a função retornará .F. (false). Dentre as causas
mais comuns de falha , podemos citar erro de sintaxe no nome do arquivo
e/ou path inexistente ou inacessível.
Descrição
Através da funcao WritePProString() , é possível criar e/ou alterar uma seção / chave de
configuração em um arquivo .ini . Caso o arquivo não exista , o mesmo será criado . No
nome do arquivo , podemos opcionalmente definir um path absoluto , com unidade de
disco , de modo que o arquivo .ini será atualizado na estação remota ( onde está sendo
executado o Protheus Remote ) . Caso não seja especificado nenhum path ou caminho
do arquivo .ini , o caminho de disco considerado será o path no Servidor onde está
instalado o Protheus Server .
FUNÇÃO DE TRATAMENTO DE CARACTERES
Sintaxe
ALLTRIM ( < cString > ) --> cTrimString
Parâmetros
Argumento Tipo Descrição
<cString> é a expressao caractere cujos espaços em branco
cString Caracter
serao eliminados.
Retorno
Tipo Descrição
ALLTRIM() retorna uma cadeia de caracteres cujos espaços em branco à
Caracter
direita e à esquerda foram removidos.
Descrição
ALLTRIM() é uma função de tratamento de dados do tipo caractere que remove os
espaços em branco à direita e à esquerda de uma cadeia de caracteres. É relacionada a
LTRIM() e RTRIM(), que removem espaços em branco à esquerda e à direita de uma
cadeia de caracteres, respectivamente. O inverso de ALLTRIM(), LTRIM(), e RTRIM()
sao as funçoes PADC(), PADR(), e PADL(), as quais centralizam, alinham à direita, ou
alinham à esquerda cadeias de caracteres através da inserção de caracteres de
preenchimento.
Sintaxe
DESCEND ( < cString > ) --> cDescend
Parâmetros
Argumento Tipo Descrição
<cString> corresponde à sequência de caracteres a ser
cString Caracter
analisada.
Retorno
Tipo Descrição
DESCEND() retorna a string especificada como parâmetro de uma forma
Caracter
complementada. Um DESCEND() de CHR(0) sempre retorna CHR(0).
Descrição
DESCEND() é uma função de conversão que retorna a forma complementada da
expressão string especificada. Esta função normalmente é utilizada para a criação de
indexadores em Ordem Decrescente.
Exemplos
Este exemplo utiliza DESCEND() em uma expressao INDEX para criar um índice de
datas de ordem descendente:
USE Sales NEW
INDEX ON DESCEND(DTOS(OrdDate)) TO SalesDate
Depois, DESCEND() pode ser utilizado para fazer uma pesquisa (SEEK) no índice
descendente:
DbSEEK(DESCEND(DTOS(dFindDate)))
Observação : Faz-se necessária a conversão da Data para String m através da
função DTOS(), pois a função DESCEND apenas trabalha com Strings.
Sintaxe
LTRIM ( < cString > ) --> cStringResult
Parâmetros
Argumento Tipo Descrição
<cString> é a cadeia de caracteres a ser copiada sem os
cString Caracter
espaços em branco à esquerda.
Retorno
Tipo Descrição
LTRIM() retorna uma cópia de <cString>, sendo que os espaços em
branco à esquerda foram removidos. Caso <cString> seja uma cadeia de
Caracter
caracteres nula ("") ou toda composta de espaços em branco, LTRIM()
retorna uma cadeia de caracteres nula ("").
Descrição
LTRIM() é uma funçao de tratamento de caracteres utilizada para Formatar cadeias de
caracteres que possuam espaços em branco à esquerda. Pode ser o caso de, por exemplo,
números convertidos para cadeias de caracteres através da funçao STR().
LTRIM() é relacionada a RTRIM(), a qual remove espaços em branco à direita, e a
ALLTRIM(), que remove espaços tanto à esquerda quanto à direita. O contrário de
ALLTRIM(), LTRIM(), e RTRIM() sao as funçoes PADC(), PADR(), e PADL(), as
quais centralizam, alinham à direita, ou alinham à esquerda as cadeias de caracteres,
através da inserçao de caracteres de preenchimento.
Sintaxe
PADL / PADR / PADC ( < exp > , < nTamanho > , [ cCaracPreench ] ) -->
cStringPreench
Parâmetros
Argumento Tipo Descrição
<exp> é um valor caractere, data, ou numérico no qual
exp Caracter
serao inseridos caracteres de preenchimento.
<nTamanho> é o tamanho da cadeia de caracteres a ser
nTamanho Numérico
retornada.
<cCaracPreench> é o caractere a ser inserido em <exp>.
cCaracPreench Caracter Caso nao seja especificado, o padrao é o espaço em
branco.
Retorno
Tipo Descrição
PADC(), PADL(), e PADR() retornam o resultado de <exp> na forma de
Caracter uma cadeia de caracteres preenchida com <cCaracPreench>, para totalizar
o tamanho especificado por <nTamanho>.
Descrição
PADC(), PADL(), e PADR() sao funçoes de tratamento de caracteres que inserem
caracteres de preenchimento em valores caractere, data ou numéricos a fim de criar uma
nova cadeia de caracteres de tamanho especificado. PADC() centraliza <exp>,
adicionando caracteres de preenchimento à direita e à esquerda; PADL() adiciona
caracteres de preenchimento à esquerda; e PADR() adiciona caracteres de
preenchimento à direita. Caso o tamanho de <exp> exceda o argumento <nTamanho>,
todas as funçoes PAD() truncam cStringPreench ao <nTamanho> especificado.
PADC(), PADL(), e PADR() sao utilizadas para exibir cadeias de caracteres de tamanho
variável em uma área de tamanho fixo. Elas podem ser usadas, por exemplo, para
assegurar o alinhamento com comandos ?? consecutivos. Outra utilizaçao é exibir textos
em uma tela de tamanho fixo, para certificar-se de que o texto anterior foi
completamente sobreescrito.
PADC(), PADL(), e PADR() sao o contrário das funçoes ALLTRIM(), LTRIM(), e
LTRIM(), as quais eliminam espaçoes em branco à esquerda e à direita de cadeias de
caracteres.
Sintaxe
RTRIM ( < cString > ) --> cTrimString
Parâmetros
Argumento Tipo Descrição
<cString> é a cadeia de caracteres a ser copiada sem os
cString Caracter
espaços em branco à direita.
Retorno
Tipo Descrição
RTRIM() retorna uma cópia de <cString>, sendo que os espaços em
branco à direita foram removidos. Caso <cString> seja uma cadeia de
Caracter
caracteres nula ("") ou totalmente composta por espaços, RTRIM() retorna
uma cadeia de caracteres nula ("").
Descrição
RTRIM() é uma funçao de tratamento de caracteres utilizada para Formatar cadeias de
caracteres que contenham espaços em branco à direita. Ela é útil quando você deseja
eliminar espaços em branco à direita ao se concatenar cadeias de caracteres. É o caso
típico com campos de banco de dados que sao armazenados em formato de tamanho
fixo. Por exemplo, você pode usar RTRIM() para concatenar o primeiro e o último
campos de nome para formar uma cadeia de caracteres de nome.
LTRIM() é relacionada a RTRIM(), que remove espaços em branco à direita, e a
ALLTRIM(), que remove espaços em branco à direita e à esquerda. O contrário de
ALLTRIM(), LTRIM(), e RTRIM() sao as funçoes PADC(), PADR(), e PADL(), as
quais centralizam, alinham à direita, ou alinham à esquerda cadeias de caracteres,
inserindo caracteres de preenchimento.
Sintaxe
CDOW ( < dExp > ) --> cNomeDia
Parâmetros
Argumento Tipo Descrição
dExp Data <dExp> é o valor data a ser convertido.
Retorno
Tipo Descrição
Caracter CDOW() retorna o nome do dia da semana na forma de uma cadeia de
caracteres. A primeira letra será maiúscula e o resto dos caracteres virá em
minúsculas. Para um valor de data nulo ou inválido, CDOW() retorna uma
cadeia de caracteres vazia ("").
Descrição
CDOW() é uma função utilizada para obter, a partir de uma data, a cadeia de caracteres
contendo o dia da semana correspondente.
Exemplos
Os exemplos a seguir ilustram o funcionamento da funçao CDOW():
conout( DATE() ) // Resulta: 08/04/02
conout( CDOW(DATE()) ) // Resulta: Sunday
conout( CDOW(DATE() + 7) ) // Resulta: Sunday
conout( CDOW(CTOD("12/06/90")) ) // Resulta: Thursday
Sintaxe
CMONTH ( < dData > ) --> cMês
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é a data a converter.
Retorno
Tipo Descrição
CMONTH() retorna o nome do mês a partir de uma data como sendo uma
cadeia de caracteres com a primeira letra maiúscula e o restante da string
Caracter
em letras minúsculas. Para uma data nula, CMONTH() retornará uma
string nula ("").
Descrição
CMONTH() é uma função de conversão de datas que , a partir de uma data , retorna
uma cadeia de caracteres correspondendo ao nome do mês correspondente.
Exemplos
Os exemplos seguintes ilustram a utilizaçao da funçao CMONTH():
conout( CMONTH(DATE()) ) //
Resulta: August
conout( CMONTH(DATE() + 45) ) //
Resulta: September
conout( SUBSTR(CMONTH(DATE()), 1, 3) + STR(DAY(DATE()),3)) //
Resulta: Aug 4
Sintaxe
DATE ( ) --> dSistema
Retorno
Tipo Descrição
Data DATE() retorna a data do sistema como sendo um valor do tipo data.
Descrição
Retorna a data do sistema.
DATE() é a função que retorna a data do atual sistema. O formato de
saída é controlado pelo comando SET DATE. O formato padrão é mm/dd/yy.
Exemplos
conout( DATE() ) // Resulta: 08/04/02
conout( DATE() + 30 ) // Resulta: 09/03/02
conout( DATE() - 30 ) // Resulta: 07/05/02
dDate = DATE()
conout( CMONTH(dDate) ) // Resulta: August
Sintaxe
DAY ( < dData > ) --> nDia
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é a data a converter.
Retorno
Tipo Descrição
DAY() retorna um número na faixa de 0 até 31, sendo este um valor
numérico inteiro. Caso o mês seja Fevereiro, os anos bissextos sao
Numérico considerados. Se o argumento de data é 29 de Fevereiro e o ano nao é
bissexto, DAY() retornará zero. Se o argumento de data é vazio, DAY()
também retornará zero.
Descrição
Retorna o dia do mês como valor numérico. DAY() é uma funçao de conversao de datas
utilizada para converter um valor do tipo data para o dia do mês correspondente. Esta
função é usada em conjunto com CMONTH() e YEAR() para formatar datas. Além
disso, é geralmente usada em cálculos que envolvam datas.
Exemplos
Os exemplos seguintes mostram a funçao DAY() sendo utilizada
de diversas maneiras:
conout( DATE() ) // Resulta: 09/01/90
conout( DAY(DATE()) ) // Resulta: 1
conout( DAY(DATE()) + 1) // Resulta: 2
conout( DAY(CTOD("")) ) // Resulta: 0
Este exemplo utiliza DAY() em conjunto com CMONTH() e YEAR()
para formatar um valor do tipo data:
conout( CMONTH(DATE()) + STR(DAY(DATE())) +;
"," + STR(YEAR(DATE())) ) // Resulta: June 15, 1990
Sintaxe
DOW ( < dData > ) --> nDia
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é o valor data que será convertido.
Retorno
Tipo Descrição
DOW() retorna o dia da semana na forma de um número entre zero e sete.
Numérico O primeiro dia da semana é um (Domingo) e o último é sete (Sábado). Se
<dData> estiver vazio, DOW() retorna zero.
Descrição
DOW() é uma funçao de conversao de datas que converte um valor data para um
número que identifica o dia da semana. Ela é útil quando você deseja cálculos de data
em uma base semanal. DOW() é semelhante a CDOW(), a qual retorna o dia da semana
na forma de uma cadeia de caracteres ao invés de um número.
Exemplos
Os exemplos a seguir ilustram CDOW() e seu relacionamento com DOW():
conout( DATE() ) // Resulta: 09/01/89
conout( DOW(DATE()) ) // Resulta: 3
conout( CDOW(DATE()) ) // Resulta: Terca-feira
conout( DOW(DATE() - 2) ) // Resulta: 1
conout( CDOW(DATE() - 2) ) // Resulta: Domingo
A seguir está uma funçao definida por usuário que utiliza DOW() para calcular a data da
última segunda-feira a partir de qualquer outra data:
USER FUNCTION LastMonday(dData)
Return (dData - DOW(dData) + 2)
Sintaxe
DTOC ( < dData > ) --> cData
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é o valor data que será convertido.
Retorno
Tipo Descrição
DTOC() retorna uma cadeia de caracteres que representa uma data. O
valor de retorno é formatado de acordo com o formato de datas corrente.
Caracter
O formato padrao é mm/dd/aa. Uma data nula retorna uma cadeia de
caracteres em branco igual em tamanho ao formato de data corrente.
Descrição
DTOC() é uma funçao de conversao de datas utilizada por motivos de Formataçao
quando você deseja exibir a data no formato SET DATE e é necessária uma expressao
caractere. Caso você precise de um formato de data específico, você pode utilizar
TRANSFORM() ou uma expressao customizada.
Se você estiver INDEXando uma data juntamente com uma cadeia de caracteres, use
DTOS() ao invés de DTOC() para converter o valor data para uma cadeia de caracteres.
Exemplos
Os exemplos a seguir demonstram utilizaçoes gerais de DTOC():
conout( DATE() ) // Resulta: 09/01/90
conout( DTOC(DATE()) ) // Resulta: 09/01/90
conout( "Hoje e " + DTOC(DATE()) ) // Resulta: Hoje e 09/01/90
Sintaxe
DTOS ( < dData > ) --> cData
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é o valor data que será convertido.
Retorno
Tipo Descrição
DTOS() retorna uma cadeia com oito caracteres no formato, aaaammdd.
Quando <dData> for uma data nula (CTOD("")), DTOS() retorna uma
Caracter
cadeia de oito caracteres em branco. O valor de retorno nao é afetado pelo
Formato de data corrente.
Descrição
DTOS() é uma funçao de conversao de datas utilizada para criar expressoes de índice
que consistem em um valor data e uma expressao caractere. DTOS() converte um valor
data para uma cadeia de caracteres que pode ser concatenada a qualquer outra expressao
caractere. O valor de retorno é estruturado para preservar a ordem de data (ano, mês, e
dia).
Exemplos
Os exemplos a seguir ilustram DTOS() em conjunto com várias outras funçoes:
conout( DATE() ) // Resulta: 09/01/90
conout( DTOS(DATE()) ) // Resulta: 19900901
conout( LEN(DTOS(CTOD(""))) ) // Resulta: 8
Este exemplo demonstra como criar um índice com uma data
composta e chave de caractere utilizando DTOS():
USE Vendas NEW
INDEX ON DTOS(Data) + Vendedor TO DataVend
Sintaxe
ELAPTIME ( < cHoraInicial > , < cHoraFinal > ) --> cIntervalo
Parâmetros
Argumento Tipo Descrição
Informe a hora inicial no formato hh:mm:ss, onde hh é a
cHoraInicial Caracter
hora ( 1 a 24 ), mm os minutos e ss os segundos
Informe a hora final no formato hh:mm:ss, onde hh é a
cHoraFinal Caracter
hora ( 1 a 24 ), mm os minutos e ss os segundos.
Retorno
Tipo Descrição
A diferença de tempo no formato hh:mm:ss, onde hh é a hora ( 1 a 24 ),
Caracter
mm os minutos e ss os segundos
Descrição
ElapTime() retorna uma cadeia de caracteres contendo a diferença de
tempo entre cHoraFinal - cHoraInicial , no formato hh:mm:ss.
Os dois parâmetros , cHoraInicial e cHoraFinal , devem ser especificados no formato
hh:mm:ss , com tamanho de 8 bytes . Caso um dos parâmetros tenha tamanho diferente
de 8 Bytes, é gerada uma ocorrência de Erro Fatal "invalid len". Qualquer caracter
invalido nas posicões referentes à hora (hh) , minuto (mm) e segundo (ss) , serão
ignorados na composição de numeros para o cálculo. Caso o horário inicial seja maior
que o horário final , é retornada a diferença entre os horários acrescidos de 24h. Para
maiores detalhes , consulte o exemplo da função ElapTime()
Exemplos
Este exemplo utiliza a função ElapTime() para calcular o tempo necessário para um
determinado processamento.
cHoraInicio := TIME() // Armazena hora de inicio do processamento
.
. <instrucoes>
.
cElapsed := ELAPTIME(TIME(),cHoraInicio) // Calcula a diferença de
tempo
Sintaxe
MONTH ( < dData > ) --> nMês
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é o valor data a ser convertido.
Retorno
Tipo Descrição
MONTH() retorna um valor numérico inteiro na faixa de 0 (zero) a 12.
Numérico
Uma data nula (CTOD("")) retorna zero.
Descrição
MONTH() é uma funçao de conversao de datas que é útil quando você precisa de um
valor de mês numérico durante cálculos para, por exemplo, relatórios periódicos.
MONTH() faz parte de um grupo de funçoes que retornam componentes de um valor
data na forma de valores numéricos. O grupo inclui DAY() e YEAR(), que retornam os
valores de dia e ano na Forma de númericos. CMONTH() é uma funçao relacionada,
que permite a você retornar o nome do mês a partir de um valor data.
Exemplos
Estes exemplos ilustram o retorno do mês da data do sistema:
conout( DATE() ) // Resulta: 09/01/90
conout( MONTH(DATE()) ) // Resulta: 9
conout( MONTH(DATE()) + 1 ) // Resulta: 10
Este exemplo demonstra a funçao MONTH() atuando em uma data nula:
conout( MONTH(CTOD("")) ) // Resulta: 0
Sintaxe
SECONDS ( ) --> nSegundos
Retorno
Tipo Descrição
SECONDS() retorna a hora do sistema como um valor numérico na forma
[Link]ésimos. O valor numérico retornado é a quantidade de
Numérico
segundos decorridos desde a meia-noite, e tem base em um relógio de
vinte e quatro horas em uma faixa de zero a 86399.
Descrição
SECONDS() é uma funçao de horas utilizada para fornecer um método simples de
calcular o tempo decorrido, com base no relógio do sistema, durante a execuçao do
programa. É relacionado à funçao TIME(), a qual retorna a hora do sistema como uma
cadeia de caracteres na forma hh:mm:ss.
Exemplos
Este exemplo compara o valor de TIME() com o de SECONDS():
conout( TIME() ) // Resulta: [Link]
conout( SECONDS() ) // Resulta: 36000.00
Este exemplo demonstra como utilizar SECONDS() para informar o tempo decorrido
em segundos:
LOCAL nStart, nElapsed
nStart = SECONDS()
.
. <processamentos...etc....>
.
nElapsed = SECONDS() - nStart
conout( "Decorridos: " + LTRIM(STR(nElapsed)) + " segundos" )
Sintaxe
TIME ( ) --> cStringHora
Retorno
Tipo Descrição
TIME() retorna a hora do sistema como uma cadeia de caracteres na
forma hh:mm:ss. hh indica a hora no formato de 24 horas, mm indica os
Caracter
minutos, e ss indica os segundos. Horas, minutos e segundos sao
separadas por dois pontos.
Descrição
TIME() é uma funçao de tratamento de tempo, utilizada para exibir ou imprimir a hora
do sistema em um relatório ou na tela. TIME() está relacionada a SECONDS(), que
retorna a quantidade de segundos decorridos desde a meia-noite. SECONDS()
geralmente é utilizada em lugar de TIME() para cálculos sobre o tempo.
Exemplos
Estes exemplos mostram a função TIME() utilizada em conjunto com SUBSTR()
para extrair a hora, os minutos e os segundos:
cTime := TIME() // Resultado: [Link]
cHora := SUBSTR(cTime, 1, 2) // Resultado: 10
cMinutos := SUBSTR(cTime, 4, 2) // Resultado: 37
cSegundos := SUBSTR(cTime, 7, 2) // Resultado: 17
Sintaxe
YEAR ( < dData > ) --> nAno
Parâmetros
Argumento Tipo Descrição
dData Data <dData> é o valor data a ser convertido.
Retorno
Tipo Descrição
YEAR() retorna o ano do valor data especificado, inclusive dígitos
indicativos de século, na forma de um valor numérico de quatro dígitos. O
Numérico
valor retornado nao é influenciado pelo formato de DATE ou CENTURY
corrente. A especificaçao de uma data nula (CTOD("")) retorna zero.
Descrição
YEAR() é uma funçao de conversao de datas utilizada para converter um valor data para
um valor numérico indicativo do ano. Pode ser utilizada em cálculos de, por exemplo,
relatórios periódicos, ou para Formataçao de exibiçoes de data.
YEAR() é membro de um grupo de funçoes que retornam componentes de um valor
data na forma de valores numéricos. Este grupo inclui DAY() e MONTH(), que
retornam valores de dia e mês na forma de valores numéricos.
Exemplos
Os exemplos a seguir ilustram YEAR() usando a data do
sistema:
conout( DATE() ) // Resulta: 09/01/90
conout( YEAR(DATE()) ) // Resulta: 1990
conout( YEAR(DATE()) + 11 ) // Resulta: 2001
Este exemplo cria uma funçao definida pelo usuário usando
YEAR() para formatar um valor data na forma : mês dia, ano:
conout( U_Mdy(DATE()) ) // Resulta: September 20,
1990
USER FUNCTION Mdy( dDate )
Return CMONTH(dDate) + " " + LTRIM(STR(DAY(dDate)));
+ "," + STR(YEAR(dDate))
FUNÇÕES DE TRATAMENTO DE MATRIZ
Sintaxe
AADD ( < aDestino > , [ expValor ] ) --> Valor
Parâmetros
Argumento Tipo Descrição
aDestino Array É o array ao qual o novo elemento será adicionado.
É uma expressão válida que será o valor do
expValor (Qualquer)
novo elemento.
Retorno
Tipo Descrição
Avalia expValor e retorna seu Valor. Se expValor não for especificado,
(Qualquer)
AADD() retorna NIL.
Descrição
AADD() é uma função de tratamento de vetor que adiciona um elemento ao vetor. Ao
elemento de vetor recém criado é atribuido o valor especificado por <expValor>.
AADD() é utilizado para aumentar o tamanho de um vetor dinamicamente. É útil na
construção de filas ou listas dinâmicas.
AADD() é semelhante à função ASIZE(), mas adiciona apenas um elemento por vez;
ASIZE() pode aumentar ou diminuir um vetor a um tamanho especificado. AADD(),
porém, possui a vantagem de poder atribuir um valor ao novo elemento, enquanto que
ASIZE() nao pode. AADD() pode também parecer ser igual a AINS(), mas isso nao é
verdade: AINS() move elementos dentro de um vetor, mas nao modifica o tamanho do
vetor.
OBSERVAÇÃO : Caso <expValor> seja um outro vetor, o novo elemento no vetor
destino conterá uma referência ao vetor especificado por <expValor>.
Os exemplos a seguir demonstram os efeitos de chamadas múltiplas da função AADD()
para um vetor:
aArray := {} // Resulta: aArray e um vetor vazio
AADD(aArray, 5) // Resulta: aArray e { 5 }
AADD(aArray, 10) // Resulta: aArray e { 5, 10 }
AADD(aArray, { 12, 10 }) // Resulta: aArray e { 5, 10, { 12,
10 } }
Sintaxe
ACLONE ( < aFonte > ) --> aDuplica
Parâmetros
Argumento Tipo Descrição
aFonte Array <aFonte> é o vetor a ser duplicado.
Retorno
Tipo Descrição
Array Array idêntico ao aFonte , porem sem nenhuma referência ao mesmo.
Descrição
ACLONE() é uma funçao de vetor que cria uma duplicata completa do vetor de
<aFonte>. Caso <aFonte> contenha sub-vetores, ACLONE() cria sub-vetores
correspondentes e os preenche com cópias dos valores contidos nos sub-vetores de
<aFonte>.
Ao igualarmos dois arrays, eles ficam associados por referência, utilizando
aClone() não existe referência. ACLONE() é semelhante a ACOPY(), porém ACOPY()
nao duplica vetores aninhados.
Sintaxe
ACOPY ( < aFonte > , < aDestino > , [ nInicio ] , [ nCont ] , [ nPosDestino ] ) -->
aDestino
Parâmetros
Argumento Tipo Descrição
aFonte Array <aFonte> é o vetor de onde serao copiados os elementos.
<aDestino> é o vetor para onde serao copiados os
aDestino Array
elementos.
<nInicio> é a posiçao do elemento inicial no vetor
nInicio Numérico <aFonte>. Se nao for especificado, o valor assumido é um
(01).
nCont Numérico <nCont> é a quantidade de elementos a serem copiados
do vetor <aFonte> a partir da posiçao <nInicio>. Caso
<nCont> nao seja especificado, todos os elementos em
<aFonte> que começam com o elemento inicial sao
copiados.
<nPosDestino> é a posiçao do elemento inicial no vetor
nPosDestino Numérico <aDestino> que receberá os elementos de <aFonte>. Se
nao for especificado, o valor padrao é um (01).
Retorno
Tipo Descrição
Array ACOPY() retorna uma referência ao vetor destino, <aDestino>.
Descrição
ACOPY() é uma funçao de tratamento de vetor que copia elementos do vetor <aFonte>
para o vetor <aDestino>. O vetor <aDestino> já deve existir e ser grande o suficiente
para conter os elementos copiados. Caso o vetor <aFonte> tenha mais elementos, alguns
elementos nao serao copiados.
ACOPY() copia valores de todos os tipos de dados, inclusive NIL e blocos de código.
Se um elemento do vetor <aFonte> for um sub-vetor, o elemento correspondente no
vetor <aDestino> conterá uma referência ao sub-vetor. Consequentemente, ACOPY()
nao cria duplicatas completas de vetores multi-dimensionais. Para fazer isto, use a
funçao ACLONE().
Exemplos
Este exemplo cria dois vetores, cada um deles preenchido com um valor. Os dois
primeiros elementos do vetor fonte sao entao copiados para o vetor destino:
LOCAL nCount := 2, nStart := 1, aOne, aTwo
aOne := { 1, 1, 1 }
aTwo := { 2, 2, 2 }
ACOPY(aOne, aTwo, nStart, aCont) // Resulta: aTwo e agora { 1, 1,
2 }
Sintaxe
ADEL ( < aFonte > , < nPosicao > ) --> aFonte
Parâmetros
Argumento Tipo Descrição
<aFonte> é o vetor que contém um elemento a ser
aFonte Array
eliminado.
<nPosiçao> é a posiçao do elemento de vetor , a partir do
nPosicao Numérico
primeiro , que será eliminado.
Retorno
Tipo Descrição
Array ADEL() retorna uma referência ao vetor destino, <aFonte>.
Descrição
ADEL() é uma funçao de tratamento de vetor que elimina um elemento de um vetor. O
conteúdo do elemento de vetor especificado é perdido, e todos os elementos a partir
daquela posiçao até o final do elemento sobem uma posiçao. O último elemento no
vetor torna-se NIL.
AVISO : Em Advpl, vetores multi-dimensionais sao implementados através do
aninhamento de vetores dentro de outros vetores. Caso o vetor <aFonte> seja um vetor
multi-dimensional, ADEL() eliminará todo o sub-vetor especificado por <nPosiçao>,
forçando <aFonte> a nao mais ter dimensoes regulares.
Este exemplo cria um vetor constante de três elementos, e depois
elimina o segundo elemento. O terceiro elemento sobe uma posiçao, e ao
novo terceiro elemento é atribuido NIL:
LOCAL aArray
aArray := { 1, 2, 3 } // Resulta: aArray e agora { 1, 2, 3 }
ADEL(aArray, 2) // Resulta: aArray e agora { 1, 3,
NIL }
Sintaxe
AEVAL ( < aVetor > , < bBloco > , [ nInicio ] , [ nCont ] ) --> aVetor
Parâmetros
Argumento Tipo Descrição
aVetor Array <aVetor> é o vetor a ser varrido.
<bBloco> é um bloco de código a ser executado para
bBloco Code-Block
cada elemento encontrado.
<nInicio> é o elemento inicial. Caso nao seja
nInicio Numérico
especificado, o padrao assumido é o elemento um.
<nCont> é a quantidade de elementos a serem
nCont Numérico processados a partir de <nInício>. Se nao for
especificado, o padrao é todos os elementos no vetor.
Retorno
Tipo Descrição
Array AEVAL() retorna uma referência a <aVetor>.
Descrição
AEVAL() é uma funçao de tratamento de vetor que avalia um bloco de código uma vez
para cada elemento de um vetor, passando o valor do elemento como um parâmetro de
bloco. O valor de retorno do bloco é ignorado. Todos os elementos no <aVetor> sao
processados a nao ser que o argumento <nInicio> ou <nCont> seja especificado.
AEVAL() nao faz suposiçoes sobre o conteúdo dos elementos de vetor que ele está
passando para o bloco. É assumido que o bloco sabe qual o tipo de dados haverá em
cada elemento.
AEVAL() é semelhante a DBEVAL(), que aplica um bloco para cada registro de um
arquivo de banco de dados. Da mesma forma que DBEVAL(), AEVAL() pode ser
utilizado como base para a construçao de comandos de interaçao tanto para estruturas de
vetor complexas como simples.
Consulte a seçao Blocos de Código no na seção A Linguagem Advpl para maiores
informações sobre Code-Blocks.
Exemplos
Local aArray := { "Teste" , 123 }
Local bBlock := { |x,y| conout(valtype(x)) , conout(y) }
aEval(aArray,bBlock)
No exemplo acima , criamos um array com 2 elementos : O primeiro é um Caracter , e o
segundo é um número ; e criamos um code-block que receberá em x ( primeiro
parametro fornecido pela função aEval) cada elemento do array , e y ( segundo
parametro fornecido pela aEval ) o número do elemento do array que está sendo
processado nesta execução.
O resultado de tela no console do Protheus Server deverá ser :
Teste // Conteudo do primeiro elemento
C // Tipo do conteudo
1 // Numero do elemento processado
123 // Conteudo do segundo elemento
N // Tipo do Segundo Elemento
2 // Numero do elemento processado
Caso o array passado como parâmetro seja um array multi-Dimensional , serão passados
como parâmetros os arrays de primeiro nivel para o code-BLock.
Vejamos uma aplicação mais complexa : Um array multi-dimensional temos 2colunas ,
uma de código (string) e uma de valor ( numérica ) , e seja necessário realizar um
cálculo de totalização da coluna numérica :
aItens := {}
aadd(aItens,{"Branco",10})
aadd(aItens,{"Preto",15})
aadd(aItens,{"Cinza",12})
// Podemos realizar a totalização pelo metodo tradicional :
nTotal := 0
For nI := 1 to len(aItens)
nTotal := nTotal + aItens[nI][2]
Next
conout(nTotal) // 37
// Ou utilizando a Funcão aEval :
nTotal := 0
aeval(aItens , {|x| nTotal += x[2] } )
conout(nTotal)
Sintaxe
AFILL ( < aDestino > , < ValorExp > , [ nInicio ] , [ nCont ] ) --> aDestino
Parâmetros
Argumento Tipo Descrição
aDestino Array <aDestino> é o vetor a ser preenchido.
<ValorExp> é o valor a ser alocado em cada elemento de
ValorExp (Qualquer) vetor. Pode ser uma expressao de qualquer tipo de dados
válido.
<nInicio> é a posiçao do primeiro elemento a ser
nInicio Numérico preenchido. Caso este argumento seja omitido, o valor
padrao é um.
<nCont> é a quantidade de elementos a serem
preenchidos iniciando com o elemento <nInicio>. Se este
nCont Numérico
argumento for omitido, os elementos sao preenchidos a
partir da posiçao do elemento inicial até o final do vetor.
Retorno
Tipo Descrição
Array AFILL() retorna uma referência ao <aDestino>.
Descrição
AFILL() é uma funçao de vetor que preenche um vetor especificado com um único
valor de qualquer tipo de dados (inclusive vetores, blocos de código ou NIL) atribuindo
<ValorExp> a cada elemento de vetor na faixa especificada.
ATENÇÃO : AFILL() nao pode ser utilizado para preencher vetores multi-
dimensionais. Este tipo de vetores em Clipper sao implementados aninhando-se vetores
dentro de outros vetores. A utilizaçao de AFILL() com vetores multi-dimensionais
sobre-escreverá vetores para as outras dimensoes do vetor.
Exemplos
Neste exemplo, é criado um vetor com três elementos. O vetor é depois preenchido com
falso (.F.). Ao final, aos elementos nas posiçoes dois e três é atribuido o novo valos de
verdadeiro (.T.):
LOCAL aLogic[3] // Resulta: aLogic e { NIL, NIL, NIL }
AFILL(aLogic, .F.) // Resulta: aLogic e { .F., .F., .F. }
AFILL(aLogic, .T., 2, 2) // Resulta: aLogic e { .F., .T., .T. }
Sintaxe
AINS ( < aDestino > , < @nPos > ) --> aDestino
Parâmetros
Argumento Tipo Descrição
aDestino Array É o array de onde será inserido um item NIL.
É a posição, a partir da 1, na qual será inserido um
nPos Numérico
elemento NIL
Retorno
Tipo Descrição
Array Retorna uma referência ao vetor aDestino
Descrição
AINS() é uma função de vetor que insere um novo elemento em um vetor especificado.
O elemento recém inserido é NIL até que um novo valor seja atribuido a ele. Após a
inserção, o último elemento no vetor é descartado, e todos os elementos depois do novo
elemento descem uma posição.
¤ AVISO : AINS() deve ser utilizado com cuidado quando se tratar de vetores multi-
dimensionais. Vetores multi-dimensionais em Advpl sao implementados através do
aninhamento de vetores dentro de outros vetores. Utilizar AINS() com um vetor multi-
dimensional descarta o último sub-vetor no vetor destino especificado, o que causa a
perda de uma ou mais dimensoes. Para inserir uma nova dimensao em um vetor,
primeiramente adicione um novo elemento ao final do vetor utilizando AADD() ou
ASIZE() antes de usar AINS().
Exemplos
Este exemplo demonstra o efeito da utilização de AINS() em um vetor:
LOCAL aArray
aArray := { 1, 2, 3 } // Resulta: aArray e agora { 1, 2, 3 }
AINS(aArray, 2) // Resulta: aArray e agora { 1, NIL,
2 }
Sintaxe
ARRAY ( < nElementos,... > ) --> aVetor
Parâmetros
Argumento Tipo Descrição
<nElementos> é a quantidade de elementos na dimensao
nElementos,... Numérico [Link] vetores em Advpl podem ter um número
ilimitado de dimensoes.
Retorno
Tipo Descrição
Array ARRAY() retorna um vetor de dimensoes especificadas.
Descrição
ARRAY() é uma funçao de tratamento de vetor que retorna um vetor nao inicializado
com a quantidade especificada de elementos e dimensoes. Se for especificado mais de
um argumento <nElementos>, é criado um vetor multi-dimensional ou aninhado, sendo
que a quantidade de dimensoes é igual à quantidade de argumentos <nElementos>
especificada.
No Advpl, há várias formas de se criar um vetor. Você pode declarar um vetor
utilizando LOCAL ou STATIC; você pode criar um vetor utilizando PRIVATE ou
PUBLIC; você pode atribuir um vetor literal a uma variável existente; ou você pode
usar a funçao ARRAY(). ARRAY() tem a vantagem de possibilitar a você a criaçao de
vetores dentro de expressoes ou blocos de código.
Exemplos
Este exemplo cria um vetor unidimensional de cinco elementos utilizando a funçao
ARRAY(), e depois exibe a açao equivalente atribuindo um vetor literal de valores NIL:
aArray := ARRAY(5)
aArray := { NIL, NIL, NIL, NIL, NIL }
Este exemplo ilustra três declaraçoes diferentes que criam o mesmo vetor multi-
dimensional:
aArray := ARRAY(3, 2)
aArray := { {NIL, NIL}, {NIL, NIL}, {NIL, NIL} }
aArray := { ARRAY(2), ARRAY(2), ARRAY(2) }
Sintaxe
ASCAN ( < aDestino > , < ProcuraExp > , [ nInicio ] , [ nCont ] ) --> nParouEm
Parâmetros
Argumento Tipo Descrição
aDestino Array <aDestino> é o vetor a ser varrido.
<ProcuraExp> pode ser um valor simples a ser
procurado, ou um bloco de código. Caso <ProcuraExp>
ProcuraExp (Qualquer)
seja um valor simples, este poderá ser do tipo numérico,
lógico, data, ou caractere.
<nInicio> é o elemento a partir do qual terá início a
nInicio Numérico pesquisa. Se este argumento nao for especificado, a
posiçao inicial padrao é um.
<nCont> é a quantidade de elementos que serao varridos
a partir da posiçao inicial. Caso este argumento nao seja
nCont Numérico
especificado, todos os elementos, desde o elemento
inicial até o final do vetor, serao varridos.
Retorno
Tipo Descrição
ASCAN() retorna um valor numérico que representa a posiçao ocupada
no vetor pelo último elemento varrido. Se <ProcuraExp> for um valor
simples, ASCAN() retorna a posiçao do primeiro elemento que
Numérico
corresponder ao valor procurado, ou zero caso nao haja correspondência.
Se <ProcuraExp> for um bloco de código, ASCAN() retorna a posiçao do
elemento onde o bloco retornou verdadeiro (.T.).
Descrição
ASCAN() é uma funçao de tratamento de vetor que varre um vetor procurando um valor
especificado e opera da mesma forma que o comando SEEK quando pesquisa um valor
simples. O valor <ProcuraExp> é comparado ao elemento de vetor destino que começa
com o caractere mais à esquerda no elemento destino e prossegue até que nao haja mais
nenhum caractere em <ProcuraExp>. Caso nao haja correspondência, ASCAN() vai
para o próximo elemento no vetor.
Como ASCAN() utiliza o operador (=) para comparaçoes, ele é sensível ao status de
EXACT. Caso EXACT esteja ON, o elemento de vetor destino deve ser exatamente
igual ao resultado de <ProcuraExp> para que haja correspondência.
Se o argumento de <ProcuraExp> seja um bloco de código, ASCAN() varre o vetor
<aDestino> executando o bloco para cada elemento acessado. À medida em que cada
elemento é encontrado, ASCAN() passa o valor do elemento como um argumento para
o bloco de código, e depois executa um EVAL() no bloco. A operaçao de pesquisa pára
quando o bloco de código retorna verdadeiro (.T.), ou quando ASCAN() atinge o último
elemento no vetor.
Exemplos
O exemplo a seguir demonstra a pesquisa em um vetor de três elementos utilizando
valores simples e um bloco de código como critérios de pesquisa. Os critérios do bloco
de código ilustram como executar uma pesquisa que nao faz diferenciaçao entre
maiúsculas e minúsculas:
aArray := { "Tom", "Mary", "Sue" }
? ASCAN(aArray, "Mary") // Resulta: 2
? ASCAN(aArray, "mary") // Resulta: 0
? ASCAN(aArray, { |x| UPPER(x) == "MARY" }) // Resulta: 2
O Exemplo abaixo demonstra como continuar a pesquisa dos múltiplos tipos de um
argumento de pesquisa após ter sido encontrada uma correspondência:
LOCAL aArray := { "Tom", "Mary", "Sue", "Mary" }, nStart := 1
// Pegar ultima posicao de elemento de vetor
nAtEnd := LEN(myVetor)
While (nPos := ASCAN(aArray, "Mary", nStart)) > 0
? nPos, aArray[nPos]
// Pegar nova posicao inicial e testar condicao de limite
If (nStart := ++nPos) > nAtEnd
EXIT
EndIf
EndDo
Sintaxe
ASCAN ( < aDestino > , < ProcuraExp > , [ nInicio ] , [ nCont ] ) --> nParouEm
Parâmetros
Argumento Tipo Descrição
aDestino Array <aDestino> é o vetor a ser varrido.
<ProcuraExp> pode ser um valor simples a ser
procurado, ou um bloco de código. Caso <ProcuraExp>
ProcuraExp (Qualquer)
seja um valor simples, este poderá ser do tipo numérico,
lógico, data, ou caractere.
<nInicio> é o elemento a partir do qual terá início a
nInicio Numérico pesquisa. Se este argumento nao for especificado, a
posiçao inicial padrao é um.
<nCont> é a quantidade de elementos que serao varridos
a partir da posiçao inicial. Caso este argumento nao seja
nCont Numérico
especificado, todos os elementos, desde o elemento
inicial até o final do vetor, serao varridos.
Retorno
Tipo Descrição
ASCAN() retorna um valor numérico que representa a posiçao ocupada
no vetor pelo último elemento varrido. Se <ProcuraExp> for um valor
simples, ASCAN() retorna a posiçao do primeiro elemento que
Numérico
corresponder ao valor procurado, ou zero caso nao haja correspondência.
Se <ProcuraExp> for um bloco de código, ASCAN() retorna a posiçao do
elemento onde o bloco retornou verdadeiro (.T.).
Descrição
ASCAN() é uma funçao de tratamento de vetor que varre um vetor procurando um valor
especificado e opera da mesma forma que o comando SEEK quando pesquisa um valor
simples. O valor <ProcuraExp> é comparado ao elemento de vetor destino que começa
com o caractere mais à esquerda no elemento destino e prossegue até que nao haja mais
nenhum caractere em <ProcuraExp>. Caso nao haja correspondência, ASCAN() vai
para o próximo elemento no vetor.
Como ASCAN() utiliza o operador (=) para comparaçoes, ele é sensível ao status de
EXACT. Caso EXACT esteja ON, o elemento de vetor destino deve ser exatamente
igual ao resultado de <ProcuraExp> para que haja correspondência.
Se o argumento de <ProcuraExp> seja um bloco de código, ASCAN() varre o vetor
<aDestino> executando o bloco para cada elemento acessado. À medida em que cada
elemento é encontrado, ASCAN() passa o valor do elemento como um argumento para
o bloco de código, e depois executa um EVAL() no bloco. A operaçao de pesquisa pára
quando o bloco de código retorna verdadeiro (.T.), ou quando ASCAN() atinge o último
elemento no vetor.
Exemplos
O exemplo a seguir demonstra a pesquisa em um vetor de três elementos utilizando
valores simples e um bloco de código como critérios de pesquisa. Os critérios do bloco
de código ilustram como executar uma pesquisa que nao faz diferenciaçao entre
maiúsculas e minúsculas:
aArray := { "Tom", "Mary", "Sue" }
? ASCAN(aArray, "Mary") // Resulta: 2
? ASCAN(aArray, "mary") // Resulta: 0
? ASCAN(aArray, { |x| UPPER(x) == "MARY" }) // Resulta: 2
O Exemplo abaixo demonstra como continuar a pesquisa dos múltiplos tipos de um
argumento de pesquisa após ter sido encontrada uma correspondência:
LOCAL aArray := { "Tom", "Mary", "Sue", "Mary" }, nStart := 1
// Pegar ultima posicao de elemento de vetor
nAtEnd := LEN(myVetor)
While (nPos := ASCAN(aArray, "Mary", nStart)) > 0
? nPos, aArray[nPos]
// Pegar nova posicao inicial e testar condicao de limite
If (nStart := ++nPos) > nAtEnd
EXIT
EndIf
EndDo
Parâmetros
Argumento Tipo Descrição
Representa o objeto a ser varrido pela função, pode ser
destino (Qualquer)
atribuido ao parametro um array um Objeto.
Representa o valor que será pesquisado, podendo ser um
procura (Qualquer)
bloco de código.
Representa o elemento a partir do qual terá inicio a
nInicio Numérico pesquisa, quando este argumento nao for informado o
valor default será 1.
Representa a quantidade de elementos que serão
pesquisados a partir da posição inicial, quando este
nCont Numérico
argumento nao for informado todos elementos do array
serão pesquisados
Retorno
Tipo Descrição
Retorna o valor numérico(indice) que representa a posição ocupada no
Numérico vetor pelo ultimo elemento pesquisado, no caso quando a o elemnto foi
encontrado.
Descrição
A função ASCANX()‚ é uma funçao de tratamento de vetor. ASCANX tem como
objetivo varrer um vetor
procurando um valor especificado e opera de forma parecida com a função ASCAN.
A diferença fundamental da funçao ASCANX é que a função recebe um segundo
parametro em seu codeblock representando o indice do array.
Exemplo.:
nPos := aScanX( ARRAY, { |X,Y| X[1] == cNome .OR. y<=100})
Nesta linha de exemplo, note a inclusão no codeblock do Y, onde a função irá terminar
sua execução em 3 condiçoes:
1) Até encontrar o elemento no ARRAY com a ocorrência cNome, retornando a
posição desse elemento.
2) Essa é novidade, ASCANX irá verificar o Array até a posição 100.
3)O elemento cNome nao foi encontrado no ARRAY e a condição de Y até 100 nao
satizfaz, pois o array é menor do que 100 posiçoes!
Obs.: Como ASCAN() que utiliza o operador (=) para comparaçoes, a funçao
ASCANX() também é case sensitive, no caso os elementos procurados devem ser
exatamente igual.
Sintaxe
ASIZE ( < aDestino > , < @nTamanho > ) --> ASIZE()
Parâmetros
Argumento Tipo Descrição
aDestino Array <aDestino> é o vetor a ser aumentado ou diminuido.
nTamanho Numérico <nTamanho> é o novo tamanho do vetor.
Retorno
Tipo Descrição
Array Retorna uma referência ao array aDestino.
Descrição
ASIZE() é uma função de tratamento de vetor que muda o valor real do vetor
<aDestino>. O vetor é diminuido ou aumentado para corresponder ao tamanho
especificado. Caso o vetor seja diminuido, os elementos no final do vetor sao perdidos.
Se o vetor for aumentado, novos elementos sao adicionados ao final do vetor e a eles
atribuido NIL.
ASIZE() é semelhante a AADD(), o qual adiciona somente um novo elemento ao final
de um vetor e opcionalmente atribui um novo valor ao mesmo tempo. Observe que
ASIZE() é diferente de AINS() e ADEL(), os quais na realidade nao modificam o
tamanho do vetor.
Exemplos
Estes exemplos demonstram a adição de novos elementos e a eliminação de elementos
existentes:
aArray := { 1 } // Resulta: aArray e { 1 }
ASIZE(aArray, 3) // Resulta: aArray e { 1, NIL, NIL }
ASIZE(aArray, 1) // Resulta: aArray e { 1 }
Sintaxe
ASORT ( < aDestino > , [ nInicio ] , [ nCont ] , [ bOrdem ] ) --> aDestino
Parâmetros
Argumento Tipo Descrição
<aDestino> é o vetor cujos elementos serao colocados
aDestino Array
em ordem.
<nInicio> é o primeiro dos elementos que serao
nInicio Numérico colocados em ordem. Caso nao seja especificada, a
posiçao inicial assumida é um.
<nCont> é a quantidade de elementos que serao
colocados em ordem. Se nao for especificada, todos os
nCont Numérico
elementos no vetor que começam com o elemento inicial
sao ordenados.
<bOrdem> é um bloco de código opcional utilizado para
determinar qual a ordem que será seguida. Caso nao seja
especificada, a ordem padrao é ascendente. ***
bOrdem Code-Block
Atenção : Caso utilizada a função aSort para um array
aninhado (milti-dimensional), o parâmetro bOrdem deve
ser passado ; caso contrário o array não será ordenado.
Retorno
Tipo Descrição
Array ASORT() retorna uma referência ao vetor <aDestino>.
Descrição
ASORT() é uma funçao de vetor que coloca em ordem todo ou parte de um vetor que
contém elementos de um único tipo de dados. Os tipos de dados que podem ser
ordenados incluem caractere, data, lógico e numérico.
Se o argumento <bOrdem> nao for especificado, a ordem padrao é ascendente.
Elementos com valores baixos sao colocados no início do vetor (primeiro elemento),
enquanto elementos com valores altos sao colocados no final do vetor (último
elemento).
Caso o argumento de bloco <bOrdem> seja especificado, ele é utilizado para determinar
a ordem em que os elementos serao colocados. Cada vez que o bloco é avaliado, dois
elementos do vetor destino sao passados como parâmetros de bloco. O bloco deve
retornar verdadeiro (.T.) se os elementos estiverem ordenados. Isto pode ser usado para
criar uma ordem descendente ou de dicionário. Veja os exemplos abaixo.
Quando ordenadas, as cadeias de caracteres sao colocadas na sequência ASCII; valores
lógicos sao ordenados com falso (.F.) sendo considerado o valor menor; valores data sao
ordenados cronologicamente; e numéricos sao ordenados por magnitude.
OBSERVAçÃO : Sendo os vetores multi-dimensionais em Clipper implementados
através do aninhamento de sub-vetores dentro de outros vetores, ASORT() nao ordena
diretamente vetores deste tipo. Para ordenar um vetor aninhado, você deve fornecer um
bloco de código que dará o tratamento adequado aos sub-vetores.
Exemplos
No Exemplo abaixo , ordenamos um array em ordem crescenter , depois em ordem
decrescente através de um code-block .
Local aArray := { 3, 5, 1, 2, 4 }
ASORT(aArray) // Resultado: { 1, 2, 3, 4, 5 }
ASORT(aArray,,,{ |x, y| x > y }) // Resultado: { 5, 4, 3, 2, 1 }
No Exemplo abaixo , utilizamos na expressão de ordenação a função upper() , para
ordenar o array em ordem alfabérica independentemente da informação estar em letras
maiúsculas e/ou minusculas.
aArray := { "Fred", Kate", "ALVIN", "friend" }
ASORT(aArray,,, { |x, y| UPPER(x) < UPPER(y) })
No exemplo abaixo , montamos um code-block para ordenação de um array multi-
dimensional , para ordenar o array em ordem crescente do segundo elemento da
dimensão.
aKids := { {"Mary", 14}, {"Joe", 23},{"Art", 16} }
aSortKids := ASORT(aKids,,, { |x, y| x[2] < y[2] })
// Resultado : { {"Mary", 14}, {"Art", 16}, {"Joe",23} }
Sintaxe
ATAIL ( < aArray > ) --> Ret
Parâmetros
Argumento Tipo Descrição
aArray Array Representa o array a ser informado para a função.
Retorno
Tipo Descrição
(Qualquer) Retorna á última ocorrencia ou o último elemento do array.
Descrição
A função tem o objetivo de retornar a última ocorrência do array informado pelo
argumento <aArray>, caso o argumento Array passado esteja vazio a função irá retornar
NIL.
Se for informado um argumento que não for um Array para a função, isto irá causar um
um erro ADVPL.
Ex:
user function tstArray()
Local aArray := {'ola', 'ops', 'oq', 'aff', 'oljha'}
Local cRet
cRet := atail(aArray) //retorna oljha
return cRet
FUNÇÕES TRATAMENTO XML
Sintaxe
XmlChildCount ( < oParent > ) --> nChild
Parâmetros
Argumento Tipo Descrição
Indica o node XML no qual ele irá fazer a contagem dos
oParent Objeto
filhos.
Retorno
Tipo Descrição
Numérico Retorna o numero de elementos encontrados.
Descrição
A função tem o objetivo de retornar a quantidade de nós existentes, a partir de um nodo
pai informado como argumento.
A função não faz essa contagem recursivamente pela estrutura, ou seja, ela nao varre a
estrutura entrando em todos subNodos a partir do elemento passado como raiz para a
contagem e sim apenas os filhos de primeiro nível.
Essa função é util para manipularmos os objetos XML diretamente, sem
necessariamente conhecermos o conteúdo do objeto.
Sintaxe
XmlChildEx ( < OParent > , < cProcura > ) --> retorno
Parâmetros
Argumento Tipo Descrição
Nodo usado para indicar o inicio da procura do elemento
OParent Objeto
requerido.
cProcura Caracter Representa o nome do elemento que desejamos encontrar.
Retorno
Tipo Descrição
Quando a funçao encontrar apenas um elemento será retornado o objeto
(Qualquer) node, caso possua mais de um elemento do mesmo nome irá retornar um
array dos nodes, caso contrário retorna NIL.
Descrição
A função tem o objetivo de retornar um ou mais filhos da estrutura, de acordo com o
nome do elemento procurado.
Especificando um elemento qualquer do objeto para a função, na qual será usado como
base para busca apenas em seu primeiro sub-nível a função irá retornar todos os
nodos filhos que encontar.
É útil quando quando queremos buscar por um elemento filho e exista mais de um
elemento do mesmo tipo.
Sintaxe
XmlCloneNode ( < oParent > , < cNewName > ) --> Nil
Parâmetros
Argumento Tipo Descrição
oParent Objeto Representa o objeto node XML no qual será colando
cNewName Caracter Indica o nome no qual será atribuido o node clonado
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função tem o objetivo de criar um clone, do nó informado pelo parametro,
especificando um novo nome para o elemento, de forma que a função clona apenas o
node, as propriedades não.
Quando o nodo clonado esta com o mesmo nome de um existente, então é criado um
array automaticamente com os nodos.
Ela pode ser utilizada para acrescentarmos dados em um modelo de xml já existente.
Sintaxe
XmlDelNode ( < oParent > , < cNode > ) --> Nil
Parâmetros
Argumento Tipo Descrição
oParent Objeto Representa o Node pai do elemento que será removido.
Representa o Real name do elemento node que será
cNode Caracter
removido.
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função tem o objetivo de deletar um nodo de um objeto xml.
Para isto informamos passando por parametro um elemento do objeto que contém a
estrutura do xml(um nodo qualquer), este nao precisa ser obrigatóriamente o root da
estrutura.
Em seguida informamos o nome do nodo que desejamos deletar, pois a função irá
procurar recursivamente a partir do nodo informado, o elemento que possuí o nome do
nodo a ser deletado dentro da estrutura.
A xmlDelNode irá deletar todos nodos que contenham o nome igual ao do nodo
informado para ser deletado a partir do nodo informado para pesquisa.
A função retorna true caso consiga encontrar um elemento e deleta-lo, false caso
contrário.
Exemplos
Neste exemplo, criamos uma string contendo o xml, em seguida parseamos ele, e agora
vamos deletar um nodo do objeto retornado pela xmlParser, note que no exemplo passei
o nodo '<itens>' como raiz da estrutura a ser pesquisada e queremos deletar o nodo
'<item>', que é elemento de '<itens>'.
A função xmlDelNode tem como objetivo deletar todos os elementos '<item>' que
encontrar dentro da estrutura passada para inicio da pesquisa.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function getObjXML()
Local cError := ""
Local cWarning := ""
Local oXml := NIL
//Gera o Objeto XML
oXml := XmlParser( GeraXML(), "_", @cError, @cWarning )
if !XmlDelNode( oScript:_PEDIDO:_ITENS, "_ITEM" )
conout("Nao foi possivel excluir")
EndIf
// Tranforma o Objeto XML em arquivo ou string
// Grava o arquivo em um diretório \xml a partir do rootPath
SAVE oXml XMLFILE "\xml\[Link]"
Return oXml
// função para gerar uma string contendo um xml
Static Function GeraXML()
Local cScript := '<?xml version="1.0" encoding="UTF-8"?>'
cScript += "<pedido>"
cScript += " <Nome Cliente>Microsiga Software S/A</Nome
Cliente>"
cScript += " <Endereco>Av. Braz Leme</Endereco>"
cScript += " <Numero>1361</Numero>"
cScript += " <Data>22-03-2005</Data>"
cScript += " <Itens>"
cScript += " <Item>"
cScript += " <Produto>Prothues</Produto>"
cScript += " <Quantidade>1</Quantidade>"
cScript += " <Preco>100.00</Preco>"
cScript += " </Item>"
cScript += " <Item>"
cScript += " <Produto>ERP<Produto>"
cScript += " <Quantidade>0</Quantidade>"
cScript += " <Preco>0</Preco>"
cScript += " </Item>"
cScript += " </Itens>"
cScript += "</pedido>"
Return cScript
Sintaxe
XmlGetChild ( ) --> Nil
Retorno
Tipo Descrição
(NULO) Nil
Descrição
A função tem o objetivo de retornar um elemento filho da estrutura.
Especificando um elemento qualquer do objeto para a função, na qual irá usar como
base para retornar o nodo filho de número indicado pelo segundo parametro passado
para a função.
É útil quando queremos mudar o posicionamento do objeto, para algum nodo filho
do atual na estrutura do objeto XML.
No Exemplo seguinte usamos a função para nos posicionar no nodo <itens>, em seguida
apagamos todos os nodos filhos com a xmlDelNode.
Usando o comando SAVE criamos um arquivo [Link] ao final da execução do
programa.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function ExeXML()
Local cError := ""
Local cWarning := ""
Local oScript
Local cFile := ""
//a partir do rootpath do ambiente
cFile := "\xml\[Link]"
//Gera o Objeto XML ref. ao script
oScript := XmlParser( GeraXML(), "_", @cError, @cWarning )
oScript := XmlGetchild( oScript:_PEDIDO ,
XmlChildCount( oScript:_PEDIDO ))
// Agora vou apagar um node
if !XmlDelNode( oScript , "_ITEM" )
conout("Nao foi possivel apagar o nodo")
EndIf
// Tranforma o Objeto XML em arquivo
SAVE oScript XMLFILE "\xml\[Link]"
Return oScript
Static Function GeraXML()
// Script XML a gerar objeto
Local cScript := '<?xml version="1.0" encoding="UTF-8"?>'
cScript += "<pedido>"
cScript += " <Nome Cliente>Microsiga Software S/A</Nome
Cliente>"
cScript += " <Endereco>Av. Braz Leme</Endereco>"
cScript += " <Numero>1361</Numero>"
cScript += " <Data>22-03-2005</Data>"
cScript += " <Itens>"
cScript += " <Item>"
cScript += " <Produto>Prothues</Produto>"
cScript += " <Quantidade>1</Quantidade>"
cScript += " <Preco>100.00</Preco>"
cScript += " </Item>"
cScript += " <Item>"
cScript += " <Produto>ERP<Produto>"
cScript += " <Quantidade>0</Quantidade>"
cScript += " <Preco>0</Preco>"
cScript += " </Item>"
cScript += " </Itens>"
cScript += "</pedido>"
Return cScript
Sintaxe
XmlGetParent ( < oNode > ) --> oParent
Parâmetros
Argumento Tipo Descrição
representa o node no qual será usado como referência para
oNode Objeto
o retorno do node pai.
Retorno
Tipo Descrição
Objeto Um objeto posicionado no node de acordo com o argumento passado.
Descrição
A função tem o objetivo de retornar um nodo que representa o nodo 'pai'
do elemento especificado por parametro.
É útil quando queremos 'subir' na estrutura do objeto XML
Sintaxe
XmlNewNode ( < oParent > , < cElementName > , < cRealName > , < cType > ) --> Nil
Parâmetros
Argumento Tipo Descrição
oParent Objeto Indica o local onde será inserido o novo node XML.
cElementName Caracter É o nome do elemento Node no XML
cRealName Caracter É o nome Real do Node XML
cType Caracter Representa o tipo de node XML que será criado
Retorno
Tipo Descrição
Objeto Nil
Descrição
A função tem o objetivo de criar um novo nodo a partir de um ponto qualquer no xml.
Para isto é necessário informar em qual ponto do objeto xml(o xml parseado) que
desejamos adicionar um novo elemento.
O novo nodo será adicionado como filho do nodo passado por parametro, onde serão
informados também os dados em relação a ele:
-REALNAME
-ELEMENTNAME
-TYPE
(para entender melhor o funcionamento da função veja o exemplo)
Exemplos
Neste exemplo criamos o xml através da função GeraXML, parseamos ele através da
xmlParser retornando o objeto xml.
Em seguida visualizamos o objeto retornado e usamos a funçao xmlChildCount
retornando a quantidade de elementos no objeto contendo o xml. No Nosso exemplo a
função irá retornar 5 elementos.
Agora usaremos a xmlNewNode, especificando que o novo nodo será adicionado como
filho de '<pedido>', logo depois acessamos o nodo e acrecentamos um texto para ele.
obs: o resultado disso no xml será <exemplo1>Exemplo Microsiga</exemplo1>
Após a criação do nodo, a xmlChildCount irá retornar 6 indicando que o nodo foi
inserido.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function getObjXML()
Local cError := ""
Local cWarning := ""
Local cXML := ""
Local oXml := NIL
//Gera o Objeto XML
oXml := XmlParser( GeraXML(), "_", @cError, @cWarning )
//verifica quantos elementos possuo
conout( XmlChildCount( oScript:_PEDIDO ) )
// Criando um node
XmlNewNode(oScript:_PEDIDO, "Exemplo1", "Exemplo1", "NOD" )
//setando o CONTEUDO do meu nodo ""
oXml:_PEDIDO:Exemplo1:Text := "Exemplo Microsiga"
//verifica quantos elementos possuo depois da inserção
conout( XmlChildCount( oScript:_PEDIDO ) )
// Tranforma o Objeto XML em string
SAVE oXml XMLSTRING cXML
Return oXml
// função para gerar uma string contendo um xml
Static Function GeraXML()
Local cScript := '<?xml version="1.0" encoding="UTF-8"?>'
cScript += "<pedido>"
cScript += " <Nome Cliente>Microsiga Software S/A</Nome
Cliente>"
cScript += " <Endereco>Av. Braz Leme</Endereco>"
cScript += " <Numero>1361</Numero>"
cScript += " <Data>22-03-2005</Data>"
cScript += " <Itens>"
cScript += " <Item>"
cScript += " <Produto>Prothues</Produto>"
cScript += " <Quantidade>1</Quantidade>"
cScript += " <Preco>100.00</Preco>"
cScript += " </Item>"
cScript += " <Item>"
cScript += " <Produto>ERP<Produto>"
cScript += " <Quantidade>0</Quantidade>"
cScript += " <Preco>0</Preco>"
cScript += " </Item>"
cScript += " </Itens>"
cScript += "</pedido>"
Return cScript
Sintaxe
XmlNode2Arr ( < oRoot > , < cNode2Array > ) --> lRet
Parâmetros
Argumento Tipo Descrição
Elemento Node no qual será usado como root para inicio
oRoot Objeto
da busca do elemento a ser tranformado em array.
Representa o elemento procurado para ser transformado
cNode2Array Caracter
em array na estrutura.
Retorno
Tipo Descrição
Lógico Retorna true caso consiga transformar em array, false caso contrário.
Descrição
A função tem o objetivo de transformar em array, um objeto(node) da estrutura do xml.
Informando um elemento(node) da estrutura XML através de parametro como raiz, a
função irá procurar pelo nome do nodo no qual se deseja transformar em array.
Exemplos
No exemplo seguinte é demonstrado o simples uso da função XmlNode2Arr, em que
pegamos o objetoXml e o tranformamos em um array.
Em seguida gravamos esse objeto em arquivo .xml propriamente dito.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function ExeXML()
Local cError := ""
Local cWarning := ""
Local oScript
//Gera o Objeto XML ref. ao script
oScript := XmlParser( GeraXML(), "_", @cError, @cWarning )
// Transforma node em uma array, no caso tranforma a estrutura
para array
XmlNode2Arr( oScript:_PEDIDO, "_PEDIDO" )
// Tranforma o Objeto XML em arquivo
// Grava o arquivo em um diretório \xml a partir do rootPath
SAVE oScript XMLFILE "\xml\[Link]"
Return .T.
Static Function GeraXML()
Local cScript := '<?xml version="1.0" encoding="UTF-8"?>'
cScript += "<pedido>"
cScript += " <Nome Cliente>Microsiga Software S/A</Nome
Cliente>"
cScript += " <Endereco>Av. Braz Leme</Endereco>"
cScript += " <Numero>1361</Numero>"
cScript += " <Data>22-03-2005</Data>"
cScript += " <Itens>"
cScript += " <Item>"
cScript += " <Produto>Prothues</Produto>"
cScript += " <Quantidade>1</Quantidade>"
cScript += " <Preco>100.00</Preco>"
cScript += " </Item>"
cScript += " <Item>"
cScript += " <Produto>ERP<Produto>"
cScript += " <Quantidade>0</Quantidade>"
cScript += " <Preco>0</Preco>"
cScript += " </Item>"
cScript += " </Itens>"
cScript += "</pedido>"
Return cScript
Sintaxe
XmlParser ( < cXml > , < cReplace > , < @cError > , < @cWarning > ) --> oXML
Parâmetros
Argumento Tipo Descrição
cXml Caracter É a cadeia de caracteres que contém o código XML.
Representa o valor a ser atribuido para os caracteres de
cReplace Caracter
espaço encontrados na especificação dos nodes XML.
Caso ocorra algum erro durante execução da função, a
cError Caracter
variável será preenchida com a descrição do erro ocorrido.
Caso ocorra algum alerta de 'warning' durante execução da
cWarning Caracter função, a variável será preenchida com a descrição do
'warning' ocorrido.
Retorno
Tipo Descrição
Objeto Representa um objeto com a estrutura de acordo com o XML.
Descrição
A função tem o objetivo de retornar um objeto que possuí uma estrutura referente
ao xml, passado pelo parametro na função.
A estrutura retornada:
<ObjXML>
<NodeXML>
-<ArrayNodes>
-REALNAME
-TEXT
-TYPE
Onde REALNAME, TEXT e TYPE são propriedades que todos nodos possuem.
A propriedade ArrayNodes existirá quando um nodo possuir mais de um filho, do
mesmo tipo. (demonstrado no exemplo)
Exemplos
Neste exemplo criamos uma função geraXml que retorna uma string contento um
XML.
Quando passamos essa string para a XmlParser, a função irá montar o objeto analisando
se a sintaxe e a ordem das tags está bem formada, caso isso nao ocorra a função irá
retonar um warning ou até um possível erro, nos parametros informados por referência.
A estrutura:
oXml:
pedido:
-realName
-type
-text
nome_cliente:
-realName
-type
-text
endereço:
-realName
-type
-text
numero:
-realName
-type
-text
data:
-realName
-type
-text
itens:
-item <- (array)
-item[1]:
-realName
-type
-text
produto:
quantidade:
preco:
-item[2]
-realName
-type
-text
produto:
quantidade:
preco:
-realName
-type
-text
Caso isso nao ocorra a função irá retornar o objeto contendo uma estrutura em forma de
arvore, no caso a mesma estrutura do xml.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function getObjXML()
Local cError := ""
Local cWarning := ""
Local cXML := ""
Local oXml := NIL
//Gera o Objeto XML
oXml := XmlParser( GeraXML(), "_", @cError, @cWarning )
//acessando o CONTEUDO do meu nodo ""
oXml:_PEDIDO:_NOME_CLIENTE:Text := "Microsiga"
// Tranforma o Objeto XML em string
//SAVE oXml XMLSTRING cXML
Return oXml
// função para gerar uma string contendo um xml
Static Function GeraXML()
Local cScript := '
Sintaxe
XmlParserFile ( < cFile > , < cReplace > , < @cError > , < @cWarning > ) --> oXML
Parâmetros
Argumento Tipo Descrição
Representa o path de um arquivo .xml, indicando o local
cFile Caracter
onde se encontra o arquivo no disco.
Representa o valor a ser atribuido para os caracteres de
cReplace Caracter
espaço encontrados na especificação dos nodes XML.
cError Caracter Caso ocorra algum erro durante execução
cError Caracter da função, a variável será preenchida com a descrição do
erro ocorrido.
cWarning Array Caso ocorra algum alerta de 'warning'
cWarning Caracter durante execução da função, a variável será preenchida
com a descrição do 'warning' ocorrido.
Retorno
Tipo Descrição
Objeto Retorna um objeto q contém uma estrutura de acordo com o XML.
Descrição
A função tem o objetivo de retornar um objeto que possuí uma estrutura referente ao
arquivo .xml, passado pelo parametro na função.
A estrutura retornada:
<ObjXML>
<NodeXML>
-<ArrayNodes>
-REALNAME
-TEXT
-TYPE
Onde REALNAME, TEXT e TYPE são propriedades que todos nodos possuem.
A propriedade ArrayNodes existirá quando um nodo possuir mais de um filho, do
mesmo tipo. (demonstrado no exemplo)
Exemplos
Neste exemplo vamos usar a função que tem o mesmo objetivo da XmlParser, a
diferença é que esta lê um arquivo do disco com a extensão .xml.
Quando passamos a string informando o path do arquivo em disco, devemos lembrar
que a procura do arquivo será feita através do rootpath do Protheus.
logo após a leitura do arquivo a função irá montar o objeto analisando se a sintaxe e a
ordem das tags está bem formada, caso isso não ocorra a função irá retonar um warning
ou até um possível erro, nos parametros informados por referência.
Caso isso nao ocorra a função irá retornar o objeto contendo uma estrutura em forma de
arvore, no caso a mesma estrutura do xml.
#INCLUDE "[Link]"
#INCLUDE "[Link]"
User Function getObjXML()
Local cError := ""
Local cWarning := ""
Local oXml := NIL
Local cFile := ""
//a partir do rootpath do ambiente
cFile := "\xml\[Link]"
//Gera o Objeto XML
oXml := XmlParserFile( cFile, "_", @cError, @cWarning )
//acessando o CONTEUDO do meu nodo ""
oXml:_PEDIDO:_NOME_CLIENTE:Text := "Microsiga"
Return oXml
INFORMAÇÕES ADICIONAIS
ARREDONDAMENTO
No Protheus, pode haver diferença de arredondamento em algumas operações
numéricas. Isso ocorre devido a diferenças no armazenamento de variáveis numéricas
nos diversos processadores. Diferença esta, inclusive, presente no Advpl, mesmo antes
do surgimento do Protheus.
Para evitar esses problemas de arredondamento, utilize a função 'Round', principalmente
antes de realizar uma comparação, e antes de utilizar a função 'Int'. Desse
modo, assegura-se que o resultado será correto independentemente do processador /
plataforma.
Exemplos:
1. If (Valor/30) = 50 // pode ser falso ou inválido
If Round(Valor/30, 0) = 50 // correto
2. M->EE8_QTDEM1:= Int (M->EE8_SLDINI/M->EE8_QE) // pode ser
falso ou inválido
M->EE8_QTDEM1:= Int (Round(M->EE8_SLDINI/M->EE8_QE, 10)) //
correto
CRIAÇÃO DE CLASSES
Podemos criar Classes próprias em Advpl ; bastando para tal nos utilizarmos dos
comandos de declaração de Classes , Métodos e Propriedades do Protheus. Veja abaixo
um modelo simples que exemplifica a utilização e declaração de uma Classe de
Exemplo utilizando Advpl:
#INCLUDE "[Link]"
// Crio uma função para teste da Classe Exemplo
Function u_teste()
Local oSoma1 := Exemplo():New() // Crio um novo objeto de exemplo
( objeto 1 )
Local oSoma2 := Exemplo():New() // Crio outro objeto de exemplo
( objeto 2 )
// Realizo 3 chamadas ao método Soma, com o objeto 1
oSoma1:Soma(10)
oSoma1:Soma(20)
oSoma1:Soma(30)
// Realizo 2 chamadas ao método Soma, com o objeto 2
oSoma2:Soma(30)
oSoma2:Soma(30)
// Imprimo no console o acumulador das somas do obj 1 ( 60 )
conout(oSoma1:nAcumulador)
// Imprimo no console o acumulador das chamadas à soma com o objeto 1
( 3 )
conout(oSoma1:nChamadas)
// Imprimo no console o acumulador das somas do obj 2 ( 60 )
conout(oSoma2:nAcumulador)
// Imprimo no console o acumulador das chamadas à soma com o objeto 2
(2)
conout(oSoma2:nChamadas)
Return
//
----------------------------------------------------------------------
----------
// Declaracao da Classe Exemplo
//
----------------------------------------------------------------------
----------
CLASS Exemplo
// Declaracao das propriedades da Classe
DATA nAcumuladorDATA nChamadas
// Declaração dos Métodos da Classe
METHOD New() CONSTRUCTORMETHOD Soma( nNum )
ENDCLASS
// Criação do construtor, onde atribuimos os valores default
// para as propriedades e retornamos Self
METHOD New() Class Exemplo
::nAcumulador := 0
::nChamadas := 0
Return Self
// Criação do Método de Soma , que recebe um número e o soma
// ao acumulador, retornando o conteudo do acumululador após
// a soma , e incrementa em 1 o contador de chamadas do método
METHOD Soma( nNum ) Class Exemplo
::nAcumulador += nNum
::nChamadas++
Return ::nAcumulador
Podemos utilizar os outros tipos de variáveis Advpl nas Classes , como variáveis Locais
, Private , Static , etc... Para acessarmos uma propriedade da classe atual , devemos
prefixá-la com :: ( dois sinais de 2 pontos )
Ao declarar um objeto utilizando o construtor da classe , utilizamos a sintaxe :
oObjeto := NomeDaClasse():Metodo_Contrutor(). Para acessar uma propriedade deste
objeto , utilizamos oObjeto:Propriedade , e para acessar um método da classe aplicável
a este objeto , utilizamos oObjeto:Metodo( parametros,... )
PALAVRAS RESERVADAS
Lista de Palavras Reservadas
AADD DTOS INKEY REPLICATE VAL
ABS ELSE INT RLOCK VALTYPE
ASC ELSEIF LASTREC ROUND WHILE
AT EMPTY LEN ROW WORD
BOF ENDCASE LOCK RTRIM YEAR
BREAK ENDDO LOG SECONDS CDOW
ENDIF LOWER SELECT CHR EOF
LTRIM SETPOS CMONTH EXP MAX
SPACE COL FCOUNT MIN SQRT
CTOD FIELDNAME MONTH STR DATE
FILE PCOL SUBSTR DAY FLOCK
PCOUNT TIME DELETED FOUND PROCEDURE
TRANSFORM DEVPOS FUNCTION PROW TRIM
DOW IF RECCOUNT TYPE DTOC
IIF RECNO UPPER
Novas Palavras Reservadas
A partir das versões Protheus Ap5 - Build 7.00.030702 , Ap6 - Build
7.00.030702 e Ap7 - Build 7.00.030702 , as palavras abaixo passaram a ser
reservadas:
TRY AS CATCH THROW
Notas:
Palavras reservadas não podem ser utilizadas para variáveis, procedimentos, ou
funções.
Funções reservadas são pertencentes ao compilador e portanto não podem ser
redefinidas por uma aplicação.
Abreviações de quatro letras de palavras reservadas e funções também são
reseravdas.
Todos os identifadores que começarem com um ou mais caracters de sublinhado
(_) são utilizados como identificadores internos e portanto são também
reservados.
TABELAS DE PICTURES DE FORMATAÇÃO
Comando SAY/PSAY
Funções
Conteudo Funcionalidade
C Exibe CR depois de números positivos
E Exibe numéricos com o ponto e a vírgula invertidos (formato Europeu)
R Insere caracteres diferentes dos caracteres de template
X Exibe DB depois de números negativos
Z Exibe zeros como brancos
( Envolve números negativos entre parênteses
! Converte todos os carecteres alfabáticos para maiúsculo
Templates
Conteudo Funcionalidade
X Exibe dígitos para qualquer tipo de dado
9 Exibe dígitos para qualquer tipo de dado
# Exibe dígitos para qualquer tipo de dado
! Converte caracteres alfabéticos para maiúsculo
* Exibe asterisco no lugar de espaços em branco inicias em números
. Exibe a posição do ponto decimal
, Exibe a posição do milhar
Comando GET
Funções
Conteudo Funcionalidade
A Permite apenas caracteres alfabéticos
C Exibe CR depois de números positivos
E Exibe numéricos com o ponto e vírgula invertidos (formato Europeu)
Insere caracteres diferentes dos caracteres de template na exibição mas não
R
insere-os na variável do GET
Permite rolamento horizontal do texto dentro do GET, <n> é um número
S<n>
inteiro que identifica o tamanho da região
X Exibe DB depois de números negativos
Z Exibe zeros como brancos
( Exibe números negativos entre parênteses com os espaços em branco iniciais
) Exibe números negativos entre parênteses sem os espaços em branco iniciais
! Converte caracteres alfabéticos para maiúsculo
Templates
Conteudo Funcionalidade
X Permite qualquer caractere
Permite apenas dígitos para qualquer tipo de dado, incluindo o sinal para
9
numéricos
# Permite dígitos, sinais e espaços em branco para qualquer tipo de dado
! Converte caracteres alfabéticos para maiúsculo
* Exibe um asterisco no lugar dos espaços em branco iniciais em números
. Exibe o ponto decimal
, Exibe a posição do milhar
TÉCNICAS DE PROGRAMAÇÃO EFICIENTE
Para o desenvolvimento de sistemas e a programação de rotinas, sempre é esperado que
qualquer código escrito seja:
de correto funcionamento
eficiente
legível
reutilizável
extensível
portável
Após anos de experiência na utilização de linguagens padrão xBase e do
desenvolvimento da linguagem AdvPl, algumas técnicas para uma programação
otimizada e eficiente foram reconhecidas. A utilização das técnicas a seguir, visa buscar
o máximo aproveitamento dos recursos da linguagem com o objetivo de criar programas
com estas características.
Criação de Funções Segundo a Necessidade
Observe o código de exemplo:
User Function GetAnswer(lDefault)
Local lOk
lOk := GetOk(lDefault)
If lOk
Return .T.
Else
Return .F.
Endif
Return nil
Utilizando-se apenas o critério "a função funciona corretamente?", a função GetAnswer
é perfeita. Recebe um parâmetro lógico com a resposta padrão e retorna um valor lógico
dependente da opção escolhida pelo usuário em uma função de diálogo "sim/não"
designada para isso. Pode entretanto ser melhorada, particularmente se eficiência for
considerada como um critério para um código melhor. Eficiência tipicamente involve a
utilização de poucos recursos de máquina, poucos chamadas de funções ou tornar mais
rápido um processo.
Segundo esse raciocínio, poderia se produzir o seguinte código:
User Function GetAnswer(lDefault)
Return If( GetOk(lDefault), .T., .F.)
Ou melhor:
User Function GetAnswer(lDefault)
Return GetOk(lDefault)
Com a otimização do código da função GetAnswer, pode facilmente verificar que a
mesma não realiza nada adicional à chamada de GetOk, podendo ser substituída por
uma chamada direta desta, continuando a funcionar corretamente.
Codificação Auto-Documentável
Nenhum comentário substitui um código claramente escrito, e este não é um um
acidente. Considere o exemplo:
cVar := " " // 11 espaços
O tamanho da variável cVar não é evidente por si só e não é facilmente verificado. Estes
mesmos 10 espaços estariam mais óbvios e ainda assim garantidos se a instrução fosse
escrita como:
cVar := Space(11)
O mesmo princípio pode ser aplicado para qualquer string longa de caracteres repetidos.
A função Replicate pode ser utilizada como a seguir:
cVar := Replicate( "*", 80 )
Este tipo de programação deixa o código fácil de digitar, fácil de ler e mais flexível.
Utilização de Soluções Simples
Simplicidade na criação de instruções torna a programação e até mesmo a execução
mais rápida. Considere a linha de código:
If nVar > 0 .Or. nVar < 0
Se o valor da variável nVar for igual a zero (0) no momento da execução desta linha de
código, ambas as comparações separadas pelo operador lógico .Or. serão efetuadas:
Após ser avaliada, a primeria comparação irá falhar. A segunda comparação será então
avaliada e falhará também. Como resultado, o código existente dentro da estrutura de
fluxo If não será executado. Tal código somente será executado quando o valor desta
variável for maior OU menor do que zero. Ou seja, sempre que for DIFERENTE de
zero, o que torna a linha a seguir mais eficiente:
If nVar != 0
Este tipo de alteração torna o código mais legível e o processamento mais rápido,
evitando a avaliação de instruções desnecessariamente.
Existem outras situações onde a simplificação pode ser utilizada. A expressão de
avaliação a seguir:
If cVar == "A" .Or. cVar == "B" .Or ;
cVar == "C" .Or. cVar == "D"
Pode ser substituído pelo operador de contenção:
If cVar $ "ABCD"
Opção por Flexibilidade
A melhor solução é aquela que envolve o problema imediato e previne problemas no
futuro. Considere o exemplo:
@nRow,nCol PSAY cVar Picture "!!!!!!!!!!!!!!!!!!!!"
Exceto contando-se os caracteres, não existe maneira de saber se o número de caracteres
de exclamação é o esperado. Enquanto isto é um problema, existem algo mais grave. A
expressão de picture é estática. Se no futuro for necessário ajustar o tamanho da variável
cVar, será necessário localizar todos os lugares no código onde esta máscara de picture
está sendo utilizada para ajuste manual. Existe uma opção dsolução de de auto-ajuste
disponível que é fácil de digitar e tem a garantia de executar a tarefa igualmente (tornar
todos os caracteres maiúsculos):
@nRow,nCol PSAY cVar Picture "@!"
Opção da Praticidade ao Drama
Se a solução parece complexa, provavelmente é porque o caminho escolhido está
levando a isso. Deve-se sempre se perguntar porque alguém desenvolveria uma
linguagem que requisite tantos comandos complicados para fazer algo simples. Na
grande maioria dos casos, existe uma solução mais simples. O exemplo abaixo deixa
isso bem claro:
@ 10,25 Say Substr(cCep,1,5) + "-" + Substr(cCep,6,3) Picture
"!!!!!!!!!"
Que pode ficar mais simples assim:
@ 10,25 Say cCep Picture "@R 99999-999"
Utilização de Operadores de Incremento/Decremento
Utilizados devidamente, os operadores de incremento e decremento tornam o código
mais fácil de ler e possivelmente um pouco mais rápidos. Ao contrário de escrever
adições simples como:
nVar := nVar + 1
nVar := nVar -1
Pode-se escrevê-las assim:
++nVar
--nVar
Deve-se apenas tomar cuidado com a precedência destes operadores, pois o "++" ou o
"--" podem aparecer antes ou depois de uma variável, e em alguns casos quando a
variável for utilizada dentro de uma expressão, a prefixação ou sufixação destes
operadores afetará o resultado. Para maiores detalhes, consulte a documentação de
operadores da linguagem AdvPl.
Evitar Passos Desnecessários
Existe uma diferença entre um bom hábito e perda de tempo. Algumas vezes estes
conceitos podem estar muito próximos, mas um modo de diferenciá-los é balancear os
benefícios de realizar alguma ação contra o problema que resultaria se não fosse
executada. Observe o exemplo:
Local nCnt := 0
For nCnt := 1 To 10
<código>
Next nCnt
Inicializar a variável no momento da declaração não é um problema. Se o 0 fosse
necessário no exemplo, teria sido útil a inicialização na declaração. Mas neste caso a
estrutura de repetição For... Next atribui o seu valor imediatamente com 1, portanto não
houve ganho em atribuir a variável com 0 no começo.
Neste exemplo não há nenhum ponto negativo e nada errado ocorrerá se a variável não
for inicializada, portanto é aconselhável evitar este tipo de inicialização, pois não torna
o código mais seguro e também não expressa a intenção do código mais claramente.
Porém note este exemplo, onde a variável não é inicializada:
Local nCnt
While ( nCnt++ < 10 )
<código>
EndDo
Em AdvPl, variáveis não inicializadas sempre tem seu valor contendo nulo (nil) a
princípio, o que fará com que uma exceção em tempo de execução aconteça quando a
instrução de repetição while for executada.
Diferentemente do primeiro exemplo, onde a inicialização da variável não fazia
diferença alguma, neste segundo exemplo a inicialização é absolutamente necessária.
Deve-se procurar inicializar variáveis numéricas com zero (0) e variáveis caracter com
string nula ("") apenas quando realmente necessário.
Utilização de Alternativas
Quando se está trabalhando em uma simples rotina, deve-se tomar algum tempo para
explorar duas ou três diferentes abordagens. Quando se está trabalhando em algo mais
complexo, deve-se planejar prototipar algumas a mais. Considere o seguinte código:
If cHair = "A"
Replace hair With "Loira"
Else
If cHair = "B"
Replace hair With "Morena"
Else
If cHair = "C"
Replace hair With "Ruiva"
Else
If cHair = "D"
Replace hair With "Grisalho"
Else
Replace hair With "Preto"
Endif
Endif
Endif
Endif
Um código de uma única letra, (A até E), foi informado para indicar a
cor de cabelo. Este código foi então convertido e armazenado como uma
string. Pode-se notar que a cor "Preto" será atribuída se nenhuma
outra opção for verdadeira.
Uma alternativa que reduz o nível de identação torna o código mais
fácil de ler enquanto reduz o número de comandos replace:
Do Case
Case cHair == "A"
cColor := "Loira"
Case cHair == "B"
cColor := "Morena"
Case cHair == "C"
cColor := "Ruiva"
Case cHair == "D"
cColor := "Grisalho"
OtherWise
cColor := "Preto"
EndCase
Replace hair With cColor
Utilização de Arquivos de Cabeçalho
Quando Necessário
Se um arquivo de código criado se referencia a comandos para
interpretação e tratamento de arquivos XML, este deve se incluir o
arquivo de cabeçalho próprio para tais comandos ([Link] no
exemplo). Porém não deve-se incluir arquivos de cabeçalho apenas por
segurança. Se não se está referenciando nenhuma das constantes ou
utilizando nenhum dos comandos contidos em um destes arquivos, a
inclusão apenas tornará a compilação mais demorada.
Constantes em Maiúsculo
Isto é uma convenção que faz sentido. Em AdvPl, como em C por exemplo,
a regra é utilizar todos os caracteres de uma constante em maiúsculo,
a fim de que possam ser claramente reconhecidos como constantes no
código, e que não seja necessários lembrar onde foram declarados.
Utilização de Identação
Este é um hábito que todo programador deve desenvolver. Não consome
muito esforço para manter o código alinhado durante o trabalho, porém
quando necessário pode-se utilizar AP6 IDE para a reidentação de
código.
Considere o exemplo:
While !SB1->(Eof())
If mv_par01 = SB1->B1_COD
dbSkip()
Loop
Endif
Do Case
Case SB1->B1_LOCAL == "01" .Or. SB1->B1_LOCAL == "02"
TrataLocal(SB1->B1_COD,SB1->B1_LOCAL)
Case SB1->B1_LOCAL == "03"
TrataDefeito(SB1->B1_COD)
OtherWise
TrataCompra(SB1->B1_COD,SB1->B1_LOCAL)
EndCase
dbSkip()
EndDo
A utilização da identação seguindo as estruturas de controle de fluxo
(while, if, case, etc) torna a compreensão do código muito mais fácil:
While !SB1->(Eof())
If mv_par01 = SB1->B1_COD
dbSkip()
Loop
Endif
Do Case
Case SB1->B1_LOCAL == "01" .Or. SB1->B1_LOCAL == "02"
TrataLocal(SB1->B1_COD,SB1->B1_LOCAL)
Case SB1->B1_LOCAL == "03"
TrataDefeito(SB1->B1_COD)
OtherWise
TrataCompra(SB1->B1_COD,SB1->B1_LOCAL)
EndCase
dbSkip()
EndDo
Utilização de Espaços em Branco
Espaços em branco extras tornam o código mais fácil para a leitura.
Não é necessário imensas áreas em branco, mas agrupar pedaços de
código através da utilização de espaços em branco funciona muito bem.
Costuma-se separar parâmetros com espaços em branco.
Quebra de Linhas Muito Longas
Com o objetivo de tornar o código mais fácil de ler e imprimir, as
linhas do código não devem estender o limite da tela ou do papel.
Podem ser "quebradas" em mais de uma linha de texto utilizando o
ponto-e-vírgula (;).
Capitulação de Palavras-Chave
Uma convenção amplamente utilizada é a de capitular as palavras
chaves, funções, variáveis e campos utilizando uma combinação de
caracteres em maiúsculo e minúsculo, visando facilitar a leitura do
código fonte. O código a seguir:
local ncnt
while ( ncnt++ < 10 )
ntotal += ncnt * 2
enddo
Ficaria melhor com as palavras chaves e variáveis capituladas:
Local nCnt
While ( nCnt++ < 10 )
nTotal += nCnt * 2
EndDo
Utilização da Notação Húngara
A Notação Húngara é muito comum entre programadores xBase e de outras
linguagens. A documentação do AdvPl utiliza esta notação para a
descrição das funções e comandos e é aconselhável sua utilização na
criação de rotinas, pois ajuda a evitar pequenos erros e facilita a
leitura do código. Para maiores detalhes, consulte a documentação
sobre a Notação Húngara disponível na documentação da linguagem AdvPl.
Utilização de Nomes Significantes para
Variáveis
A principal vantagem da liberdade na criação dos nomes de variáveis é
a facilidade de identificação da sua utilidade. Portanto deve-se
utilizar essa facilidade o máximo possível. Nomes sem sentido apenas
tornarão difícil a identificação da utilidade de uma determinada
variável, assim como nomes extremamente curtos. Nem sempre a
utilização de uma variável chamada i é a melhor saída. Claro, não
convêm criar uma variável com um nome muito longo que será utilizada
como um contador, e referenciada muitas vezes no código. O bom senso
deve ser utilizado.
Criar variáveis como nNumero ou dData também não ajudam na
identificação. A Notação Húngara já está sendo utilizada para isso e o
objetivo do nome da variável deveria ser identificar sua utilização,
não o tipo de dado utilizado. Deve-se procurar substituir tais
variáveis por algo como nTotal ou dCompra.
O mesmo é válido para nomes de funções, que devem descrever um pouco
sobre o que a função faz. Novamente nomes extremamente curtos não são
aconselháveis.
Utilização de Comentários
Comentários são muito úteis na documentação de programas criados e
para facilitar a identificação de processos importantes no futuro.
Devem sempre ser utilizados.
Sempre que possível, funções criadas devem ter uma breve descrição do
seu objetivo, parâmetros e retorno. Além de servir como documentação,
os comentários embelezam o código ao separar as funções umas das
outras.
Os comentários devem ser utilizados com bom senso, pois reescrever a
sintaxe AdvPl em português torna-se apenas perda de tempo:
#EX
If nLastKey == 27 // Se o nLastKey for igual a 27
#EX
Criação de Mensagens Sistêmicas
Significantes e Consistentes
Seja oferecendo assistência, exibindo mensagens de aviso ou mantendo o
usuário informado do estado de algum processo, as mensagens devem
refletir o tom geral e a importância da aplicação. Em termos gerais,
deve-se evitar ser muito informal e ao mesmo tempo muito técnico.
#EX
"Aguarde. Reindexando (B1_FILIAL+B1_COD+B1_LOCAL) do arquivo: \
DADOSADV\[Link]"
#/EX
Esse tipo de mensagem pode dar informações demais para o usuário e
deixá-lo sentindo-se desconfortável se não souber o que significa
"reindexando", etc. E de fato, o usuário não devia ser incomodado com
tais detalhes. Apenas a frase "Aguarde, indexando." funcionaria
corretamente, assim como palavras "processando" ou "reorganizando".
Outra boa idéia é evitar a referencia a um item corrente de uma tabela
como um "registro":
#EX
"Deletar este registro?"
#/EX
Se a operação estiver sendo efetuada em um arquivo de clientes, o
usuário deve ser questionado sobre a remoção do cliente corrente, se
possível informando valores de identificação como o código ou o nome.
Evitar Abreviação de Comandos em 4
letras
Apesar do AdvPl suportar a abreviação de comandos em quatro letras
(por exemplo, repl no lugar de replace) não há necessidade de utilizar
tal funcionalidade. Isto apenas torna o código mais difícil de ler e
não torna a compilação mais rápida ou simples.
Evitar "Disfarces" no Código
Não deve-se criar constantes para expressões complexas. Isto tornará o
código muito difícil de compreender e poderá causar erros primários,
pois pode-se imaginar que uma atribuição é efetuada a uma variável
quando na verdade há toda uma expressão disfarçada:
#define NUMLINES aPrintDefs[1]
#define NUMPAGES aPrintDefs[2]
#define ISDISK aReturn[5]
If ISDISK == 1
NUMLINES := 55
Endif
NUMPAGES += 1
A impressão que se tem após uma leitura deste código é de que valores
estão sendo atribuidos às variáveis ou que constantes estão sendo
utilizadas. Se o objetivo é flexibilidade, o código anterior deve ser
substituído por:
#define NUMLINES 1
#define NUMPAGES 2
#define ISDISK 5
If aReturn[ISDISK] == 1
aPrintDefs[ NUMLINES ] := 55
Endif
aPrintDefs[ NUMPAGES ] += 1
Evitar Código de Segurança
Desnecessário
Dada sua natureza binária, tudo pode ou não acontecer dentro de um
computador. Adicionar pedaços de código apenas para "garantir a
segurança" é freqüentemente utilizado como uma desculpa para evitar
corrigir o problema real. Isto pode incluir a checagem para validar
intervalos de datas ou para tipos de dados corretos, o que é comumente
utilizando em funções:
Static Function MultMalor( nVal )
If ValType( nVal ) != "N"
nVal := 0
Endif
Return ( nVal * nVal )
O ganho é irrisório na checagem do tipo de dado do parâmetro já que
nenhum programa corretamente escrito em execução poderia enviar uma
string ou uma data para a função. De fato, este tipo de "captura" é o
que torna a depuração difícil, já que o retorno será sempre um valor
válido (mesmo que o parâmetro recebido seja de tipo de dado
incorreto). Se esta captura não tiver sido efetuada quando um
possível erro de tipo de dado inválido ocorrer, o código pode ser
corrigido para que este erro não mais aconteça.
Isolamento de Strings de Texto
No caso de mensagens e strings de texto, a centralização é um bom
negócio. Pode-se colocar mensagens, caminhos para arquivos, e mesmo
outros valores em um local específico. Isto os torna acessíveis de
qualquer lugar no programa e fáceis de gerenciar.
Por exemplo, se existe uma mensagem comum como "Imprimindo, por favor
aguarde..." em muitas partes do código, corre-se o risco de não seguir
um padrão para uma das mensagens em algum lugar do código. E mantê-las
em um único lugar, como um arquivo de cabeçalho, torna fácil a
produção de documentação e a internacionalização em outros idiomas.
SINTAXE DE LINGUAGEM
Criacäo de um Programa
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Um programa de computador nada mais é do que um grupo de comandos logicamente
dispostos com o objetivo de executar determinada tarefa. Esses comandos são gravados
em um arquivo texto que é transformado em uma linguagem executável por um
computador através de um processo chamado compilação. A compilação substitui os
comandos de alto nível (que os humanos compreendem) por instruções de baixo nível
(compreendida pelo sistema operacional em execução no computador). No caso do
AdvPl, não é o sistema operacional de um computador que irá executar o código
compilado, mas sim o AP6 Server.
Dentro de um programa, os comandos e funções utilizados devem seguir regras de
sintaxe da linguagem utilizada, pois caso contrário o programa será interrompido por
erros. Os erros podem ser de compilação ou de execução.
Erros de compilação são aqueles encontrados na sintaxe que não permitem que o
arquivo de código do programa seja compilado. Podem ser comandos
especificados de forma errônea, utilização inválida de operadores, etc.
Erros de execução são aqueles que acontecem depois da compilação, quando o
programa está sendo executado. Podem ocorrer por inúmeras razões, mas
geralmente se referem a funções não existentes, ou variáveis não criadas ou
inicializadas, etc.
Linhas de Programa
As linhas existentes dentro de um arquivo texto de código de programa podem ser
linhas de comando, linhas de comentário ou linhas mistas.
Linhas de Comando
Linhas de comando possuem os comandos ou instruções que serão executadas. Por
exemplo:
Local nCnt
Local nSoma := 0
For nCnt := 1 To 10
nSoma += nCnt
Next nCnt
Linhas de Comentário
Linhas de comentário possuem um texto qualquer, mas não são executadas. Servem
apenas para documentação e para tornar mais fácil o entendimento do programa.
Existem três formas de se comentar linhas de texto. A primeira delas é utilizar o sinal de
* (asterisco) no começo da linha:
* Programa para cálculo do total
* Autor: Microsiga Software S.A.
* Data: 2 de outubro de 2001
Todas as linhas iniciadas com um sinal de asterisco são consideradas como comentário.
Pode-se utilizar a palavra NOTE ou dois símbolos da letra "e" comercial (&&) para
realizar a função do sinal de asterisco. Porém todas estas formas de comentário de
linhas são obsoletas e existem apenas para compatibilização com o padrão xBase. A
melhor maneira de comentar linhas em AdvPl é utilizar duas barras transversais:
// Programa para cálculo do total
// Autor: Microsiga Software S.A.
// Data: 2 de outubro de 2001
Outra forma de documentar textos é utilizar as barras transversais juntamente com o
asterisco, podendo-se comentar todo um bloco de texto sem precisar comentar linha a
linha:
/*
Programa para cálculo do total
Autor: Microsiga Software S.A.
Data: 2 de outubro de 2001
*/
Todo o texto encontrado entre a abertura (indicada pelos caracteres /*) e o fechamento
(indicada pelos caracteres */) é considerado como comentário.
Linhas Mistas
O AdvPl também permite que existam linhas de comando com comentário. Isto é
possível incluíndo-se as duas barras transversais (//) ao final da linha de comando e
adicionando-se o texto do comentário:
Local nCnt
Local nSoma := 0 // Inicializa a variável com zero para a soma
For nCnt := 1 To 10
nSoma += nCnt
Next nCnt
Tamanho da Linha
Assim como a linha física, delimitada pela quantidade de caracteres que pode ser
digitado no editor de textos utilizado, existe uma linha considerada linha lógica. A linha
lógica, é aquela considerada para a compilação como uma única linha de comando.
A princípio, cada linha digitada no arquivo texto é diferenciada após o pressionamento
da tecla <Enter>. Ou seja, a linha lógica, é a linha física no arquivo. Porém algumas
vezes, por limitação física do editor de texto ou por estética, pode-se "quebrar" a linha
lógica em mais de uma linha física no arquivo texto. Isto é efetuado utilizando-se o sinal
de ponto-e-vírgula (;).
If !Empty(cNome) .And. !Empty(cEnd) .And. ; <enter>
!Empty(cTel) .And. !Empty(cFax) .And. ; <enter>
!Empty(cEmail)
GravaDados(cNome,cEnd,cTel,cFax,cEmail)
Endif
Neste exemplo existe uma linha de comando para a checagem das variáveis utilizadas.
Como a linha torna-se muito grande, pode-se dividí-la em mais de uma linha física
utilizando o sinal de ponto-e-vírgula. Se um sinal de ponto-e-vírgula for esquecido nas
duas primeiras linhas, durante a execução do programa ocorrerá um erro, pois a segunda
linha física será considerada como uma segunda linha de comando na compilação. E
durante a execução esta linha não terá sentido.
Estrutura de um Programa
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Apesar de não ser uma linguagem de padrões rígidos com relação à estrutura do
programa, é importante identificar algumas de suas partes. Considere o programa de
exemplo abaixo:
/*
+===========================================+
| Programa: Cálculo do Fatorial |
| Autor : Microsiga Software S.A. |
| Data : 02 de outubro de 2001 |
+===========================================+
*/
Local nCnt
Local nResultado := 1 // Resultado do fatorial
Local nFator := 5 // Número para o cálculo
// Cálculo do fatorial
For nCnt := nFator To 1 Step -1
nResultado *= nCnt
Next nCnt
// Exibe o resultado na tela, através da função alert
Alert("O fatorial de " + cValToChar(nFator) + ;
" é " + cValToChar(nResultado))
// Termina o programa
Return
Pode-se classificar um programa em AdvPl em quatro partes básicas:
Área de Identificação
Área de Ajustes Iniciais
Corpo do Programa
Área de Encerramento
A Área de Identificação
Esta é uma área que não é obrigatória e é dedicada a documentação do programa.
Quando existente, contém apenas comentários explicando a sua finalidade, data de
criação, autor, etc, e aparece no começo do programa, antes de qualquer linha de
comando.
O formato para esta área não é definido. Pode-se colocar qualquer tipo de informação
desejada e escolher a formatação apropriada.
/*
+==========================================+
| Programa: Cálculo do Fatorial |
| Autor : Microsiga Software S.A. |
| Data : 02 de outubro de 2001 |
+==========================================+
*/
Opcionalmente pode-se incluir definições de constantes utilizadas no programa ou
inclusão de arquivos de cabeçalho nesta área.
A Área de Ajustes Iniciais
Nesta área geralmente se fazem os ajustes iniciais, importantes para o correto
funcionamento do programa. Entre os ajustes se encontram declarações de variáveis,
inicializações, abertura de arquivos, etc. Apesar do AdvPl não ser uma linguagem rígida
e as variáveis poderem ser declaradas em qualquer lugar do programa, é aconselhável
fazê-lo nesta área visando tornar o código mais legível e facilitar a identificação de
variáveis não utilizadas.
Local nCnt
Local nResultado := 0 // Resultado do fatorial
Local nFator := 10 // Número para o cálculo
O Corpo do Programa
É nesta área que se encontram as linhas de código do programa. É onde se realiza a
tarefa necessária através da organização lógica destas linhas de comando. Espera-se que
as linhas de comando estejam organizadas de tal modo que no final desta área o
resultado esperado seja obtido, seja ele armazenado em um arquivo ou em variáveis de
memória, pronto para ser exibido ao usuário através de um relatório ou na tela.
// Cálculo do fatorial
For nCnt := nFator To 1 Step -1
nResultado *= nCnt
Next nCnt
A Área de Encerramento
É nesta área onde as finalizações são efetuadas. É onde os arquivos abertos são
fechados, e o resultado da execução do programa é utilizado. Pode-se exibir o resultado
armazenado em uma variável ou em um arquivo ou simplesmente finalizar, caso a tarefa
já tenha sido toda completada no corpo do programa. É nesta área que se encontra o
encerramento do programa. Todo programa em AdvPl deve sempre terminar com a
palavra chave return.
// Exibe o resultado na tela, através da função alert
Alert("O fatorial de " + cValToChar(nFator) + ;
" é " + cValToChar(nResultado))
// Termina o programa
Return
Controlando o Fluxo
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
O AdvPl suporta várias estruturas de controle que permitem mudar a seqüência de fluxo
de execução de um programa. Estas estruturas permitem a execução de código baseado
em condições lógica e a repetição da execução de pedaços de código qualquer número
de vezes.
Em AdvPl, todas as estruturas de controle podem ser "aninhadas" dentro de todas as
demais estruturas contanto que estejam aninhadas propriamente. Estruturas de controle
têm um identificador de início e um de fim, e qualquer estrutura aninhada deve se
encontrar entre estes identificadores.
Também existem estruturas de controle para determinar que elementos, comandos, etc
em um programa serão compilados. Estas são as diretivas do pré-processador
#ifdef...#endif e #ifndef...#endif. Consulte a documentação sobre o pré-processador para
maiores detalhes.
As estruturas de controle em AdvPl estão divididas em :
Estruturas de Repetição
Estruturas de Decisão.
Desviando a Execucäo
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Estruturas de desvio são deseginadas para executar uma seção de código se determinada
condição lógica resultar em verdadeiro (.T.). Em AdvPl existem dois comandos para
execução de seções de código de acordo com avaliações lógicas. O comando
IF...ENDIF e o comando DO CASE...ENDCASE.
O Comando DO CASE...ENDCASE
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Executa o primeiro conjunto de comandos cuja expressão condicional resulta em
verdadeiro (.T.).
Sintaxe
DO CASE
CASE lExpressao1
Commandos
[CASE lExpressao2
Commandos
...
CASE lExpressaoN
Commandos]
[OTHERWISE
Commandos]
ENDCASE
Parâmetros
Quando a primeira expressão CASE resultante em verdadeiro (.T.) for
encontrada, o conjunto de comandos seguinte é executado. A
execução do conjunto de comandos continua até que a próxima
cláusula CASE, OTHERWISE ou ENDCASE seja encontrada. Ao
terminar de executar esse conjunto de comandos, a execução continua
CASE com o primeiro comando seguinte ao ENDCASE.
lExpressao1 Se uma expressão CASE resultar em falso (.F.), o conjunto de
Comandos... comandos seguinte a esta até a próxima cláusula é ignorado.
Apenas um conjunto de comandos é executado. Estes são os primeiros
comandos cuja expressão CASE é avaliada como verdadeiro (.T.).
Após a execução, qualquer outra expressão CASE posterior é
ignorada (mesmo que sua avaliação resultasse em verdadeiro).
OTHERWISE Se todas as expressões CASE forem avaliadas como falso (.F.), a
Commandos cláusula OTHERWISE determina se um conjunto adicional de
comandos deve ser executado. Se essa cláusula for incluida, os
comandos seguintes serão executados e então o programa continuará
com o primeiro comando seguinte ao ENDCASE. Se a cláusula
OTHERWISE for omitida, a execução continuará normalmente após a
cláusula ENDCASE.
Comentários
O Comando DO CASE...ENDCASE é utilizado no lugar do comando IF...ENDIF
quando um número maior do que uma expressão deve ser avaliada, substituindo a
necessidade de mais de um comando IF...ENDIF aninhados.
Exemplo
Local nMes := Month(Date())
Local cPeriodo := ""
DO CASE
CASE nMes <= 3
cPeriodo := "Primeiro Trimestre"
CASE nMes >= 4 .And. nMes <= 6
cPeriodo := "Segundo Trimestre"
CASE nMes >= 7 .And. nMes <= 9
cPeriodo := "Terceiro Trimestre"
OTHERWISE
cPeriodo := "Quarto Trimestre"
ENDCASE
Return
O Comando IF...ENDIF
Revisão: 20/09/2004
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Executa um conjunto de comandos baseado no valor de uma expressão lógica.
Sintaxe
IF lExpressao
Comandos
[ELSE
Comandos...]
ENDIF
Parâmetros
Especifica uma expressão lógica que é avaliada. Se lExpressao resultar em
verdadeiro (.T.), qualquer comando seguinte ao IF e antecedente ao ELSE ou
ENDIF (o que ocorrer primeiro) será [Link] lExpressao resultar em
falso (.F.) e a cláusula ELSE for definida, qualquer comando após essa
lExpressao
cláusula e anterior ao ENDIF será executada. Se a cláusula ELSE não for
definida, todos os comandos entre o IF e o ENDIF são ignorados. Neste
caso, a execução do programa continua com o primeiro comando seguinte ao
ENDIF.
Conjunto de comandos AdvPl que serão executados dependendo da
Comandos
avaliação da expressão lógica em lExpressao.
Comentários
Pode-se aninhar um bloco de comando IF...ENDIF dentro de outro bloco de comando
IF...ENDIF. Porém, para a avaliação de mais de uma expressão lógica, deve-se utilizar o
comando DO CASE...ENDCASE.
Exemplo
Local dVencto := CTOD("31/12/01")
If Date() > dVencto
Alert("Vencimento ultrapassado!")
Endif
Return
IF no Protheus
Nas versões do ERP Siga Advanced 2.07 /4.07 e anteriores, caso o comando IF
recebesse um argumento nulo ( NIL ) , a aplicação era abortada com a ocorrência
"Error BASE/1066 Argument error: conditional".
A partir das versões Protheus 507 e posteriores, a aplicação não é abortada, e o
comando IF comporta-se como se tivesse recebido o valor booleano .F. ( falso ) .
O Comando FOR...NEXT
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
A estrutura de controle FOR...NEXT, ou simplesmente o loop FOR, repete uma seção
de código em um número determinado de vezes.
Sintaxe
FOR Variavel := nValorInicial TO nValorFinal [STEP nIncremento]
Comandos...
[EXIT]
[LOOP]
NEXT
Parâmetros
Especifica uma variável ou um elemento de uma matriz para atuar
como um contador. A variável ou o elemento da matriz não precisa ter
Variavel
sido declarado antes da execução do comando FOR...NEXT. Se a
variável não existir, será criada como uma variável privada.
nValorInicial é o valor inicial para o contador; nValorFinal é o valor
nValorInicial final para o contador. Pode-se utilizar valores numéricos literais,
TO nValorFinal variáveis ou expressões, contanto que o resultado seja do tipo de dado
numérico.
STEP nIncremento é a quandidade que será incrementada ou decrementada no
nIncremento contador após cada execução da seção de comandos. Se o valor de
nIncremento for negativo, o contador será decrementado. Se a cláusula
STEP for omitida, o contador será incrementado em 1. Pode-se utilizar
valores numéricos literais, variáveis ou expressões, contanto que o
resultado seja do tipo de dado numérico.
Especifica um ou mais instruções de comando AdvPl que serão
Comandos
executadas.
Transfere o controle de dentro do comando FOR...NEXT para o
comando imediatamente seguinte ao NEXT, ou seja, finaliza a
EXIT
repetição da seção de comandos imediatamente. Pode-se colocar o
comando EXIT em qualquer lugar entre o FOR e o NEXT.
Retorna o controle diretamente para a cláusula FOR sem executar o
restante dos comandos entre o LOOP e o NEXT. O contador é
LOOP incrementadou ou decrementado normalmente, como se o NEXT
tivesse sido alcançado. Pode-se colocar o comando LOOP em qualquer
lugar entre o FOR e o NEXT.
Comentários
Uma variável ou um elemento de uma matriz é utilizado como um contador para
especificar quantas vezes os comandos AdvPl dentro da estrutura FOR...NEXT são
executados. Os comandos AdvPl depois do FOR são executados até que o NEXT seja
alcançado. O contador (Variavel) é então incrementado ou decremantado com o valor
em nIncremento (se a cláusula STEP for omitida, o contador é incrementado em 1).
Então, o contador é comparado com o valor em nValorFinal. Se for menor ou igual ao
valor em nValorFinal, os comandos seguintes ao FOR são executados novamente. Se o
valor for maior que o contido em nValorFinal, a estrutura FOR...NEXT é terminada e o
programa continua a execução no primeiro comando após o NEXT.
Os valores de nValorInicial, nValorFinal e nIncremento são apenas considerados
inicialmente. Entretanto, mudar o valor da variável utilizada como contador dentro da
estrutura afetará o número de vezes que a repetição será executada. Se o valor de
nIncremento é negativo e o valor de nValorInicial é maior que o de nValorFinal, o
contador será decrementado a cada repetição.
Exemplo
Local nCnt
Local nSomaPar := 0
For nCnt := 0 To 100 Step 2
nSomaPar += nCnt
Next
Alert( "A soma dos 100 primeiros números pares é: " + ;
cValToChar(nSomaPar) )
Return
Este exemplo imprime a soma dos 100 primerios números pares. A soma é obitida
através da repetição do cálculo utilizando a própria variável de contador. Como a
cláusula STEP está sendo utilizada, a variável nCnt será sempre incrementada em 2. E
como o contador começa com 0, seu valor sempre será um número par.
O Comando WHILE...ENDDO
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
A estrutura de controle WHILE...ENDDO, ou simplesmente o loop WHILE, repete uma
seção de código enquanto uma determinada expressão resultar em verdadeiro (.T.).
Sintaxe
WHILE lExpressao
Comandos...
[EXIT]
[LOOP]
ENDDO
Parâmetros
Especifica uma expressão lógica cujo valor determina quando os comandos
entre o WHILE e o ENDDO são executados. Enquanto o resultado de
lExpressao
lExpressao for avaliado como verdadeiro (.T.), o conjunto de comandos são
executados.
Especifica um ou mais instruções de comando AdvPl que serão executadas
Comandos
enquanto lExpressao for avaliado como verdadeiro (.T.).
EXIT Transfere o controle de dentro do comando WHILE...ENDDO para o
comando imediatamente seguinte ao ENDDO, ou seja, finaliza a repetição da
seção de comandos imediatamente. Pode-se colocar o comando EXIT em
qualquer lugar entre o WHILE e o ENDO.
Retorna o controle diretamente para a cláusula WHILE sem executar o
restante dos comandos entre o LOOP e o ENDDO. A expressão em
LOOP
lExpressao é reavaliada para a decisão se os comandos continuarão sendo
executados.
Comentários
Os comandos entre o WHILE e o ENDDO são executados enquanto o resultado da
avaliação da expressão em lExpressao permanecer verdadeiro (.T.). Cada palavra chave
WHILE deve ter uma palavra chave ENDDO correspondente.
Exemplo
Local nNumber := 0
Local nSomaPar := 0
While nNumber <= 100
nSomaPar += nNumber
nNumber += 2
Enddo
Alert( "A soma dos 100 primeiros números pares é: " +
cValToChar(nSomaPar) )
Return
Repeticäo de Comandos
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Estruturas de repetição são deseginadas para executar uma seção de código mais de uma
vez. Por exemplo, imagiando-se a existência de uma função para imprimir um relatório,
pode-se desejar imprimi-lo quatro vezes. Claro, pode-se simplesmente chamar a função
de impressão quatro vezes em seqüência, mas isto se tornaria pouco profissional e não
resolveria o problema se o número de relatórios fosse variável.
Em AdvPl existem dois comandos para a repetição de seções de código. O comando
FOR...NEXT e o comando WHILE...ENDDO.
Macro Substituicäo
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
O operador de macro substituição, simbolizado pelo "e" comercial (&), é utilizado para
a avaliação de expressões em tempo de execução. Funciona como se uma expressão
armazenada fosse compilada em tempo de execução, antes de ser de fato executada.
Considere o exemplo:
01 X := 10
02 Y := "X + 1"
03 B := &Y // O conteúdo de B será 11
A variável X é atribuída com o valor 10, enquanto a variável Y é atribuída com a string
de caracteres contendo "X + 1".
A terceira linha utiliza o operador de macro. Esta linha faz com que o número 11 seja
atribuído à variável B. Pode-se perceber que esse é o valor resultante da expressão em
formato de caractere contida na variável Y.
Utilizando-se uma técnica matemática elementar, a substituição, temos que na segunda
linha, Y é definido como "X + 1", então pode-se substituir Y na terceira linha:
03 B := &"X + 1"
O operador de macro cancela as aspas:
03 B := X + 1
Pode-se perceber que o operador de macro remove as aspas, o que deixa um pedaço de
código para ser executado. Deve-se ter em mente que tudo isso acontece em tempo de
eecução, o que torna tudo muito dinâmico. Uma utilização interessante é criar um tipo
de calculadora, ou avaliador de fórmulas, que determina o resultado de algo que o
usuário digita.
O operador de macro tem uma limitação: variáveis referenciadas dentro da string de
caracteres (X nos exemplos anteriores) não podem ser locais.
Operadores Comuns
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Na documentação sobre variáveis há uma breve demonstração de como atribuir valores
a uma variável da forma mais simples. O AdvPl amplia significativamente a utilização
de variáveis através do uso de expressões e funções. Uma expressão é um conjunto de
operadores e operandos cujo resultado pode ser atribuído a uma variável ou então
analisado para a tomada de decisões. Por exemplo:
Local nSalario := 1000, nDesconto := 0.10
Local nAumento, nSalLiquido
nAumento := nSalario * 1.20
nSalLiquido := nAumento * (1-nDesconto)
Neste exemplo são utilizadas algumas expressões para calcular o salário líquido após
um aumento. Os operandos de uma expressão podem ser uma variável, uma constante,
um campo de arquivo ou uma função.
Operadores Matemáticos
Os operadores utilizados em AdvPl para cálculos matemáticos são:
+ Adição
- Subtração
* Multiplicação
/ Divisão
** ou ^ Exponenciação
% Módulo (Resto da Divisão)
Operadores de String
Os operadores utilizados em AdvPl para tratamento de caracteres são:
+ Concatenação de strings (união)
- Concatenação de strings com eliminação dos brancos finais das strings intermediárias
$ Comparação de Substrings (contido em)
Operadores Relacionais
Os operadores utilizados em AdvPl para operações e avaliações relacionais são:
< Comparação Menor
> Comparação Maior
= Comparação Igual
== Comparação Exatamente Igual (para caracteres)
<= Comparação Menor ou Igual
>= Comparação Maior ou Igual
<> ou # ou != Comparação Diferente
Operadores Lógicos
Os operadores utilizados em AdvPl para operações e avaliações lógicas são:
.And. E lógico
.Or. OU lógico
.Not. ou ! NÃO lógico
Operadores Especiais
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Além dos operadores comuns, o AdvPl possui alguns outros operadores ou
identificadores. Estas são suas finalidades:
() Agrupamento ou Função
[] Elemento de Matriz
{} Definição de Matriz, Constante ou Bloco de Código
-> Identificador de Apelido
& Macrosubstituição
@ Passagem de parâmetro por referência
Os parênteses são utilizados para agrupar elementos em uma expressão mudando a
ordem de precedência da avaliação da expressão (segundo as regras matemáticas por
exemplo). Também servem para envolver os argumentos de uma função. Veja a
documentação sobre precedência de operadores para maiores detalhes.
Os colchetes são utilizados para especificar um elemento específico de uma matriz. Por
exemplo, A[3,2], refere-se ao elemento da matriz A na linha 3, coluna 2.
As chaves são utilizadas para a especificação de matrizes literais ou blocos de código.
Por exemplo, A:={10,20,30} cria uma matriz chamada A com três elementos.
O símbolo -> identifica um campo de um arquivo diferenciando-o de uma variável. Por
exemplo, FUNC->nome refere-se ao campo nome do arquivo FUNC. Mesmo que exista
uma variável chamada nome, é o campo nome que será acessado.
O símbolo & identifica uma avaliação de expressão através de macro e é visto em
detalhes na documentação sobre macrossubstituição.
O símbolo @ é utilizado para indicar que durante a passagem de uma variável para uma
função ou procedimento ela seja tomada como uma referência e não como valor.
Operadores de Atribuicäo
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Os operadores utilizados em AdvPl para atribuição de valores a variáveis de memória
são:
= Atribuição Simples
:= Atribuição em Linha
+= Adição e Atribuição em Linha
-= Subtração e Atribuição em Linha
*= Multiplicação e Atribuição em Linha
/= Divisão e Atribuição em Linha
**= ou ^= Exponenciação e Atribuição em Linha
%= Módulo (resto da divisão) e Atribuição em Linha
Atribuição Simples
O sinal de igualdade é utilizado para atribuir valor a uma variável de memória.
nVariavel = 10
Atribuição em Linha
O operador de atribuição em linha é caracterizado por dois pontos e o sinal de
igualdade. Tem a mesma função do sinal de igualdade sozinho, porém aplia a atribuição
às variáveis. Com ele pode-se atribuir mais de uma variável ao mesmo tempo.
nVar1 := nVar2 := nVar3 := 0
Quando diversas variáveis são inicializadas em uma mesma linha, a atribuição começa
da direita para a esquerda, ou seja, nVar3 recebe o valro zero inicialmente, nVar2
recebe o conteúdo de nVar3 e nVar1 recebe o conteúdo de nVar2 por final.
Com o operador de atribuição em linha, pode-se substituir as inicializações individuais
de cada variável por uma inicialização apenas:
Local nVar1 := 0, nVar2 := 0, nVar3 := 0
por
Local nVar1 := nVar2 := nVar3 := 0
O operador de atribuição em linha também pode ser utilizado para substituir valores de
campos em um banco de dados.
Atribuição Composta
Os operadores de atribuição composta são uma facilidade da linguagem AdvPl para
expressões de cálculo e atribuição. Com eles pode-se economizar digitação:
Operador Exemplo Equivalente a
+= X += Y X = X + Y
-= X -= Y X = X - Y
*= X *= Y X = X * Y
/= X /= Y X = X / Y
**= ou ^= X **= Y X = X ** Y
%= X %= Y X = X % Y
Operadores de Incremento/Decremento
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
A linguagem AdvPl possui operadores para realizar incremento ou decremento de
variáveis. Entende-se por incremento aumentar o valor de uma variável numérica em 1 e
entende-se por decremento diminuir o valor da variável em 1. Os operadores são:
++ Incremento Pós ou Pré-fixado
-- Decremento Pós ou Pré-fixado
Os operadores de decremento/incremento podem ser colocados tanto antes (pré-fixado)
como depois (pós-fixado) do nome da variável. Dentro de uma expressão, a ordem do
operador é muito importante, podendo alterar o resultado da expressão. Os operadores
incrementais são executados da esquerda para a direita dentro de uma expressão.
Local nA := 10
Local nB := nA++ + nA
O valor da variável nB resulta em 21, pois a primeira referência a nA (antes do ++)
continha o valor 10 que foi considerado e imediatamente aumentado em 1. Na segunda
referência a nA, este já possuía o valor 11. O que foi efetuado foi a soma de 10 mais 11,
igual a 21. O resultado final após a execução destas duas linhas é a variável nB
contendo 21 e a variável nA contendo 11.
No entanto:
Local nA := 10
Local nB := ++nA + nA
Resulta em 22, pois o operador incremental aumentou o valor da primeira nA antes que
seu valor fosse considerado.
Ordem de Precedencia dos Operadores
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Dependendo do tipo de operador, existe uma ordem de precedência para a avaliação dos
operandos. Em princípio, todas as operações com os operadores são realizadas da
esquerda para a direita se eles tiverem o mesmo nível de prioridade.
A ordem de precedência, ou nível de prioridade de execução, dos operadores em AdvPl
é:
1. Operadores de Incremento/Decremento pré-fixado
2. Operadores de String
3. Operadores Matemáticos
4. Operadores Relacionais
5. Operadores Lógicos
6. Operadores de Atribuição
7. Operadores de Incremento/Decremento pós-fixado
Em expressões complexas com diferentes tipos de operadores, a avaliação seguirá essa
sequência. Caso exista mais de um operador do mesmo tipo (ou seja, de mesmo nível), a
avaliação se dá da esquerda para direita. Para os operadores matemáticos entretanto há
uma precedência a seguir:
1. Exponenciação
2. Multiplicação e Divisão
3. Adição e Subtração
Considere o exemplo:
Local nResultado := 2+10/2+5*3+2^3
O resultado desta expressão é 30, pois primeiramente é calculada a exponenciação
2^3(=8), então são calculadas as multiplicações e divisões 10/2(=5) e 5*3(=15), e
finalmente as adições resultando em 2+5+15+8(=30).
Alteração da Precedência
A utilização de parênteses dentro de uma expressão altera a ordem de precedência dos
operadores. Operandos entre parênteses são analisados antes dos que se encontram fora
dos parênteses. Se existirem mais de um conjunto de parênteses não-aninhados, o grupo
mais a esquerda será avaliado primeiro e assim sucessivamente.
Local nResultado := (2+10)/(2+5)*3+2^3
No exemplo acima primeiro será calculada a exponenciação 2^3(=8). Em seguida
2+10(=12) será calculado, 2+5(=7) calculado, e finalmente a divisão e a multiplicação
serão efetuadas, o que resulta em 12/7*3+8(=13.14).
Se existirem vários parênteses aninhados, ou seja, colocados um dentro do outro, a
avaliação ocorrerá do parênteses mais intero em direção ao mais externo.
Blocos de Codigo
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Blocos de código são um conceito existente há muito tempo em linguagens xBase. Não
como algo que apareceu da noite para o dia, e sim uma evolução progressiva utilizando
a combinação de muitos conceitos da linguagem para a sua implementação.
Um Primeiro Lembrete
O AdvPl é uma linguagem baseada em funções. Funções têm um valor de retorno.
Assim como o operador de atribuição :=.
Assim, ao invés de escrever:
x := 10 // Atribui o valor 10 à variável chamada X
Alert("Valor de x: " + cValToChar(x))
Pode-se escrever:
// Atribui e então exibe o valor da variável X
Alert("Valor de x: " + cValtoChar(X := 10))
A expressão x:=10 é avaliada primeiro, e então seu resultado (o valor de X, que agora é
10) é passada para a função cvaltochar para a conversão para caracter, e em seguida
para a função alert para a exibição. Por causa desta regra de precedência é possível
atribuir um valor a mais de uma varíavel ao mesmo tempo:
Z := Y := X := 0
Por causa dessa regra, essa expressão é avaliada como se fosse escrita assim:
Z := ( Y := (X := 0) )
Apesar do AdvPl avaliar expressões da esquerda para a direita, no caso de atribuições
isso acontece ao contrário, da direita para a esquerda. O valor é atribuído à variável X,
que retorna o valor para ser atribuído à variável Y e assim sucessivamente. Pode-se
dizer que o zero foi "propagado através da expressão".
Outro Lembrete
Em AdvPl pode-se juntar diversas linhas de código em uma única linha físcia do
arquivo. Por exemplo, o código:
If lAchou
Alert("Cliente encontrado!")
Endif
pode ser escrito assim:
If lAchou ; Alert("Cliente encontrado!") ; Endif
O ponto-e-vírgula indica ao AdvPl que a nova linha de código está para começar. Pode-
se então colocar diversas linhas lógicas de código na mesma linha física através do
editor de texto utilizado.
Apesar da possibilidade de se escrever todo o programa assim, em uma única linha
física, isto não é recomendado pois dificulta a legibilidade do programa e,
conseqüentemente, a manutenção.
Lista de Expressões
A evolução dos blocos de código começa com as listas de expressões. Nos exemplos a
seguir, o símbolo ==> indicará o retorno da expressão após sua avaliação (seja para
atribuir em uma variável, exibir para o usuário ou imprimir em um relatório), que será
impresso em um relatório por exemplo.
Duas Linhas de Código
@00,00 PSAY x := 10 ==> 10
@00,00 PSAY y := 20 ==> 20
Cada uma das linhas terá a expressão avaliada, e o valor da variável será então
impresso.
Duas Linha de Código em Uma , Utilizando Ponto-e-Vírgula
Este é o mesmo código que o anterior, apenas escrito em uma única linha:
Alert( cValToChar( x := 10 ; y := 20 ) ) ==> 10
Apesar desse código se encontrar em uma única linha física, existem duas linhas lógicas
separadas pelo ponto e vírgula. Ou seja, esse código é equivalente a:
Alert( cValToChar( x := 10 ) )
y := 20
Portanto apenas o valor 10 da variável x será passado para as funções cvaltochar e alert
para ser exibido. E o valor 20 apenas será atribuído à variável y.
Convertendo para uma Lista de Expressões
Quando parênteses são colocados ao redor do código e o sinal de ponto-e-vírgula
substituído por uma vírgula apenas, o código torna-se uma lista de expressões:
Alert( cValToChar ( ( X := 10 , Y := 20 ) ) ) ==> 20
O valor de retorno resultante de uma lista de expressões é o valor resultante da última
expressão ou elemento da lista. Funciona como se fosse um pequeno programa ou
função, que retorna o resultado de sua última avaliação (efetuadas da esquerda para a
direita).
Neste exemplo, a expressão x := 10 é avaliada, e então a expressão y := 20, cujo valor
resultante é passado para a função alert e cvaltochar, e então exibido. Depois que essa
linha de código é executada, o valor de X é igual a 10 e o de y igual a 20, e 20 será
exibido.
Teoricamente, não há limitação para o número de expressões que podem ser
combinadas em uma lista de expressões. Na prática, o número máximo é por volta de
500 símbolos.
Debugar listas de expressões é difícil oprque as expressões não estão divididas em
linhas de código fonte, o que torna todas as expressões associadas a uma mesma linha
de código. Isto pode tornar muito difícil determinar onde um erro ocorreu.
Onde Pode-se Utilizar uma Lista de Expressões?
O propósito principal de uma lista de expressões é agrupá-las em uma única unidade.
Em qualquer lugar do código AdvPl que uma expressão simples pode ser utilizada,
pode-se utilizar uma lista de expressões. E ainda, pode-se fazer com que várias coisas
aconteçam onde normalmente apenas uma aconteceria.
X := 10 ; Y := 20
If X > Y
Alert("X")
Z := 1
Else
Alert("Y")
Z := -1
Endif
Aqui temos o mesmo conceito, escrito utilizando listas de expressões na função iif:
X := 10 ; Y := 20
iif( X > Y , ;
( Alert("X"), Z := 1 ) , ;
( Alert("Y"), Z := -1 ) )
De Listas de Expressões para Blocos de Código
Considere a seguinte lista de expressões:
Alert( cValToChar( ( x := 10, y := 20 ) ) ) ==> 20
O AdvPl permite criar funções, que são pequenos pedaços de código, como se fosse um
pequeno programa, utilizados para diminuir partes de tarefas mais complexas e
reaproveitar código em mais de um lugar num programa. Para maiores detalhes consulte
a documentação sobre a criação de funções em AdvPl. Porém, a idéia neste momento é
que a lista de expressões utilizada na linha anterior pode ser criada como uma função:
Function Lista()
X := 10
Y := 20
Return Y
E a linha de exemplo com a lista de expressões pode ser substituída, tendo o mesmo
resultado, por:
Alert( cValToChar( Lista() ) ) ==> 20
Como mencionado anteriormente, uma lista de expressões é como um pequeno
programa ou função. Com poucas mudanças, uma lista de expressões pode se tornar um
bloco de código:
( X := 10 , Y := 20 ) // Lista de Expressões
{|| X := 10 , Y := 20 } // Bloco de Código
Note as chaves {} utilizadas no bloco de código. Ou seja, um bloco de código é uma
matriz. Porém na verdade, não é uma lista de dados, e sim uma lista de comandos, uma
lista de código.
// Isto é uma matriz de dados
A := {10, 20, 30}
// Isto é um bloco de código, porém funciona como
// se fosse uma matriz de comandos
B := {|| x := 10, y := 20}
Executando um Bloco de Código
Diferentemente de uma matriz, não se pode acessar elementos de um bloco de código
através de um índice numérico. Porém blocos de código são semelhantes a uma lista de
expressões, e a uma pequena função. Ou seja, podem ser executados. Para a execução,
ou avaliação, de um bloco de código, deve-se utilizar a função eval:
nRes := Eval(B) ==> 20
Essa função recebe como parâmero um bloco de código e avalias todas as expressões
contidas neste bloco de código, retornando o resultado da última expressão avaliada.
Passando Parâmetros
Já que blocos de código são como pequenas funções, também é possível a passagem de
parâmetros para um bloco de código. Os parâmetros devem ser informados entre as
barras verticais (||) separados por vírgulas, assim como em uma função.
B := {| N | X := 10, Y := 20 + N}
Porém deve-se notar que já que o bloco de código recebe um parâmetro, um valor deve
ser passado quando o bloco de código for avaliado.
C := Eval(B, 1) ==> 21
Utilizando Blocos de Código
Blocos de código podem ser utilizados em diversas situações. Geralmente são utilizados
para executar tarefas quando eventos de objetos são acionados ou para modificar o
comportamento padrão de algumas funções.
Por exemplo, considere a matriz abaixo:
A := {"GARY HALL", "FRED SMITH", "TIM JONES"}
Esta matriz pode ser ordenada pelo primeiro nome, utilizando-se a chamada da função
asort(A), resultado na matriz com os elementos ordenados dessa forma:
{"FRED SMITH", "GARY HALL", "TIM JONES"}
A ordem padrão para a função asort é ascendente. Este comportamento pode ser
modificado através da informação de um bloco de código que ordena a matriz de forma
descendente:
B := { |X, Y| X > Y }
aSort(A, B)
O bloco de código (de acordo com a documentação da função asort) deve ser escrito
para aceitar dois parâmetros que são os dois elementos da matriz para comparação. Note
que o bloco de código não conhece que elementos está comparando - a função asort
seleciona os elementos (talvez utilizando o algorítmo QuickSort) e passa-os para o
bloco de código. O bloco de código compara-os e retorna verdadeiro (.T.) se se
encontram na ordem correta, ou falso (.F.) se não. Se o valor de retorno for falso, a
função asort irá então trocar os valores de lugar e seguir comparando o próximo par de
valores.
Então, no bloco de código anterior, a comparação X > Y é verdadeira se os elementos
estão em ordem descendente, o que significa que o primeiro valor é maior que o
segundo.
Para ordenar a mesma matriz pelo último nome, também em ordem descendente, pode-
se utilizar o seguinte bloco de código:
B := { |X, Y| Substr(X,At(" ",X)+1) > Substr(Y,At(" ",Y)+1) }
Note que este bloco de código procura e compara as partes dos caracteres
imediatamente seguinte a um espaço em branco. Depois de utilizar esse bloco de código
para a função asort, a matriz conterá:
{"GARY HALL", "TIM JONES", "FRED SMITH"}
Finalmente, para ordenar um sub-elemento (coluna) de uma matriz por exemplo, pode-
se utilizar o seguinte bloco de código:
B := { |X, Y| X[1] > Y[1] }
Criacäo e Atribuicäo de Variaveis
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Variáveis de memória são um dos recursos mais importantes de uma linguagem. São
áreas de memória criadas para armazenar informações utilizadas por um programa para
a execução de tarefas. Por exemplo, quando o usuário digita uma informação qualquer,
como o nome de um produto, em uma tela de um programa esta informação é
armazenada em uma variável de memória para posteriormente ser gravada ou impressa.
A partir do momento que uma variável é criada, não é necessário mais se referenciar ao
seu conteúdo, e sim ao seu nome. O nome de uma variável é um identificador único que
segue duas regras regras:
Máximo de 10 caracteres. O AdvPl não impede a criação de uma variável de memória
cujo nome contenha mais de 10 caracteres, porém apenas os 10 primeiros serão
considerados para a localização do conteúdo armazenado. Portanto se forem criadas
duas variáveis cujos 10 primeiros caracteres forem iguais, como nTotalGeralAnual e
nTotalGeralMensal, as referências a qualquer uma delas no programa resultarão o
mesmo. Ou seja, serão a mesma variável:
nTotalGeralMensal := 100
nTotalGeralAnual := 300
Alert("Valor mensal: " + cValToChar(nTotalGeralMensal))
Quando o conteúdo da variável nTotalGeralMensal é exibido, o seu valor será de 300.
Isso acontece porque no momento que esse valor foi atribuido à variável
nTotalGeralAnual, o AdvPl considerou apenas os 10 primeiros caracteres (assim como
o faz quando deve exibir o valor da variável nTotalGeralMensal), ou seja, considerou-as
como a mesma variável. Assim o valor original de 100 foi substituido pelo de 300.
Limitação de caracteres no nome. Os nomes das variáveis devem sempre começar por
uma letra ou o caracter de sublinhado ( _ ). No restante, pode conter letras, números e o
caracter de sublinhado. Qualquer outro caracter, incluindo espaços em branco, não são
permitidos.
O AdvPl permite a criação ilimitada de variáveis, dependendo apenas da memória
disponível. A seguir estão alguns nomes válidos para variáveis:
TOT01
cNumero
VAR_QUALQUER
M_CARGO
A11
E alguns inválidos:
1CODIGO (Inicia por um número)
M CARGO (contém um espaço em branco)
LOCAL (palavra reservada do AdvPl)
O AdvPl não é uma linguagem de tipos rígidos para variáveis, ou seja, não é necessário
informar o tipo de dados que determinada variável irá conter no momento de sua
declaração, e o seu valor pode mudar durante a execução do programa. Também não há
necessidade de declarar variáveis em uma seção específica do seu código fonte, embora
seja aconselhável declarar todas as variáveis necessárias no começo, tornando a
manutenção mais fácil e evitando a declaração de variáveis desnecessárias.
Para declarar uma variável deve-se utilizar um identificador de escopo, seguido de uma
lista de variáveis separadas por vírgula (,). Um identificador de escopo é uma palavra
chave que indica a que contexto do programa a variável declarada pertence. O contexto
de variáveis pode ser local (visualizadas apenas dentro do programa atual), público
(visualizadas por qualquer outro programa), entre outros. Os diferentes tipos de
contexto de variáveis são explicados na documentação sobre escopo de variáveis.
Considere as linhas de código de exemplo:
nResultado := 250 * (1 + (nPercentual / 100))
Se esta linha for executada em um programa AdvPl, ocorrerá um erro de execução com
a mensagem "variable does not exist: nPercentual", pois esta variável está sendo
utilizada em uma expressão de cálculo sem ter sido declarada. Para solucionar este erro,
deve-se declarar a variável previamente:
Local nPercentual, nResultado
nResultado := 250 * (1 + (nPercentual / 100))
Neste exemplo, as variáveis são declaradas previamente utilizando o identificador de
escopo local. Quando a linha de cálculo for executada, o erro de variável não existente
não mais ocorrerá. Porém variáveis não inicializadas têm sempre o valor default nulo
(Nil) e este valor não pode ser utilizado em um cálculo pois também gerará erros de
execução (nulo não pode ser dividido por 100). A resolução deste problema é efetuada
inicializando-se a variável através de uma das formas:
Local nPercentual,nResultado
Store 10 To nPercentual
nResultado := 250 * (1 + (nPercentual / 100))
ou
Local nPercentual, nResultado
nPercentual := 10
nResultado := 250 * (1 + (nPercentual / 100))
ou
Local nPercentual := 10, nResultado
nResultado := 250 * (1 + (nPercentual / 100))
A diferença entre o último exemplo e os dois anteriores é que a variável é inicializada
no momento da declaração. Nos dois primeiros exemplos, a variável é primeiro
declarada e então inicializada em uma outra linha de código. O comando store existe
apenas por compatibilidade com versões anteriores e outras linguagens xBase, mas é
obsoleto. Deve-se utilizar o operador de atribuição (:= ou somente =). É aconselhável
optar pelo operador de atribuição composto de dois pontos e sinal de igual, pois o
operador de atribuição utilizando somente o sinal de igual pode ser facilmente
confundido com o operador relacional (para comparação) durante a criação do
programa.
Uma vez que um valor lhe seja atribuído, o tipo de dado de uma variável é igual ao tipo
de dado do valor atribuído. Ou seja, uma variável passa a ser numérica se um número
lhe é atribuído, passa a ser caracter se uma string de texto lhe for atribuída, etc. Porém
mesmo que uma variável seja de determinado tipo de dado, pode-se mudar o tipo da
variável atribuindo outro tipo a ela:
01 Local xVariavel // Declara a variável inicialmente com valor nulo
02
03 xVariavel := "Agora a variável é caracter..."
04 Alert("Valor do Texto: " + xVariavel)
05
06 xVariavel := 22 // Agora a variável é numérica
07 Alert(cValToChar(xVariavel))
08
09 xVariavel := .T. // Agora a variável é lógica
10 If xVariavel
11 Alert("A variável tem valor verdadeiro...")
12 Else
13 Alert("A variável tem valor falso...")
14 Endif
15
16 xVariavel := Date() // Agora a variável é data
17 Alert("Hoje é: " + DtoC(xVariavel))
18
19 xVariavel := nil // Nulo novamente
20 Alert("Valor nulo: " + xVariavel)
21
22 Return
No programa de exemplo anterior, a variável xVariavel é utilizada para armazenar
diversos tipos de dados. A letra "x" em minúsculo no começo do nome é utilizada para
indicar uma variável que pode conter diversos tipos de dados, segundo a Notação
Húngara (consulte documentação específica para detalhes). Este programa troca os
valores da variável e exibe seu conteúdo para o usuário através da função alert. Essa
função recebe um parâmetro que deve ser do tipo string de caracter, por isso
dependendo do tipo de dado da variável xVariavel é necessário fazer uma conversão
antes.
Apesar dessa flexibilidade de utilização de variáveis, deve-se tomar cuidados na
passagem de parâmetros para funções ou comandos, e na concatenação (ou soma) de
valores. Note a linha 20 do programa de exemplo. Quando esta linha é executada, a
variável xVariavel contem o valor nulo. A tentativa de soma de tipos de dados
diferentes gera erro de execução do programa. Nesta linha do exemplo, ocorrerá um
erro com a mensagem "type mismatch on +". Excetuando-se o caso do valor nulo, para
os demais deve-se sempre utilizar funções de conversão quando necessita-se concatenar
tipos de dados diferentes (por exemplo, nas linhas 07 e 17.
Note também que quando uma variável é do tipo de dado lógico, ela pode ser utilizada
diretamente para checagem (linha 10):
If xVariavel
é o mesmo que
If xVariavel = .T.
A declaração de variáveis para os demais tipos de dados, matrizes e blocos de código, é
exatamente igual ao descrito até agora. Apenas existem algumas diferenças quanto a
inicialização, que podem ser consultadas na documentação de inicialização de matrizes
e blocos de código.
Diferenciacäo entre variaveis e nomes de campos
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Muitas vezes uma variável pode ter o mesmo nome que um campo de um arquivo ou
tabela aberto no momento. Neste caso, o AdvPl privilegiará o campo. Assim uma
referência a um nome que identifique tanto uma variável como um campo, resultará no
conteúdo do campo.
Para especificar qual deve ser o elemento referenciado, deve-se utilizar o operador de
identificação de apelido (->) e um dos dois identificadores de referência, MEMVAR ou
FIELD.
cRes := MEMVAR->NOME
Esta linha de comando identifica que o valor atribuído à variável cRes deve ser o valor
da variável de memória chamada NOME.
cRes := FIELD->NOME
Neste caso, o valor atribuído à variável cRes será o valor do campo NOME existente no
arquivo ou tabela aberto na área atual.
O identificador FIELD pode ser substituído pelo apelido de um arquivo ou tabela
aberto, para evitar a necessidade de selecionar a área antes de acessar o conteúdo de
terminado campo.
cRes := CLIENTES->NOME
Para maiores detalhes sobre abertura de arquivos com atribuição de apelidos, consulte a
documentação sobre acesso a banco de dados ou a documentação da função dbUseArea.
Inicializando Matrizes
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Algumas vezes o tamanho da matriz é conhecido previamente. Outras vezes o tamanho
da matriz só será conhecido em tempo de execução.
Se o tamanho da matriz é conhecido
Se o tamanho da matriz é conhecido no momento que o programa é escrito, há diversas
maneiras de implementar o código.
01 Local nCnt
02 Local aX[10]
03 Local aY := Array(10)
04 Local aZ := {0,0,0,0,0,0,0,0,0,0}
05
06 For nCnt := 1 To 10
07 aX[nCnt] := nCnt * nCnt
08 Next nCnt
Este código preenche a matriz com uma tabela de quadrados. Os valores serão 1, 4, 9,
16 ... 81, 100. Note que a linha 07 se refere à variável aX, mas poderia também
trabalhar com aY ou aZ. O objetivo deste exemplo é demonstrar trÊs modos de criar
uma matriz de tamanho conhecido no momento da criação do código.
Na linha 02 a matriz é criada usando aX[10]. Isto indica ao AdvPl para alocar espaço
para 10 elementos na matriz. Os colchetes [ e ] são utilizados para indicar o tamanho
necessário.
Na linha 03 é utilizada a função array com o parâmetro 10 para criar a matriz, e o
retorno desta função é atribuído à variável aY.
Na linha 03 é efetuado o que se chama "desenhar a imagen da matriz". Como pode-se
notar, existem dez 0´s na lista encerrada entre chaves ({}). Claramente, este método não
é o utilizado para criar uma matriz de 1000 elementos. O terceiro método difere dos
anteriores porque inicializa a matriz com os valores definitivos. Nos dois primeiros
métodos, cada posição da matriz contém um valor nulo (Nil) e deve ser inicializado
posteriormente.
A linha 07 demonstra como um valor pode ser atribuído para uma posição existente em
uma matriz especificando o índice entre colchetes.
Se o tamanho da matriz não é conhecido
Se o tamanho da matriz não é conhecido até o momento da execução do programa, há
algumas maneiras de criar uma matriz e adicionar elementos a ela. O exemplo a seguir
ilustra a idéia de criação de uma matriz vazia (sem nenhum elemento) e adição de
elementos dinamicamente.
01 Local nCnt
02 Local aX[0]
03 Local aY := Array(0)
04 Local aZ := {}
05
06 For nCnt := 1 To nSize
07 aAdd(aX,nCnt*nCnt)
08 Next nCnt
A linha 02 utiliza os colchetes para criar uma matriz vazia. Apesar de não ter nenhum
elemento, seu tipo de dado é matriz.
Na linha 03 a chamada da função array cria uma matriz sem nenhum elemento.
Na linha 04 está declarada a representação de uma matriz vazia em AdvPl. Mais uma
vez, estão sendo utilizadas as chaves para indicar que o tipo de dados da variável é
matriz. Note que {} é uma matriz vazia (tem o tamanho 0), enquanto {Nil} é uma
matriz com um único elemento nulo (tem tamanho 1).
Porque cada uma destas matrizes não contem elementos, a linha 07 utiliza a função aadd
para adicionar elementos sucessivamente até o tamanho necessário (especificado por
exemplo na variável nSize).
Matrizes
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Matrizes, ou arrays, são coleções de valores. Ou, de uma maneira mais fácil de
entender, uma lista. Uma matriz pode ser criada através de diferentes maneiras.
Consulte a documentação sobre Inicialização de Matrizes para maiores detalhes.
Cada item em uma matriz é referenciado pela indicação de sua posição numérica na
lista, iniciando pelo número 1. O exemplo a seguir declara uma variável, atribui uma
matriz de três elementos a ela, e então exibe um dos elementos e o tamanho da matriz:
Local aLetras // Declaração da variável
aLetras := {"A", "B", "C"} // Atribuição da matriz à variável
Alert(aLetras[2]) // Exibe o segundo elemento da matriz
Alert(cValToChar(Len(aLetras))) // Exibe o tamanho da matriz
O AdvPl permite a manipulação de matrizes facilmente. Enquanto que em outras
linguagens como C ou Pascal é necessário alocar memória para cada elemento de uma
matriz (o que tornaria a utilização de "pointeiros" necessária), o AdvPl se encarrega de
gerenciar a memória e torna simples adicionar elementos a uma matriz, utilizando a
função aAdd:
aAdd(aLetras,"D") // Adiciona o quarto elemento ao final da matriz
Alert(aLetras[4]) // Exibe o quarto elemento
Alert(aLetras[5]) // Erro! Não há um quinto elemento na matriz
Matrizes como Estruturas
Uma característica interessante do AdvPl é que uma matriz pode conter qualquer coisa:
números, datas, lógicos, caracteres, objetos, etc. E ao mesmo tempo. Em outras
palavras, os elementos de uma matriz não precisam ser necessariamente do mesmo tipo
de dado, em contraste com outras linguagens como C e Pascal.
aFunct1 := {"Pedro",32,.T.}
Esta matriz contem uma string, um número e um valor lógico. Em outras linguagens
como C ou Pascal, este "pacote" de informações pode ser chamado como um "struct"
(estrutura em C, por exemplo) ou um "record" (registro em Pascal, por exemplo). Como
se fosse na verdade um registro de um banco de dados, um pacote de informações
construído com diversos campos. Cada campo tendo um pedaço diferente de dado.
Suponha que no exemplo anterior, o array aFunct1 contenha informações sobre o nome
de uma pessoa, sua idade e sua situação matrimonial. Os seguintes #defines podem ser
criados para indicar cada posição dos valores dentro da matriz:
#define FUNCT_NOME 1
#define FUNCT_IDADE 2
#define FUNCT_CASADO 3
E considere mais algumas matrizes para representar mais pessoas:
aFunct2 := {"Maria" , 22, .T.}
aFunct3 := {"Antônio", 42, .F.}
Os nomes podem ser impressos assim:
Alert(aFunct1[FUNCT_NOME])
Alert(aFunct2[FUNCT_NOME])
Alert(aFunct3[FUNCT_NOME])
Agora, ao invés de trabalhar com variáveis individuais, pode-se agrupá-las em uma
outra matriz, do mesmo modo que muitos registros são agrupados em uma tabela de
banco de dados:
aFuncts := {aFunct1, aFunct2, aFunct3}
Que é equivalente a isso:
aFuncts := { {"Pedro" , 32, .T.}, ;
{"Maria" , 22, .T.}, ;
{"Antônio", 42, .F.} }
aFuncts é uma matriz com 3 linhas por 3 colunas. Uma vez que as variáveis separadas
foram combinadas em uma matriz, os nomes podem ser exibidos assim:
Local nCount
For nCount := 1 To Len(aFuncts)
Alert(aFuncts[nCount,FUNCT_NOME])
// O acesso a elementos de uma matriz multidimensional
// pode ser realizado também desta forma:
// aFuncts[nCount][FUNCT_NOME]
Next nCount
A variável nCount seleciona que funcionário (ou que linha) é de interesse. Então a
constante FUNCT_NOME seleciona a primeira coluna daquela linha.
Cuidados com Matrizes
Matrizes são listas de elementos, portanto memória é necessária para armazenar estas
informações. Como as matrizes podem ser multidimensionais, a memória necessária
será a multiplicação do número de itens em cada dimensão da matriz, considerando-se o
tamanho do conteúdo de cada elemento contido nesta. Portanto o tamanho de uma
matriz pode variar muito.
A facilidade da utilização de matrizes, mesmo que para armazenar informações em
pacotes como descrito anteriormente, não é compensada pela utilização em memória
quando o número de itens em um array for muito grande. Quando o número de
elementos for muito grande deve-se procurar outras soluções, como a utilização de um
arquivo de banco de dados temporário.
Não há limitação para o número de dimensões que uma matriz pode ter, mas o número
de elementos máximo (independentes das dimensões onde se encontram) é de 100000.
Tipos de Dados
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
O AdvPl não é uma linguagem de tipos rígidos (strongly typed), o que significa que
variáveis de memória podem diferentes tipos de dados durante a execução do programa.
Variáveis podem também conter objetos, mas os tipos primários da linguagem são:
Numérico
Lógico
Caracter
Data
Matriz (Array)
Bloco de Código
Numérico
O AdvPl não diferencia valores inteiros de valores com ponto flutuante, portanto pode-
se criar variáveis numéricas com qualquer valor dentro do intervalo permitido. Os
seguintes elementos são do tipo de dado numérico:
2
43.53
0.5
0.00001
1000000
Uma variável do tipo de dado numérico pode conter um número de dezoito dígitos
incluindo o ponto flutuante, no intervalo de 2.2250738585072014 E–308 até
1.7976931348623158 E+308.
Lógico
Valores lógicos em AdvPl são identificados através de .T. ou .Y. para verdadeiro e .F.
ou .N. para falso (independentemente se os caracteres estiverem em maiúsculo ou
minúsculo).
Caracter
Strings ou cadeias de caracteres são identificadas em AdvPl por blocos de texto entre
aspas duplas (") ou aspas simples ('):
"Olá mundo!"
'Esta é uma string'
"Esta é 'outra' string"
Uma variável do tipo caracter pode conter strings com no máximo 1 Mb, ou seja,
1048576 caracteres.
Data
O AdvPl tem um tipo de dados específico para datas. Internamente as variáveis deste
tipo de dado são armazenadas como um número correspondente a data Juliana.
Variáveis do tipo de dados Data não podem ser declaradas diretamente, e sim através da
utilização de funções específicas como por exemplo ctod que converte uma string para
data.
Matriz (Array)
Matrizes são um tipo de dado especial. É a disposição de outros elementos em colunas e
linhas. O AdvPl suporta matrizes uni ou multidimensionais. Os elementos de uma
matriz são acessados através de índices numéricos iniciados em 1, identificando a linha
e coluna para quantas dimenões existirem.
Uma matriz pode conter no máximo 100000 elementos, independentemente do número
de dimensões.
Matrizes devem ser utilizadas com cautela, pois se forem muito grandes podem exaurir
a memória do servidor.
Bloco de Código
O bloco de código é um tipo de dado especial. É utilizado para armazenar instruções
escritas em AdvPl que poderão ser executadas posteriormente.
ESCOPO DE VÁRIAVEIS
O Contexto de Variaveis dentro de um Programa
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
As variáveis declaradas em um programa ou função, são visíveis de acordo com o
escopo onde são definidas. Como também do escopo depende o tempo de existência das
variáveis. A definição do escopo de uma variável é efetuada no momento de sua
declaração.
Local nNumero := 10
Esta linha de código declara uma variável chamada nNumero indicando que pertence
seu escopo é local.
Os identifadores de escopo são:
LOCAL
STATIC
PRIVATE
PUBLIC
O AdvPl não é rígido em relação à declaração de variáveis no começo do programa. A
inclusão de um identificador de escopo não é necessário para a declaração de uma
variável, contanto que um valor lhe seja atribuído.
nNumero2 := 15
Quando um valor é atribuído à uma variável em um programa ou função, o AdvPl criará
a variável caso ela não tenha sido declarada anteriormente. A variável então é criada
como se tivesse sido declarada como Private.
Devido a essa característica, quando pretende-se fazer uma atribuição a uma variável
declarada previamente mas escreve-se o nome da variável de forma incorreta, o AdvPl
não gerará nenhum erro de compilação ou de execução. Pois compreenderá o nome da
variável escrito de forma incorreta como se fosse a criação de uma nova variável. Isto
alterará a lógica do programa, e é um erro muitas vezes difícil de identificar.
Variaveis Estaticas
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Variáveis estáticas funcionam basicamente como as variáveis locais, mas mantêm seu
valor através da execução. Variáveis estáticas devem ser declaradas explicitamente no
código com o identificador STATIC.
O escopo das variáveis estáticas depende de onde são declaradas. Se forem declaradas
dentro do corpo de uma função ou procedimento, seu escopo será limitado àquela
rotina. Se forem declaradas fora do corpo de qualquer rotina, seu escopo é todo o
arquivo de programa.
Neste exemplo, a variável nVar é declarada como estática e inicializada com o valor 10:
Function Pai()
Static nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Quando a função Filha é executada, nVar ainda existe mas não pode ser acessada.
Diferente de variáveis declaras como LOCAL ou PRIVATE, nVar continua a existir e
mantem seu valor atual quando a execução da função Pai termina. Entretanto, somente
pode ser acessada por execuções subseqüêntes da função Pai.
Variaveis Locais
Revisão: 02/12/2004
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Variáveis locais são pertencentes apenas ao escopo da função onde foram declaradas.
Devem ser explicitamente declaradas com o identificador LOCAL, como no exemplo:
Function Pai()
Local nVar := 10, aMatriz := {0,1,2,3}
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, a variável nVar foi declarada como local e atribuída com o valor 10.
Quando a função Filha é executada, nVar ainda existe mas não pode ser acessada.
Quando a execução da função Pai terminar, a variável nVar é destruída. Qualquer
variável com o mesmo nome no programa que chamou a função Pai não é afetada.
Variáveis locais são criadas automaticamente cada vez que a função onde forem
declaradas for ativada. Elas continuam a existir e mantêm seu valor até o fim da
ativação da função (ou seja, até que a função retorne o controle para o código que a
executou). Se uma função é chamada recursivamente (por exemplo, chama a si mesma),
cada chamada em recursão cria um novo conjunto de variáveis locais.
A visibilidade de variáveis locais é idêntica ao escopo de sua declaração. Ou seja, a
variável é visível em qualquer lugar do código fonte em que foi declarada. Se uma
função é chamada recursivamente, apenas as variáveis locais criadas na mais recente
ativação são visíveis.
A declaração de variáveis locais dentro de uma função deve preceder qualquer
comando interno ou declaração de outros tipos de variáveis (Private ou Public) da
função caso contrário será gerado um erro de compilação.
Exemplo:
Function A( )
Private x:= 0
Local b:=0 <<<<< ERRADO, ERRO DE COMPILAÇÃO
...
Return
Versão correta:
Function A( )
Local b:=0 // correto
Private x:=0
....
Return
Variaveis Privadas
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
A declaração é opcional para variáveis privadas. Mas podem ser declaradas
explicitamente com o identificador PRIVATE.
Adicionalmente, a atribuição de valor a uma variável não criada anteriormente
automaticamente cria a variável como privada. Uma vez criada, uma variável privada
continua a existir e mantem seu valor até que o programa ou função onde foi criada
termine (ou seja, até que a função onde foi criada retorne para o código que a executou).
Neste momento, é automaticamente destruída.
É possível criar uma nova variável privada com o mesmo nome de uma variável já
existente. Entretanto, a nova (duplicada) variável pode apenas ser criada em um nível de
ativação inferior ao nível onde a variável foi declarada pela primeira vez (ou seja,
apenas em uma função chamada pela função onde a variável já havia sido criada). A
nova variável privada irá esconder qualquer outra variável privada ou pública (veja a
documentação sobre variáveis públicas) com o mesmo nome enquanto existir.
Uma vez criada, uma variável privada é visível em todo o programa enquanto não for
destruída automaticamente quando a rotina que a criou terminar ou uma outra variável
privada com o mesmo nome for criada em uma subfunção chamada (neste caso, a
variável existente torna-se inacessível até que a nova variável privada seja destruída).
Em termos mais simples, uma variável privada é visível dentro da função de criação e
todas as funções chamadas por esta, a menos que uma função chamada crie sua própria
variável privada com o mesmo nome.
Por exemplo:
Function Pai()
Private nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, a variável nVar é criada como privada e inicializada com o valor 10.
Quando a função Filha é executada, nVar ainda existe e, diferente de uma variável local,
pode ser acessada pela função Filha. Quando a função Pai terminar, nVar será destruída
e qualquer declaração de nVar anterior se tornará acessível novamente.
Variaveis Publicas
Revisão: 13/07/2002
Abrangência
Versão 5.07 Versão 5.08 Versão 6.09 Versão 7.10 Versão 8.11
Versões Anteriores
Pode-se criar variáveis públicas dinamicamente no código com o identificador PUBLIC.
As variáveis públicas continuam a existir e mantêm seu valor até o fim da execução.
É possível criar uma variável privada com o mesmo nome de uma variável pública
existente. Entretanto, não é permitido criar uma variável pública com o mesmo nome de
uma variável privada existente.
Uma vez criada, uma variável pública é visível em todo o programa onde foi declarada
até que seja escondida por uma variável privada criada com o mesmo nome. A nova
variável privada criada esconde a variável pública existente, e esta se tornará inacessível
até que a nova variável privada seja destruída. Por exemplo:
Function Pai()
Public nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, nVar é criada como pública e inicializada com o valor 10. Quando a
função Filha é executada, nVar ainda existe e pode ser acessada. Diferente de variáveis
locais ou privadas, nVar ainda existe após o término da a execução da função Pai.
Diferentemente dos outros identificadores de escopo, quando uma variável é declarada
como pública sem ser inicializada, o valor assumido é falso (.F.) e não nulo (nil).