0% acharam este documento útil (0 voto)
171 visualizações246 páginas

Propriedades e Métodos de Classes Visuais

TSRCOBJECT é uma classe abstrata que define características comuns a todos os objetos visuais em AdvPL, como posicionamento, propriedades de texto e cores. Ela contém propriedades como posição, tamanho, texto e cores, além de métodos para manipulação dos objetos. MSDialog deve ser usada como janela padrão para entrada de dados e é do tipo modal, não permitindo interação com outras janelas. TButton cria botões que podem executar ações ao serem clicados. TCheckbox cria controles de seleção com dois estados

Enviado por

Edson Borges
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOC, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
171 visualizações246 páginas

Propriedades e Métodos de Classes Visuais

TSRCOBJECT é uma classe abstrata que define características comuns a todos os objetos visuais em AdvPL, como posicionamento, propriedades de texto e cores. Ela contém propriedades como posição, tamanho, texto e cores, além de métodos para manipulação dos objetos. MSDialog deve ser usada como janela padrão para entrada de dados e é do tipo modal, não permitindo interação com outras janelas. TButton cria botões que podem executar ações ao serem clicados. TCheckbox cria controles de seleção com dois estados

Enviado por

Edson Borges
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOC, PDF, TXT ou leia on-line no Scribd

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).

Você também pode gostar