Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: Previsão de Horas para Customizações em ERP TOTVS

_Créditos da imagem: Gerada com auxílio do ChatGPT_ --- # **Previsão de Horas para Customizações em ERP TOTVS: Uma Abordagem Baseada em Fatores de Complexidade** No universo de customizações para o ERP da TOTVS, uma das etapas mais desafiadoras é a estimativa precisa do esforço necessário para o desenvolvimento. Muitas vezes, projetos aparentemente simples podem se tornar complexos devido a fatores como dificuldade de acesso ao ambiente ou falta de conhecimento da regra de negócio. Por isso, criamos uma metodologia de cálculo baseada em fatores de ajuste para tornar as estimativas mais precisas e confiáveis. ## **Por que uma boa estimativa é essencial?** Um orçamento mal calculado pode impactar diretamente o cronograma, os custos e até a qualidade da entrega. No caso de projetos relacionados ao ERP TOTVS, onde cada customização está ligada a regras de negócios específicas e a um ambiente muitas vezes complexo, subestimar ou superestimar o tempo necessário pode gerar problemas sign

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..."

Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema.


#INCLUDE "PROTHEUS.CH"
#INCLUDE "TBICONN.CH"
/*/
 Funcao:  MATA010Ex
 Data:  30/04/2011
 Autor:  Marinaldo de Jesus
 Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus
 Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou
    2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando )
/*/
User Function MATA010Ex( cEmpFil )

 Local aEmpFil

 Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) }
 
 Local cEmp
 Local cFil
 Local cMod
 Local cModName  := "SIGAFAT"
 
 DEFAULT cEmpFil  := "01;01"
 
 aEmpFil    := StrTokArr( cEmpFil , ";" )
 
 cEmp    := aEmpFil[1]
 cFil    := aEmpFil[2]

 SetModulo( @cModName , @cMod )
 
 PREPARE ENVIRONMENT EMPRESA( cEmp ) FILIAL ( cFil ) MODULO ( cMod )

   InitPublic()

   SetsDefault()

   SetModulo( @cModName , @cMod )

  DEFINE WINDOW oMainWnd FROM 001,001 TO 400,500 TITLE OemToAnsi( FunName() )
    ACTIVATE WINDOW oMainWnd MAXIMIZED ON INIT ( Eval( bWindowInit ) , oMainWnd:End() )
 
 RESET ENVIRONMENT

Return( NIL )

/*/
 Funcao:  SetModulo
 Data:  30/04/2011
 Autor:  Marinaldo de Jesus
 Descricao: Setar o Modulo em Execucao
 Sintaxe: SetModulo( @cModName , @cMod )
/*/
Static Function SetModulo( cModName , cMod )

 Local aRetModName := RetModName( .T. )
 
 Local cSvcModulo
 Local nSvnModulo
 
 IF ( Type("nModulo") == "U" )
  _SetOwnerPrvt( "nModulo" , 0 )
 Else
  nSvnModulo := nModulo
 EndIF
 
 cModName := Upper( AllTrim( cModName ) )
 IF ( nModulo <> aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } ) )
  nModulo := aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } )
  IF ( nModulo == 0 )
   cModName := "SIGAFAT"
   nModulo  := aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } )
  EndIF
 EndIF
 
 IF ( Type("cModulo") == "U" )
  _SetOwnerPrvt( "cModulo" , "" )
 Else
  cSvcModulo := cModulo
 EndIF
 
 cMod := SubStr( cModName , 5 )
 IF ( cModulo <> cMod )
  cModulo := cMod
 EndIF

Return( { cSvcModulo , nSvnModulo  } )

Para executá-la chame-a diretamente na Tela de Entrada do sistema como U_MATA010Ex ou através de linha de comando como: totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l

Generalizando, poderíamos ter uma função de Propósito Geral para esse fim como em:


#INCLUDE "PROTHEUS.CH"
#INCLUDE "TBICONN.CH"

#DEFINE TOKEN_VALUE   Chr(63)
#DEFINE TOKEN_PARAMETERS Chr(38)

/*/
 Funcao:  EvalPrg
 Data:  30/04/2011
 Autor:  Marinaldo de Jesus
 Descricao: Executar a Funcao diretamente sem a necessidade de LOGIN no Protheus
 Sintaxe: totvsclient.exe -q -p=U_EvalPrg a="Emp?01&Fil?01&FunName?MATA010&ModName?SIGAFAT" -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando )
/*/
User Function EvalPrg( cParameters )

 Local aParameters

 Local bWindowInit  := { || __Execute( cFunName+"()" , "xxxxxxxxxxxxxxxxxxxx" , cFunName , cModName , cModName , 1 , .T. ) }
 
 Local cEmp
 Local cFil
 Local cMod
 Local cParam
 Local cFunName
 Local cModName

 Local cTknValue   := TOKEN_VALUE
 Local cTknParameters := TOKEN_PARAMETERS

 
 Local nParam
 Local nParameters
 
 DEFAULT cParameters  := "Emp?01&Fil?01&FunName?MATA010&ModName?SIGAFAT"
 
 aParameters    := StrTokArr( cParameters , TOKEN_PARAMETERS )
 
 nParameters    := Len( aParameters )
 
 For nParam := 1 To nParameters
  cParam := Lower( aParameters[ nParam ] )
  DO CASE
   CASE ( "emp" $ cParam )
    cEmp := StrTokArr( cParam , TOKEN_VALUE  )[2]
   CASE ( "fil" $ cParam ) 
    cFil := StrTokArr( cParam , TOKEN_VALUE  )[2]
   CASE  ( "funname" $ cParam ) 
    cFunName := StrTokArr( cParam , TOKEN_VALUE  )[2]
   CASE  ( "modname" $ cParam )  
    cModName := StrTokArr( cParam , TOKEN_VALUE  )[2]
  ENDCASE  
 Next nParam

 DEFAULT cEmp  := "01"
 DEFAULT cFil  := "01"
 DEFAULT cFunName := "MATA010"
 DEFAULT cModName := "SIGAFAT"

 SetModulo( @cModName , @cMod )
 
 PREPARE ENVIRONMENT EMPRESA( cEmp ) FILIAL ( cFil ) MODULO ( cMod )

   InitPublic()

   SetsDefault()
   
   SetModulo( @cModName , @cMod )

  DEFINE WINDOW oMainWnd FROM 001,001 TO 400,500 TITLE OemToAnsi( FunName() )
    ACTIVATE WINDOW oMainWnd MAXIMIZED ON INIT ( Eval( bWindowInit ) , oMainWnd:End() )
 
 RESET ENVIRONMENT

Return( NIL )

/*/
 Funcao:  SetModulo
 Data:  30/04/2011
 Autor:  Marinaldo de Jesus
 Descricao: Setar o Modulo em Execucao
 Sintaxe: SetModulo( @cModName , @cMod )
/*/
Static Function SetModulo( cModName , cMod )

 Local aRetModName := RetModName( .T. )
 
 Local cSvcModulo
 Local nSvnModulo
 
 IF ( Type("nModulo") == "U" )
  _SetOwnerPrvt( "nModulo" , 0 )
 Else
  nSvnModulo := nModulo
 EndIF
 
 cModName := Upper( AllTrim( cModName ) )
 IF ( nModulo <> aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } ) )
  nModulo := aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } )
  IF ( nModulo == 0 )
   cModName := "SIGAFAT"
   nModulo  := aScan( aRetModName , { |x| Upper( AllTrim( x[2] ) ) == cModName } )
  EndIF
 EndIF
 
 IF ( Type("cModulo") == "U" )
  _SetOwnerPrvt( "cModulo" , "" )
 Else
  cSvcModulo := cModulo
 EndIF
 
 cMod := SubStr( cModName , 5 )
 IF ( cModulo <> cMod )
  cModulo := cMod
 EndIF

Return( { cSvcModulo , nSvnModulo  } )

Neste caso, executaríamos sempre via linha de comando.

Lembrando que os "Parâmetros" do Remote, em linha de Comando são:


Parâmetros da Linha de Comando do Protheus Remote

Ao ser iniciado, o Protheus Remote exibe a tela de parâmetros iniciais, para
identificação do Ambiente, da Conexão e do APO inicial. Porém, tais informações
podem ser informadas através da linha de comando do ícone de acesso ao Protheus
Remote.

As opções de linha de comando do Protheus Remote são:
-Q (Quiet): Indica que o Protheus Remote não deve mostrar o Splash (imagem
de apresentação) e a tela de identificação de parâmetros iniciais necessita ser
acompanhada da cláusula –P;
-P (Main Program): Identifica o programa (APO) inicial;
-R (CfgSection): Nome da seção de configuração. Por default, é “Config”;
-E (Environment): Nome da seção de environment no .INI do Server que será
utilizada para definições gerais;
-C (Connection): Nome da seção de conexão que será utilizada para a conexão ao
Protheus Server;
-A (Parâmetros para o Programa Inicial): Identifica um parâmetro que será passado
para o programa inicial;
-L (MP8 Remote Log File): Para não-conformidades que ocorram no Protheus
Remote (antes que este possa se conectar ao Protheus Server), é gerado um arquivo
de log no diretório de execução deste aplicativo.
Este arquivo tem o nome definido pela identificação do executável (MP8Rmt) +
um caracter de underline (_) + o nome da máquina em que o Protheus Remote
está sendo executado (com extensão .LOG).
Esta opção permite informar um nome específico para a geração deste arquivo de
log, visando automatizações específicas que necessitem saber quando uma não-
conformidade ocorreu no Protheus Remote (por exemplo, impossibilidade de
conexão).
-M (AllowMultiSession): Permite múltiplas instâncias (Cópias) do Protheus
Remote na mesma máquina (Default: não permite);
Por exemplo, pode-se utilizar a seguinte linha de comando:
totvsclient.exe -Q -P=SIGAEST -E=ENV_TOP_ENGLISH


Para baixar os exemplos, clique aqui.

[]s

иαldσ dj


Ps.: Considerando que alguns programas possuem tratamento especifico na abertura do Módulo, por exemplo PMS410, pode ocorrer, na chamada direta, uma "Exception". Sendo assim, recomendo que esse método só seja usado para programas "customizados" ou no qual tenha a plena certeza de que todas as dependências sejam carregadas na execução da própria função.

Comentários

  1. Be my dad!

    Cara já pensou em lançar um livro ou
    uma apostila, иαldσ dj desvendando o AdvPL.

    Pô meu, sou seu fã mesmo!

    ResponderExcluir
  2. Ainda me falta, além do conhecimento, o formalismo necessário para tal fim (rs). Mas está nos planos.... e se sabe como é... planos são planos... (rs). Mas alguém poderia ter a paciência de "compilar" tudo o que já escrevi em um livro ou apostila, o que acha?

    []s

    иαldσ dj

    ResponderExcluir
    Respostas
    1. Olá, abriu a rotina como vc propos, porém as mensagens em tela não aparecem nenhuma. Tipo se clicar em incluir e confirmar sem preencher os campos padrões, não aparece mensagem alguma. É normal? Versão protheus 11

      Excluir
  3. Aff, achei que era impossivel.
    Muito Obrigado Naldo, me salvou em um projeto, assim poderei fazer uma solução muito bacana para um necessidade da empresa em que trabalho.

    T+ :)

    ResponderExcluir
  4. иαldσ dj,
    Utilizando esse código que você postou, quando excede o número de licenças ele apresenta uma tela de error, tem como tratar essa mensagem, pra um tipo mais amigável? Como?

    ResponderExcluir
  5. Rapaz fiz o codigo tudo certinho mudei o que era necessario, ai quando executo aparece uma janela com o titulo de RPC e logo apos ela some

    ResponderExcluir
  6. Anônimo,

    envie o código para mail@blacktdn.com.br. Assim que tiver um tempinho dou uma olhada.

    ResponderExcluir
  7. Naldo, Boa Tarde...

    Primeiramente parabens pelo trabalho maravilhoso que vc vem realizando com este Blog, tem salvado a pele de muita gente inclusive a minha.

    Cara tem como ajudar? É o seguinte estou fazendo a integracao entre o Protheus e um sistema proprietario em xHarbour, uma dessas integracoes por exemplo é de documentos de entrada. Do lado do xHarbour ele disponibiliza em umas tabelas o documento e do lado do Protheus o mesmo lê estas informações nestas tabelas e processa via Execauto. A principio esta integração não seria on-line, será atraves de um Schedule no Protheus que de tempos em tempos ele lerá a tabela e executará a inclusão das notas. Porem Gostaria de saber se existe alguma forma de eu transformar esta rotina on-line.

    Tipo assim fazer o sistema em xHarbour gravar nestas tabelas intermediarias e ele mesmo chamar uma rotina no Protheus e executa-la.

    Tentei utilizar o seu exemplo, porem nao consegui. Vc tem algum exemplo, onde atraves do Harbour eu consiga chamar uma funcao do protheus?

    Obrigado,
    Bruno

    ResponderExcluir
  8. Boa tarde, primeiramente parabéns pelo blog. pesquisando no google achei sua dica de como iniciar um programa sem login. Peguei o seu como exemplo e funcionou perfeitamente mas montei uma tela que chama outras rotinas e relatorios porém os relatorios (padrão) do totvs não abre as perguntas dos parametros. sabe como posso ajustar isso?
    abraços.

    ResponderExcluir
    Respostas
    1. Quando via RPC o sistema entra em modo Blind (e por isso as perguntas dos relatórios não aparecem) a solução é bem simples. Após o PREPARE ENVIRONMENT altere o conteúdo da variável __cInternet de "AUTOMATICO" para NIL como em: __cInternet := NIL.

      Excluir
    2. Mais uma vez parabéns é muito bom pegar conhecimento com pessoas que realmente entende. Funcionou perfeitamente o unico problema agora é que os relatórios dá erro abaixo:

      THREAD ERROR (darne, DARNE-PC) 19/10/2012 22:39:02
      variable is not array - Type [U] on MSSPOOL:SHOW(APLIB280.PRW) 02/05/2012 09:57:20 line : 593

      Obrigado.
      Darne

      Excluir
    3. Darne, MsSpool() necessita de informações de usuário para habilitar algumas configurações e como não achou ou não identificou o usuário corrente gerou o erro em questão. Existem duas soluções bem simples:

      1) Quando preparar o ambiente informe usuário e senha de forma a identificar o usuário para MsSpool. Segundo e Terceiros parametros de RpcSetEnv. Ex.: RpcSetEnv(cEmp,cFil,cUser,cPwd). Se, ao invés da chamada à função estiver utilizando o comando PREPARE ENVIRONMENT, informe USER e PASSWORD.

      PREPARE ENVIRONMENT EMPRESA (cEmp) FILIAL (cFil) USER (cUser) PASSWORD (cPwd)

      2) Uma outra solução, caso não queria passar usuário e senha na preparação do ambiente, é alterar a variável publica que contem o ID do usuário: __cUserID. __cUserID, quando da preparação do ambiente sem informar o usuário e senha, vai estar vazia (gerando o erro em questão). Neste caso, force __cUserID sempre como "000000" que corresponde ao ID do Administrador. Como em: __cUserID := "000000". (Recomendo o método anterior uma vez que saberá quem emitiu o relatório).

      Obs.: Lembre-se de atribuir o valor a __cUserID, caso opte pela opção 2, sempre após o PREPARE ENVIRONMENT.

      Excluir
  9. Só tenho a dizer uma coisa, muuuuuiito obrigado, ambas as solucões funcionou perfeitamente. Valeu Naldo, você é féra...

    Darne

    ResponderExcluir
    Respostas
    1. Darne, legal que ambas as soluções funcionaram perfeitamente. Essa é a idéia de BlackTDN propor soluções que funcionem.

      Excluir
  10. Naldo,

    Como posso utilizar o TEMAP10 neste metodo?

    Eu tentei utilizar o PtSetTheme("TEMAP10") man não dá certo ... porém se utilizar assim :

    Local lNewApp := ((Select("SM0")==0) .or. !(Type("oApp")=="O"))
    If (lNewApp)
    MsApp():New(cModulo)
    oApp:lMenu := lMenu
    oApp:lShortCut := .F.
    oApp:cInternet := NIL
    oApp:cModDesc := cTitulo
    oApp:bMainInit := { || MsgRun("Aguarde...",,{|| U_funcao(lNewApp)})}
    SetFunName(cInternal)
    PtSetTheme(cTema)
    oApp:CreateEnv()
    oApp:RunApp(.T.)
    Else
    U_Funcao(lNewApp)
    EndIf

    dá certo ... porem dá erro no Final na hora de fechar ...

    Tem alguma ideia ?

    Abrass

    Daniel Ratkevicius

    ResponderExcluir
  11. Este comentário foi removido pelo autor.

    ResponderExcluir
  12. eaw
    cara estou com uma duvido
    na minha empresa usamos maquinas linux e maquinas windows estamos mudando agora para a versão 11
    e eu e a equipe colocamos os atalhos em todas as maquinas mais de 200, porem existe alguns espertinhos que alteram a programa inicial onde vai "siga...", resumindo queria saber se tem como colocar algum parametro no smartclient.ini que impedisse de abrir o splash inicial
    desde ja agradeço

    ResponderExcluir
    Respostas
    1. SR Protheus, não me lembro se existe parâmetro para esse fim, mas existem pontos de Entrada que possibilitariam a validação da função de Entrada.

      Existem os Pontos de Entrada Genérico dos Módulos (SIGA+Prefixo do Modulo, ex.: SIGAGPE, SIGAFIN, SIGAFAT, SIGACOM, SIGAetc...) que você poderia implementar e validar o acesso. A questão do Ponto de Entrada Genérico e que você teria que implementá-los um a um.

      Além dos Pontos Entrada Genéricos, existem os seguintes Pontos de Entrada que Poderão validar o acesso:

      PswValid, ChgPrDir, PswSize, CallChgXNU, MODNAME, etc.

      Neles você fará o teste e se o Programa inicial não for o SIGAADV, por exemplo, emitirá uma mensagem informando sobre o acesso inválido.

      Um Exemplo Simples:

      User Function PswValid()
      IF .NOT.( IsInCallStack("SIGAADV") ) //Verifica se o Acesso foi feito pelo SIGAADV
      Final(OemToAnsi("Acesso Inválido"),OemToAnsi("Utilize SIGAADV")) //Finaliza o Sistema caso contrário
      EndIF
      Return( .T . )

      O miolo do código acima serve para os demais Pontos de Entrada...

      User Function ChgPrDir()
      Local cRelDir := IF( ( Type( "__RELDIR" ) == "C" ) , __RELDIR , NIL )
      IF .NOT.( IsInCallStack("SIGAADV") ) //Verifica se o Acesso foi feito pelo SIGAADV
      Final(OemToAnsi("Acesso Inválido"),OemToAnsi("Utilize SIGAADV")) //Finaliza o Sistema caso contrário
      EndIF
      Return( cRelDir )

      User Function PswSize()
      IF .NOT.( IsInCallStack("SIGAADV") ) //Verifica se o Acesso foi feito pelo SIGAADV
      Final(OemToAnsi("Acesso Inválido"),OemToAnsi("Utilize SIGAADV")) //Finaliza o Sistema caso contrário
      EndIF
      Return(ParamIXB)

      ... etc.

      Vale apenas Observar que deve tratar o retorno do Ponto de Entrada que for utilizar de acordo com o esperado. No seu caso, acredito que a melhor opção seja PswValid.

      []s

      иαldσ dj

      Excluir
  13. Naldo,

    Obrigado pelo seu trabalho aqui no BLOG. Sou relativamente novo em ADVPL / Protheus, a uns 6 meses quando eu comecei a pesquisar e estudar, entrei aqui e vi que "o buraco era mais em baixo" e agora, vez ou outra consigo aprender com vocês.

    Especialmente sobre esse post, eu queria saber se existe uma forma mais simples de se chamar uma função (ou programa, ou tela), mesmo sendo necessário efetuar o Login.

    Exemplo: abrir a inclusão de pedido de vendas ou a tela de cadastro de clientes.

    Outra dúvida que eu tenho é de como descobrir o nome das funções dos botões do AXCadastro. Normalmente eu entro no help online e pesco alguma coisa do arquivo html do help (é esquisito, mas foi o que eu achei: http://help.outsourcing.com.br/p11/portuguese/***MATA121***_pedido_de_compra.htm).

    Valeu!

    ResponderExcluir
  14. Naldo,

    Obrigado pelo trabalho de vocês aqui no blog. Sou novo no PROTHEUS / ADVPL, mas quando comecei a pesquisar, passei por aqui e vi que "o buraco é mais em baixo". Hoje já consigo aprender um pouco com vocês.

    Especialmente sobre esse post, queria saber se não existe uma forma mais simples de chamar uma função (ou tela, ou programa) diretamente da command line, mesmo sendo necessário se fazer o Login. Exemplo: abrir a inclusão do Pedido de Venda ou abrir a tela de cadastro de clientes.

    Outra dúvida que eu tenho é como saber quais funções são chamadas pelos botões da AXCadastro, nas telas padrão do sistema. O que eu tenho feito (é esquisito, mas era o que eu conhecia) é pescar alguma coisa do Help do P11, tipo isso: http://help.outsourcing.com.br/p11/portuguese/***MATA121***_pedido_de_compra.htm.

    Se você poder me indicar também algum post sobre como o TOTVS operacionaliza o conceito de workflow, eu tbm agradeço.

    Valeu!

    ResponderExcluir
  15. Este comentário foi removido pelo autor.

    ResponderExcluir
  16. Boa tarde!

    Seu blog é excelente, parabéns! Temos Totvs Logix em nossa empresa há 15 anos e agora estamos usando a Folha Protheus (SIGA GPE).
    Temos desenvolvimento interno em Informix 4GL e agora aprendendo ADVPL.
    Seguinte, usei esse post para criar um programa para ser executado direto pelo Smarclient. Esse programa é para imprimir o recibo de pagamento (a Totvs desenvolveu um recibo gráfico específico pra mim).
    Queremos colocar totens nas unidades para cada funcionário informar sua matricula e uma senha (combinação de cpf, data nascimento, etc) e imprimir seu recibo. Poderíamos usar o Portal Web do Protheus, mas ele é muito complexo para usuários de fábrica, e além disso o recibo é diferente do meu específico.
    O fato é que já conseguimos criar a janela e chamada do REPORT. O problema é que não conseguimos fazer sair na impressora. O ideal é imprimisse diretamente sem preview, assim não correria risco de ficar na tela e outro funcionário visualizar. Porém não conseguimos nem imprimir, nem gerar preview. Como mandar o bendito relatório para a impressora?

    Já tentei todos os códigos abaixo:

    //SET DEVICE TO SCREEN
    //If aReturn[5]==1
    //oPrint:Preview()
    dbCommitAll()
    SET PRINTER TO
    OurSpool(wnrel)
    //Endif

    //Set Printer to "ADM-DESIGN"
    //Set Printer on
    //Set device to printer
    //InitPrint()

    //if !SndToPrnWin(cNomeRel, lPagAtu, lPagInt, nRgStart, nRgEnd )
    //Alert('Relatório não pode ser impresso')
    //else
    //Alert('Relatório impresso com sucesso')
    //endif

    //cNomeRel := "RECIBO"
    //cDrive := ""
    //cNomeImp := "ADM-DESIGN"
    //ctamanho := "M"
    //cAlias := "SRA"
    //lServer := .f.
    //nLastKey := 0
    //
    //cNomeRel:=SetPrint(cAlias,cNomeRel,nil ,titulo,cDesc1,cDesc2,cDesc3,.F.,"",.F.,cTamanho,nil ,nil ,nil ,cDrive,.T. ,lServer,cNomeImp)
    //
    //If nLastKey == 27
    // Set Filter To
    // Return
    //Endif
    //
    //SetDefault(aReturn,cAlias)
    //
    //Set Printer to &cNomeRel
    //Set Printer On
    //Set device to Printer

    ResponderExcluir
  17. Naldo, que deveria trocar pra fazer funcionar este codigo no P11? Eu compile o codigo e recebo o erro "Invalid Class TMDICHILD" na linha do "DEFINE WINDOW".... obrigado!

    ResponderExcluir
  18. Funcionou, mas, ao passar pela linha SRA->(dbsetorder(1)), não reconheceu a tabela (Alias does not exist SRA...).
    Como contornar?
    Obrigado!

    ResponderExcluir
  19. Bom dia иαldσ dj!

    Você saberia me dizer se eu consigo retornar de alguma forma os Parâmetros da Linha de Comando do Protheus Remote? Estamos precisando saber o -C (Connection) que o usuário está acessando logo na abertura do sistema. Como temos um link principal e um de contingência, gostaríamos de saber quando ele está acessando o Protheus pelo link de contingência. Hoje os usuários têm dois atalhos com mesmo Environment, mas com connections diferentes.

    Muito obrigada!

    ResponderExcluir
  20. Boa tarde,

    Alguém sabe como manipular - na rotina CFGA530 - nas Funcionalidades das Transações/Rotinas a coluna Definição da Operação?

    O que está ocorrendo é o seguinte: Necessito criar uma Regra de Bloqueio para a rotina FINA740 (Funções Contas a Receber), para o Menu Compensação (em Ações Relacionadas) e marcar como Não Permitido unica e exclusivamente o botão Excluir, lembrando que no Menu Compensação existem 3 botões (Compensar, Excluir e Estornar), porém, na coluna Definição da Operação todos os três botões estão com o número 4, os botões Excluir e Estornar não obedecem a instrução de Acesso Não Permitido, pois o "mandatário" é o Botão Compensar, se neste for marcado Não Permitido no Acesso, TODOS os três botões passam a ter o Acesso Não Permitido para o usuário ou para o Grupo de Usuários que tiverem esta regra de bloqueio definida.

    ResponderExcluir
  21. Bom dia, tudo
    Alguem sabe de alguma função que checa se a rotina esta em execução, eu utilizei a LOCKBYNAME mas nao funcionou.

    att.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas