How to create an optional parameter in ADVPL?

Asked

Viewed 580 times

4

In several functions documented by Totvs there are optional parameters. I would like to create an optional parameter in my function, how to do?

I’m wanting to make the function updEnvio receive a vector (from recnos) as an optional parameter.

User Function updEnvio(cTabela)
    Local cSQL := ""
    Local cCampo := IIF(SUBS(cTabela,1,1)=='S', SUBS(cTabela,2,2), cTabela)
    Local nStatus := 0

    cSQL := ""
    cSQL += " UPDATE " + RetSqlName(cTabela)
    cSQL += " SET " + cCampo + "_YGSENV = 'S' "
    cSQL += " WHERE 1=1 "
    cSQL += " AND " + cCampo + "_FILIAL = '" + xFilial(cTabela) + "' "
    cSQL += " AND " + cCampo + "_YGSENV <> 'S' "

    nStatus := TcSqlExec(cSQL)

    If (nStatus < 0)
        conout("Oops, TCSQLError: " + TCSQLError())
    Endif
Return

Roughly speaking, I wanted to transform it so that, if the vector was empty, it would update the whole table; however, if it had content, only the elements whose recnos are described in that vector. Using the C++ logic to be, I would write the default value of the parameter in your statement. So my pseudo ADVPL code goes like this:

User Function updEnvio(cTabela, aRecnos := {})
    Local cSQL := ""
    Local cCampo := IIF(SUBS(cTabela,1,1)=='S', SUBS(cTabela,2,2), cTabela)
    Local nStatus := 0
    Local i

    cSQL := ""
    cSQL += " UPDATE " + RetSqlName(cTabela)
    cSQL += " SET " + cCampo + "_YGSENV = 'S' "
    cSQL += " WHERE 1=1 "
    cSQL += " AND " + cCampo + "_FILIAL = '" + xFilial(cTabela) + "' "
    cSQL += " AND " + cCampo + "_YGSENV <> 'S' "

    If LEN(aRecnos) > 0
      cSql += " AND R_E_C_N_O_ IN ("
      cSql += STR(aRecnos[1])
      For i := 2 to len(aRecnos)
        cSql += "," + STR(aRecnos[i])
      Next i
      cSql += ")"
    Endif

    nStatus := TcSqlExec(cSQL)

    If (nStatus < 0)
        conout("Oops, TCSQLError: " + TCSQLError())
    Endif
Return

2 answers

3


Before we adopt a correct nomenclature: What is the difference between parameter and argument?. Parameter are never optional, or they exist or do not exist, it is not as in Javascript. Arguments can be optional. And what you want to know is if the parameters can have their values initialized if the argument referring to it is not the past.

It is not possible with this syntax, the language does not support what you want in the question. She has a trick to facilitate what she wants (by the way it was I who created it in 1994 and until today it is in the same way, a resource of include) using default.

User Function updEnvio(cTabela, aRecnos)
    Local cSQL := ""
    Local cCampo := IIF(SUBS(cTabela,1,1)=='S', SUBS(cTabela,2,2), cTabela)
    Local nStatus := 0
    Local i
    Default aRecnos := {}

    cSQL := ""
    cSQL += " UPDATE " + RetSqlName(cTabela)
    cSQL += " SET " + cCampo + "_YGSENV = 'S' "
    cSQL += " WHERE 1=1 "
    cSQL += " AND " + cCampo + "_FILIAL = '" + xFilial(cTabela) + "' "
    cSQL += " AND " + cCampo + "_YGSENV <> 'S' "

    If LEN(aRecnos) > 0
      cSql += " AND R_E_C_N_O_ IN ("
      cSql += STR(aRecnos[1])
      For i := 2 to len(aRecnos)
        cSql += "," + STR(aRecnos[i])
      Next i
      cSql += ")"
    Endif

    nStatus := TcSqlExec(cSQL)

    If (nStatus < 0)
        conout("Oops, TCSQLError: " + TCSQLError())
    Endif
Return

I put in the Github for future reference.

With the default the value will only be assigned if nothing comes as a parameter. I mean, they took what I created and turned it into official syntax, when it actually had an obvious syntax better when they decided to put it in the language.

As a curiosity open the file protheus.ch that you have access to customize and look for the excerpt (not to mention that it is identical to what I did, I used Iif() always so as not to confuse visually with a command If parentheses):

#xcommand DEFAULT <uVar1> := <uVal1> ;
      [, <uVarN> := <uValN> ] => ;
    <uVar1> := If( <uVar1> == nil, <uVal1>, <uVar1> ) ;;
   [ <uVarN> := If( <uVarN> == nil, <uValN>, <uVarN> ); ]

A curiosity that few know is that you can use the preprocessor, which is much more powerful than C, and create named arguments, which end up being even more useful because in essence the language does not work with objects (has a very bad and inefficient implementation, so avoid using).

  • When the workaround becomes official syntax

  • 1

    @Jeffersonquesado edited, in fact it is still what I had created :D

-1

In ADVPL the parameters of a function are optional. Parameters not provided come with value nil.

Example:

#include "protheus.ch"

user function test(xParm)
  if xParm != nil
    conout("xParm=" + xParm)
  else
    conout("nao recebeu parametros!")
  end if

  return

That’s it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.