Programação

Lógica de Programação AdvPL – Parte 3

Escritor por Vinícius Gregório

 

Olá!

 

Hoje vamos retomar nossa série de artigos sobre lógica de programação (ficou parada por muito tempo!!!) falando um pouco sobre estruturas de decisão.

 

É sempre bom avisar: essa é uma série de artigos para quem está começando a programar agora e teve pouco ou nenhum contato com outras linguagens de programação.

 

Assim como fizemos nos artigos anteriores, utilizaremos a linguagem AdvPL para demonstrar os exemplos.

 

Estruturas de Decisão

 

As estruturas de decisão compõe uma parte extremamente importante nos nossos algoritmos. São elas que definem fluxos diferentes de processamentos das informações, dependendo de uma ou mais condições. O ponto de decisão (duh!) sempre vai ser uma expressão booleana (verdadeiro ou falso), independente da quantidade de operadores necessários para isso.

 

Vamos começar analisando um código-fonte simples:

 

#INCLUDE "PROTHEUS.CH"

/*
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±±
±±ºPrograma  ³XTSTIF      ºAutor  ³V. Gregório         º Data ³  13/04/14   º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºDesc.     ³ Dialog para exemplificar estruturas de decisão               º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºUso       ³ AcademiaERP                                                  º±±
±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
*/
User Function XTSTIF()
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Declaração de variáveis³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Local nRetorno		:= 0
Local oDlg, oGroup, oButton, oCombo, cCombo
Local nPosPadrao	:= 1
Local aOpcoes		:= {"Sim","Não"}
Local cTitDialog	:= "Estruturas de Decisão"
Local cTitGroup		:= "Escolha um dos itens"

DEFAULT nPosPadrao	:= 1

cCombo	:= aOpcoes[nPosPadrao]

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Dialog principal. Na ativação ela é centralizada.³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
DEFINE MSDIALOG oDlg FROM 0,0 TO 100,230 PIXEL TITLE cTitDialog

	oGroup:= TGroup():New(05,05,oDlg:nClientHeight/4,(oDlg:nClientWidth/2)-5,cTitGroup,oDlg,,,.T.)

	oCombo:= tComboBox():New(oDlg:nClientHeight/8,10,{|u|if(PCount()>0,cCombo:=u,cCombo)},;
	aOpcoes,100,20,oDlg,,{||/*onChange*/},,,,.T.,,,,,,,,,aOpcoes[nPosPadrao])

	//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
	//³Botão para o controle de fechamento da janela³
	//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
	oButton:=tButton():New((oDlg:nClientHeight/4)+3,10,"OK",oDlg,{||oDlg:End()},100,10,,,,.T.)

ACTIVATE MSDIALOG oDlg CENTERED

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Define o retorno com base na posição do combo³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
nRetorno	:= aScan(aOpcoes,cCombo)

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³***********************************************³
//³Com base na escolha do usuário, vamos          ³
//³mudar o comportamento da rotina                ³
//³***********************************************³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
If nRetorno	== 1
	MsgInfo("O usuário escolheu a opção: Sim")
Else
	MsgInfo("O usuário escolheu a opção: Não")
EndIf

Return nRetorno

 

Já utilizamos esse fonte anteriormente no artigo de posicionamento dinâmico de tela para o Protheus. Porém, com algumas alterações, ele vai nos servir em diversos exemplos.

 

Caso não entenda alguma função ou trechos do código, não se preocupe. Você aprenderá sobre eles em outros artigos. Vamos focar no seguinte trecho de código:

 

If nRetorno	== 1
	MsgInfo("O usuário escolheu a opção: Sim")
Else
	MsgInfo("O usuário escolheu a opção: Não")
EndIf

 

A rotina exibe uma tela simples para o usuário com um combo com dois itens: Sim e Não. Nesse caso, delegamos para o usuário uma escolha e, dependendo do que ele decidir, o programa irá seguir por um fluxo diferente (onde a posição no array aOpcoes é 1=Sim, 2=Não).

 

Repare que, o desenvolvedor poderia colocar diversos comandos dentro de cada opção (dentro do IF ou do ELSE). Nesse caso, colocamos somente um alerta com a opção escolhida.

 

Outra possibilidade ainda para o IF/ELSE é o fato de podermos encadear mais de uma opção. Veja o exemplo abaixo:

 

If nRetorno == 1
	MsgInfo("O usuário escolheu a opção: Sim")
ElseIf nRetorno == 2
	MsgInfo("O usuário escolheu a opção: Não")
Else
	MsgInfo("Supondo que existisse outra opção")
EndIf

 

Para entender melhor como funcionam as estruturas de decisão, precisamos nos familiarizar com os operadores e ligações (ou conjunções) que compõe essas linhas:

 

Operadores

Fique atualizado, É GRÁTIS!
Cadastre o seu endereço de e-mail e fique por dentro de todas as atualizações da AcademiaERP.
Não enviamos spam.

:= : Esse operador serve para a definição do valor de uma variável, ou seja, quando colocamos cVariavel := “Texto”, estamos atribuindo a string “Texto” para a variável cVariavel. Uma atribuição retorna .T. quando ela é bem sucedida.

 

== : Comparação de valores. Esse operador permite comparar o valor de duas variáveis ou expressões e, caso sejam iguais, retorna .T. Exemplo: “Texto” == “Texto” -> .T. , “texto” == “Texto” -> .F.

 

<> ou != : Diferente de… Verifica se o valor de duas variáveis ou expressões são diferentes. É o contrário de ==. Exemplo: “Texto” <> “Texto” -> .F. , “texto” <> “Texto” -> .T.

 

$ : Contido. Verifica se um determinado conteúdo está contido dentro de outro conjunto de conteúdos. Confuso não?!

 

Exemplo:

 

Local cNumeros	:= "1234567890"
Local cTeste		:= "1"

If  cTeste $ cNumeros
	//vai entrar no if pq o texto "1" está dentro da cadeia de caracteres armazenada na variável cNumeros
EndIf

 

() : os parânteses são utilizados para delimitar o processamento de uma expressão. Exatamente como funciona em expressões algébricas (lembra disso certo?), os parênteses internos são resolvidos antes dos parânteses externos. Exemplo: nValor := ((55*30)/100) -> 16,5

 

Ligações

 

As estruturas de decisão podem ser compostas por uma ou mais expressões booleanas. Ou seja, existem formas de unir expressões e o resultado dessa união é que determina o resultado da estrutura.

 

.and. : Em tradução livre: e.

 

If cCor == "amarelo" .and. cFormato <> "triangulo"
EndIf

 

No exemplo acima, o IF só será .T. se a variável cCor estive preenchida com “amarelo” e se a variável cFormato não estiver preenchida com “triangulo”.

 

.or. : Em tradução livre: ou.

 

If cCor == "amarelo" .or. cFormato <> "triangulo"
EndIf

 

No exemplo acima, o IF só será .T. caso ou cCor esteja preenchida com “amarelo” ou cFormato seja diferente de “triangulo”. Caso qualquer uma dessas afirmações seja verdadeira, a condição geral será atendida.

 

.xor. : Bom, esse não tem “tradução livre”….. .xor. é o código para eXclusive Or. Veja:

 

If cCor == "amarelo" .xor. cFormato <> "triangulo"
EndIf

 

A expressão desse IF só será verdadeira em uma dessas situações:

  1. cCor está com o valor “amarelo” E cFormato é igual a “triangulo”;
  2. cFormato não é igual a “triangulo” e cCor não é igual a “amarelo”;

 

Ou seja, o .XOR. só retorna verdadeiro se apenas uma das condições for verdadeira (obrigatóriamente a(s) outra(s) tem que ser falsas). Bizarro e raramente você vai irá encontrar isso em fontes mas, se encontrar, já não precisa se assustar 😉

 

.not. ou ! : Esses itens servem pra negar a expressão seguinte. Basicamente, a condição será verdadeira caso o resultado seja o oposto da expressão. Exemplos:

 

If .not. cCor == "amarelo"
EndIf

If !(cCor == "amarelo")
EndIf

 

Em ambos os exemplos o resultado será .T. se cCor estiver preenchido com qualquer valor, exceto “amarelo”.

 

DO CASE

 

A estrutura DO CASE permite que o programa analise diversas condições para a decisão no código. Vamos ao exemplo:

 

#INCLUDE "PROTHEUS.CH"

/*
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±±
±±ºPrograma  ³XTSTCASE    ºAutor  ³V. Gregório         º Data ³  13/04/14   º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºDesc.     ³ Dialog para exemplificar estruturas de decisão               º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºUso       ³ AcademiaERP                                                  º±±
±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
*/
User Function XTSTCASE()
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Declaração de variáveis³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Local nRetorno		:= 0
Local oDlg, oGroup, oButton, oCombo, cCombo
Local nPosPadrao	:= 1
Local aOpcoes		:= {"Sim","Não","Talvez","Quem sabe..."}
Local cTitDialog	:= "Estruturas de Decisão"
Local cTitGroup		:= "Escolha um dos itens"

DEFAULT nPosPadrao	:= 1

cCombo	:= aOpcoes[nPosPadrao]

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Dialog principal. Na ativação ela é centralizada.³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
DEFINE MSDIALOG oDlg FROM 0,0 TO 100,230 PIXEL TITLE cTitDialog

	oGroup:= TGroup():New(05,05,oDlg:nClientHeight/4,(oDlg:nClientWidth/2)-5,cTitGroup,oDlg,,,.T.)

	oCombo:= tComboBox():New(oDlg:nClientHeight/8,10,{|u|if(PCount()>0,cCombo:=u,cCombo)},;
	aOpcoes,100,20,oDlg,,{||/*onChange*/},,,,.T.,,,,,,,,,aOpcoes[nPosPadrao])

	//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
	//³Botão para o controle de fechamento da janela³
	//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
	oButton:=tButton():New((oDlg:nClientHeight/4)+3,10,"OK",oDlg,{||oDlg:End()},100,10,,,,.T.)

ACTIVATE MSDIALOG oDlg CENTERED

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Define o retorno com base na posição do combo³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
nRetorno	:= aScan(aOpcoes,cCombo)

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³***********************************************³
//³Com base na escolha do usuário, vamos          ³
//³mudar o comportamento da rotina                ³
//³***********************************************³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Do Case
	Case nRetorno == 1 // Sim
		MsgInfo("O usuário escolheu a opção: Sim")
	Case nRetorno == 2 // Não
		MsgInfo("O usuário escolheu a opção: Não")
	Case nRetorno == 3 // Talvez
		MsgInfo("O usuário escolheu a opção: Talvez")
	Case nRetorno == 4 // Quem sabe...
		MsgInfo("O usuário escolheu a opção: Quem sabe...")
EndCase

Return nRetorno

 

A estrutura que nos interessa no código é o Do Case no final. Como podem ver, sua estrutura é bem robusta e indicativa das condições dos respectivos trechos de código.

 

Conclusão

 

Chegamos ao final de mais um artigo e, depois de assimilado todo o conteúdo, já nos preparamos para o próximo. Nele, vamos estudar como funcionam as estruturas de repetição (FOR e WHILE) no AdvPL… Abraços e até lá!

 

http://vidadeprogramador.com.br

http://vidadeprogramador.com.br

Sobre o Autor

Vinícius Gregório

Tecnólogo em análise de sistemas da informação pela Faculdade IBTA (SP), empreendedor da área de TI e consultor Protheus especializado em desenvolvimento AdvPL. Trabalhou em diversos projetos com os módulos de Compras, Estoque/Custos, Faturamento, Contabilidade Gerencial, Field Service/Gestão de Serviços, Financeiro, Gestão de Contratos e Gestão de Projetos. Atua também como desenvolvedor de sistemas web e é usuário fanático de sistemas e softwares open source... (vinicius.gregorio@academiaerp.com.br)

Deixe um comentário

Dúvida?