VT100 em ADVPL: Guia Completo para Dominar a Automação no Protheus

A programação para coletores de dados VT100 refere-se ao desenvolvimento de software para dispositivos que utilizam o protocolo de terminal VT100, amplamente usado em sistemas de automação e coleta de dados, especialmente em ambientes corporativos que utilizam o ERP TOTVS Protheus.


Introdução

No universo do desenvolvimento ADVPL para TOTVS Protheus, a programação VT100 representa uma ferramenta essencial para criação de interfaces e automação de processos em ambientes de terminal. Este guia definitivo mergulhará profundamente no mundo das funções VT100, oferecendo aos programadores uma compreensão abrangente e prática desta tecnologia fundamental.


O que é VT100?

VT100 é um padrão de terminal desenvolvido originalmente pela Digital Equipment Corporation (DEC) que se tornou um modelo de referência para comunicação e interface em sistemas de terminais. No contexto do Protheus, as funções VT100 permitem a criação de interfaces de usuário em ambientes de texto, especialmente para dispositivos móveis e coletores de dados.


Histórico de Desenvolvimento

A implementação das funções VT100 no Protheus tem uma história interessante. Segundo informações do documento original, Alexandro Valário desempenhou um papel crucial no desenvolvimento dessas bibliotecas. Na época, a Microsiga (atual TOTVS) buscava soluções para equipamentos de mobilidade que atendessem suas necessidades específicas.

VT100 em ADVPL

Fundamentos Técnicos

Conceitos Básicos de VT100

VT100 opera em um ambiente de texto puro, onde cada caractere na tela é representado por uma posição específica. As coordenadas são definidas por linhas (vertical) e colunas (horizontal), começando do canto superior esquerdo (0,0).


Bibliotecas e Funções Disponíveis

As principais bibliotecas para programação VT100 no Protheus estão contidas no arquivo apvt100.ch. Este header file deve ser incluído em todos os programas que utilizam funções VT100:


Sintaxe Advpl
#INCLUDE "APVT100.CH"

Modelos de Terminal

Existem três principais modelos de terminal suportados:

  • MT16 (16 teclas)
  • MT44 (44 teclas)
  • RF (Rádio Frequência)
  • Você pode identificar o modelo atual utilizando a função VTModelo():

    Sintaxe Advpl
    If VTModelo() == "RF"
        VTAlert("Coletor de Rádio Frequência")
    Else
        VTAlert("Microterminal Padrão")
    EndIf


    Funções Principais VT100: Referência Definitiva


    1. VTSay - Exibição de Dados

    Objetivo:

    Exibe dados em coordenadas específicas da tela.

    Sintaxe:

    @ <nLinha>, <nColuna> VTSAY <Expressão> [PICTURE <Mascara>]

    Parâmetros Descrição
    nLinha Número da linha (0 a VTMAXROW())
    nColuna Número da coluna (0 a VTMAXCOL())
    Expressão Conteúdo a ser exibido
    Mascara Formatação opcional
    Sintaxe Advpl VTSay
    nQtd := 15.45
    @ 1, 0 VTSAY "Quantidade: " + Transform(nQtd, "@E 999.99")


    2. VTGet - Entrada de Dados

    Objetivo:

    Permite a entrada interativa de dados pelo usuário.

    Sintaxe:

    @ <nLinha>, <nColuna> VTGET <variavel> [PICTURE <Mascara>] [VALID <Validacao>] [F3 <Consulta>]

    Parâmetros Descrição
    nLinha Número da linha (0 a VTMAXROW())
    nColuna Número da coluna (0 a VTMAXCOL())
    variavel Variável que receberá o valor
    Mascara Formatação opcional
    Validacao Expressão de validação
    Consulta Código da consulta padrão (F3)
    Sintaxe Advpl VTGet
    cCodigo := Space(6)
    @ 0, 0 VTSAY "Código: "
    @ 0, 8 VTGET cCodigo PICTURE "@!" VALID !Empty(cCodigo)


    3. VTRead - Ativação de Gets

    Objetivo:

    Ativa a edição em tela usando objetos VTGet.

    Sintaxe:

    VTREAD

    Sintaxe Advpl VTRead
    cNome := Space(30)
    cCPF := Space(11)
    
    @ 1, 1 VTSAY "Nome:" VTGET cNome
    @ 2, 1 VTSAY "CPF: " VTGET cCPF PICTURE "@R 999.999.999-99"
    
    VTREAD

    Caso de uso: Essencial para processar múltiplos campos de entrada em uma única tela.



    4. VTInkey() - Captura de Teclas

    Objetivo:

    Extrai um caractere do buffer de teclado.

    Sintaxe:

    nTecla := VTInkey([nSegundos])

    Parâmetros Descrição
    nSegundos Tempo de espera (opcional)
    Sintaxe Advpl VTInkey
    While .T.
        nTecla := VTInkey(1)
        If nTecla == 27  // ESC
            Exit
        EndIf
    EndDo


    5. VTLastKey() - Última Tecla Pressionada

    Objetivo:

    Retorna o código da última tecla pressionada.

    Sintaxe:

    nUltimaTecla := VTLastKey()

    Sintaxe Advpl VTLastKey
    If VTLastKey() == 27  // ESC
        VTAlert("Operação cancelada")
        Return
    EndIf


    6. VTAlert() - Mensagens de Alerta

    Objetivo:

    Exibe mensagens rápidas para o usuário.

    Sintaxe:

    VTAlert(<cMensagem>, [<cTitulo>], [<lCentralizado>], [nTempo], [nBeep])

    Parâmetros Descrição
    cMensagem Texto da mensagem
    cTitulo Título do alerta (opcional)
    lCentralizado Se verdadeiro, centraliza a mensagem
    nTempo Tempo de exibição em milissegundos
    nBeep Número de beeps
    Sintaxe Advpl VTAlert
    VTAlert("Produto não cadastrado", "Aviso", .T., 2000, 1)

    Caso de uso: Ideal para feedback rápido ao usuário em operações de validação ou confirmação.



    7. VTYesNo() - Confirmação de Ações

    Objetivo:

    Solicita confirmação do usuário.

    Sintaxe:

    lConfirmacao := VTYesNo(<cMensagem>, [<cTitulo>], [<lCentralizado>])

    Parâmetros Descrição
    cMensagem Texto da mensagem
    cTitulo Título do alerta (opcional)
    lCentralizado Se verdadeiro, centraliza a mensagem
    Sintaxe Advpl VTYesNo
    If VTYesNo("Confirma a exclusão?", "Atenção", .T.)
        // Procede com a exclusão
    Else
        VTAlert("Operação cancelada")
    EndIf

    Caso de uso: Essencial para operações críticas que requerem confirmação do usuário.



    8. VTAchoice() - Criação de Menus

    Objetivo:

    Permite criar menus interativos.

    Sintaxe:

    nOpcao := VTACHOICE(<nTopo>, <nEsquerda>, <nBase>, <nDireita>, <aOpcoes>, [<aSelecao>], [<cFuncaoUsuario>],[<nItemInicial>], [lNaoBranco], [<lMsg>], [<nLinhaJanela>],[<lScroll>])

    Parâmetros Descrição
    nTopo, nEsquerda Coordenadas do canto superior esquerdo da janela
    nBase, nDireita Coordenadas do canto inferior direito da janela
    aOpcoes Array com as opções do menu
    aSelecao Array de itens selecionáveis (opcional)
    cFuncaoUsuario Função de controle personalizada. É o nome de uma função definida pelo usuário que é executada quando uma tecla não reconhecível for pressionada. O nome da função é especificado como uma expressão caractere sem parênteses ou argumentos. Note que o comportamento de VTACHOICE() é afetado pela presença deste argumento.
    nItemInicial posição ocupada no vetor de <aOpcoes> pelo item que aparecer em destaque quando o menu for exibido pela primeira vez. Caso você especifique um item de menu que não esteja disponível, ou caso você não use argumento algum, o item que aparecer em destaque será o primeiro item selecionável do vetor.
    lNaoBranco Se for verdadeiro a opções do menu será montado conforme o tamanho da opção desconsiderando os espaços em branco à direita e esquerda. Caso seja negativa ou omitida a opção do menu será montado conforme a dimensão da tela do VTACHOICE definida em <nEsquerda> e <nDireita>.
    lMsg Conteúdo tem que ser NIL, parâmetro reservado para implementação futura.
    nLinhaJanela É o número da linha da janela na qual o item de menu inicial aparecerá.
    Sintaxe Advpl VTAchoice
    aOpcoes := {"Incluir", "Alterar", "Excluir", "Visualizar"}
    
    // Monta a tela
    @0,0 VTSAY "Opcoes:"
    
    // Monta a lista de opcoes
    While nMenu < 0
        nMenu := VTAChoice( 2, 0, VTMaxRow(), VTMaxCol(), aOpcoes, , "ACDV311VLD", nMenu )
    End

    Caso de uso: Perfeito para criação de menus principais ou submenus em aplicações.

    Modos de VTACHOICE():

    • 0 = Inativo;
    • 1 = Tentativa de passar início da lista;
    • 2 = Tentativa de passar final da lista;
    • 3 = Normal;
    • 4 = Itens não selecionados.


    9. VTAbrowse() - Browse de Arrays

    Objetivo:

    Cria um browse baseado em um array.

    Sintaxe:

    nPos := VTAbrowse(<nTopo>, <nEsquerda>, <nBase>, <nDireita>, <aCabecalho>, <aItens>, <aTamanhos>, [<cFuncaoUsuario>])

    Parâmetros Descrição
    nTopo, nEsquerda Coordenadas do canto superior esquerdo da janela
    nBase, nDireita Coordenadas do canto inferior direito da janela
    aCabecalho Array que contem os títulos das colunas
    aItens Array que contem os dados a serem mostrados
    aTamanhos Array que contem o tamanho de cada coluna
    cFuncaoUsuario Nome de uma função definida pelo usuário que é executada quando uma tecla não reconhecível for pressionada. O nome da função é especificado como uma expressão caractere sem parênteses ou argumentos. Note que o comportamento de VTABROWSE() é afetado pela presença deste argumento.
    Sintaxe Advpl VTAbrowse
    aCab      := {"Código", "Descrição", "Valor"}
    aItens    := {{"001", "Produto A", 100.00}, {"002", "Produto B", 150.00}}
    aTam      := {10, 20, 10}
    
    nPos      := VTAbrowse(0, 0, 10, 40, aCab, aItens, aTam)

    Caso de uso: Ideal para exibição de listas de dados em formato tabular.

    Modos de VTABROWSE():

    • 0 = Inativo;
    • 1 = Tentativa de passar início da lista;
    • 2 = Tentativa de passar final da lista;
    • 3 = Normal;
    • 4 = Itens não selecionados.

    Valores de Retorno da Função de Controle de VTABROWSE():

    • 0 = Aborta seleção;
    • 1 = Executa seleção;
    • 2 = Continua VTABROWSE();
    • 3 = Vai para o próximo item cuja primeira letra for a tecla pressionada.


    10. VTDBBrowse() - Browse de Banco de Dados

    Objetivo:

    Cria um browse baseado em uma tabela do banco de dados.

    Sintaxe:

    nRecno := VTDBBrowse(<nTopo>, <nEsquerda>, <nBase>, <nDireita>, <cAlias>, <aCampos>, <aTamanhos>, [<cFuncaoUsuario>], [<cTop>], [<cBottom>])

    Parâmetros Descrição
    nTopo, nEsquerda Coordenadas do canto superior esquerdo da janela
    nBase, nDireita Coordenadas do canto inferior direito da janela
    cAlias Alias da tabela
    aCampos Array com os campos a serem exibidos
    aTamanhos Array com larguras das colunas
    cFuncaoUsuario Nome de uma função definida pelo usuário que é executada quando uma tecla não reconhecível for pressionada. O nome da função é especificado como uma expressão caractere sem parênteses ou argumentos. Note que o comportamento de VTDBBROWSE () é afetado pela presença deste argumento
    cTop String com a condição de validação de top
    cBottom String com a condição de validação de Bottom
    Sintaxe Advpl VTDBBrowse
    aCampos     := {"B1_COD", "B1_DESC", "B1_PRV1"}
    aTamanhos   := {15, 30, 10}
    
    nRecno      := VTDBBrowse(0, 0, 10, 60, "SB1", aCampos, aTamanhos)

    Caso de uso: Essencial para navegação e seleção de registros em tabelas do Protheus.

    Retorno:

  • VTDBBROWSE () retorna o recno()
  • Se o processo de seleção for interrompido, VTDBBROWSE () retorna zero.

  • Modos de VTDBBROWSE():

    • 0 = Inativo;
    • 1 = Tentativa de passar início da lista;
    • 2 = Tentativa de passar final da lista;
    • 3 = Normal;
    • 4 = Itens não selecionados.

    Valores de Retorno da Função de Controle de VTDBBROWSE():

    • 0 = Aborta seleção;
    • 1 = Executa seleção;
    • 2 = Continua VTABROWSE();
    • 3 = Vai para o próximo item cuja primeira letra for a tecla pressionada.


    11. VTClear() - Limpeza de Tela

    Objetivo:

    Limpa a tela do terminal.

    Sintaxe:

    VtClear()

    Sintaxe Advpl VtClear
    VTClear()
    @ 0, 0 VTSAY "Nova Tela"

    Caso de uso: Utilizado para limpar a tela antes de apresentar novas informações.



    12. VTSave() - Salvamento de Tela

    Objetivo:

    Permite salvar o conteúdo da tela para restaurar posteriormente

    Sintaxe:

    aTela := VTSave(<nTopo>, <nEsquerda>, <nBase>,<nDireita>)

    Parâmetros Descrição
    nTopo, nEsquerda Coordenadas do canto superior esquerdo da janela
    nBase, nDireita Coordenadas do canto inferior direito da janela
    Sintaxe Advpl VTSave
    aTela := VTSave(0, 0, 5, 20)

    Caso de uso: Útil para criar janelas temporárias ou preservar partes da tela durante operações.



    13. VTRestore() - Restauração de Tela

    Objetivo:

    Permite restaurá o conteúdo da tela salvo por VTSave()

    Sintaxe:

    VTRestore(<nTopo>, <nEsquerda>, <nBase>,<nDireita>, aTela)

    Parâmetros Descrição
    nTopo, nEsquerda Coordenadas do canto superior esquerdo da janela
    nBase, nDireita Coordenadas do canto inferior direito da janela
    aTela Possui o conteúdo da tela a ser exibida
    Sintaxe Advpl VTRestore
    aTela := VTSave(0, 0, 5, 20)
    
    // Realiza operações na tela
    VTRestore(0, 0, 5, 20, aTela)

    Caso de uso: Útil para criar janelas temporárias ou preservar partes da tela durante operações.



    14. VTMaxRow() e VTMaxCol() - Dimensões da Tela

    Objetivo:

    Retornam as dimensões máximas da tela.

    Sintaxe:

    nMaxLinha := VTMaxRow()
    nMaxColuna := VTMaxCol()

    Sintaxe Advpl VTMaxRow()
    @ VTMaxRow(), 0 VTSAY "Rodapé da Tela"

    Caso de uso: Essencial para criar layouts adaptáveis a diferentes tamanhos de tela.



    15. VTSetSize() - Dimensões da Tela

    Objetivo:

    Seta o limite da área de trabalho.

    Sintaxe:

    VTSETSIZE(<nLin>, <nCol>) 

    Parâmetros Descrição
    nLin, nCol São as coordenadas máximas de linha e coluna.
    Sintaxe Advpl VTSetSize()
    VTSetSize(8, 20)

    Caso de uso: Essencial para criar layouts adaptáveis a diferentes tamanhos de tela.



    16. VTBeep() - Emissão de Som

    Objetivo:

    Emite um beep sonoro.

    Sintaxe:

    VTBeep([nQuantidade])

    Parâmetros Descrição
    nQuantidade Especifica a quantidade de beep que será emitido. Caso <nQtde> seja omitido, VTBEEP() emitira um beep.
    Sintaxe Advpl VTBeep()
    VTBeep(3)  // Emite 3 beeps

    Caso de uso: Útil para alertas sonoros em situações críticas ou para chamar atenção do usuário.



    17. VTReverso() - Modo Reverso

    Objetivo:

    Ativa ou desativa o modo reverso da tela.

    Sintaxe:

    VTReverso([lAtiva])

    Parâmetros Descrição
    lAtiva Se verdadeiro ativa, falso desativa o modo de tela. Caso <lRev> seja omitido, VTReverso() retorna o modo atual.
    Sintaxe Advpl VTReverso()
    VTReverso(.T.)
    @ 1, 1 VTSAY "Texto em Reverso"
    VTReverso(.F.)

    Caso de uso: Utilizado para destacar informações importantes na tela.



    18. VTKeyBoard() - Simulação de Teclado

    Objetivo:

    Coloca uma string no buffer de teclado.

    Sintaxe:

    VTKeyBoard(<cString>)

    Parâmetros Descrição
    cString Conjunto de caracteres a ser colocado no buffer de teclado.
    Sintaxe Advpl VTKeyBoard()
    VTKeyBoard( Chr(13) )  // Simula pressionar ENTER

    Caso de uso: Útil para automação de testes ou preenchimento automático de campos.



    19. VTClearBuffer() - Limpa o buffer de teclado

    Objetivo:

    Limpa o buffer de teclado.

    Sintaxe:

    VTClearBuffer()

    Sintaxe Advpl VTClearBuffer()
    VTCLEARBUFFER()

    Caso de uso: Útil para o conteúdo que possa ter ficado.



    Boas Práticas

    Dicas de Otimização

    1. Uso eficiente de VTClear(): Sempre use VTClear() antes de criar novas telas para evitar sobreposição de informações.
    2. advpl
      VTClear()
      @ 0, 0 VTSAY "Nova Tela Limpa"
    3. Definição da Área de Trabalho: Utilize VTSetSize() para definir a área de trabalho adequada ao dispositivo.
    4. advpl
      VTSetSize(8, 40)  // 8 linhas, 40 colunas
    5. Tratamento de Teclas de Saída: Sempre trate teclas de saída com VTLastKey() para permitir que o usuário cancele operações.
    6. advpl
      If VTLastKey() == 27  // ESC
          Return
      EndIf
    7. Uso de Variáveis Locais: Prefira variáveis locais para melhor performance e gestão de memória.
    8. advpl
      Local cNome := Space(30)
      Local nIdade := 0
    9. Validações Eficientes: Implemente validações concisas e eficientes em VTGets.
    10. advpl
      @ 1, 1 VTGET cCPF PICTURE "@R 999.999.999-99" VALID CGC(cCPF)


    Padrões de Desenvolvimento

    1. Nomenclatura Consistente: Use prefixos para identificar tipos de variáveis (c para caractere, n para numérico, etc.).
    2. Comentários Descritivos: Adicione comentários explicativos, especialmente em lógicas complexas.
    3. Modularização: Divida funcionalidades complexas em funções menores e reutilizáveis.
    4. Tratamento de Erros: Implemente tratamento de erros robusto usando VTAlert() para feedback ao usuário.
    5. Documentação de Funções: Documente o propósito, parâmetros e retorno de cada função criada.


    Armadilhas Comuns a Evitar

    1. Não Tratar Teclas de Navegação: Sempre considere teclas como ESC e ENTER.
    2. Esquecer de Limpar Buffer de Teclado: Use VTClearBuffer() antes de operações críticas.
    3. Ignorar Diferentes Modelos de Terminal: Sempre verifique o modelo com VTModelo() e adapte a interface
    4. Sobrecarga de Informações: Evite exibir muitas informações em uma única tela.
    5. Falta de Feedback: Sempre forneça feedback visual ou sonoro para ações do usuário.


    Casos de Uso Avançados

    Exemplo Completo de Aplicação

    advpl
    #INCLUDE "TOTVS.CH"
    #INCLUDE "APVT100.CH"
    
    /*/{Protheus.doc} VTDEMO1
    Programa de exemplo de uso das funcoes de VT100 para microterminal
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @version 1.0
    /*/
    User Function VTDEMO1()
        Local nPos       := 1
        Local cOpcao     := Space(1)
        Local cCodigo    := Space(6)
        Local dData      := CToD("")
        Local cSenha     := Space(6)
        Local nValor     := 0
        Local aOpcoes    := {}
        Local aItens     := {}
        Local aCab       := {}
        Local aSize      := {}
        Local aFields    := {}
        Local aHeader    := {}
    
        VTSetSize(2, 20)
    
        While .T.
            VTClear()
            InitializeVariables(@cCodigo, @dData, @nValor, @cSenha)
            VTClearBuffer()
    
            If !SelectTerminalType(@cOpcao)
                Exit
            EndIf
    
            DisplayDemoInfo()
    
            If !InputUserData(@cCodigo, @dData, @nValor, @cSenha)
                Loop
            EndIf
    
            If !ShowMenuOptions(@aOpcoes, @nPos)
                Loop
            EndIf
    
            ShowBrowserExample(@aItens, @aCab, @aSize, @nPos)
            ShowDBBrowserExample(@aFields, @aSize, @aHeader)
    
            If FinishDemo()
                Exit
            EndIf
    
            VTClearBuffer()
        EndDo
    
    Return .T.
    
    /*/{Protheus.doc} InitializeVariables
    Inicializa as variáveis do programa
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param cCodigo, character, código a ser inicializado
    @param dData, date, data a ser inicializada
    @param nValor, numeric, valor a ser inicializado
    @param cSenha, character, senha a ser inicializada
    /*/
    Static Function InitializeVariables(cCodigo, dData, nValor, cSenha)
        cCodigo := Space(6)
        dData   := CToD("")
        nValor  := 0
        cSenha  := Space(6)
    Return
    
    /*/{Protheus.doc} SelectTerminalType
    Seleciona o tipo de terminal
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param cOpcao, character, opção selecionada
    @return logical, verdadeiro se selecionou uma opção válida
    /*/
    Static Function SelectTerminalType(cOpcao)
        Local lRet := .T.
    
        While .T.
            cOpcao := "1"
            VTClear()
            @ 0,0 VTSAY "1.RF 2.MT44 3.MT16"
            @ 1,0 VTSAY "Selecione: " VTGET cOpcao PICT "9"
            VTRead
    
            If VTLastKey() == 27
                lRet := .F.
                Exit
            EndIf
    
            Do Case
                Case cOpcao == "1"
                    VTSetSize(8,20)
                    Exit
                Case cOpcao == "2"
                    VTSetSize(2,40)
                    Exit
                Case cOpcao == "3"
                    VTSetSize(2,20)
                    Exit
                Otherwise
                    VTClear()
                    @ 0,0 VTSay "Opcao invalida"
                    VTInkey(1000)
            EndCase
        EndDo
    
    Return lRet
    
    /*/{Protheus.doc} DisplayDemoInfo
    Exibe informações do demo
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    /*/
    Static Function DisplayDemoInfo()
        @ 00,00 VTSay PadC("Demo de VT100", If(VTModelo()=="MT16" .or. VTModelo()=="RF",19,39))
        @ 01,00 VTSay "Modelo:" + VTModelo()
    
        If VTLastKey() == 27
            Return
        EndIf
    
        VTInkey(0)
        VTClear()
    Return
    
    /*/{Protheus.doc} InputUserData
    Coleta dados do usuário
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param cCodigo, character, código a ser coletado
    @param dData, date, data a ser coletada
    @param nValor, numeric, valor a ser coletado
    @param cSenha, character, senha a ser coletada
    @return logical, verdadeiro se todos os dados foram coletados com sucesso
    /*/
    Static Function InputUserData(cCodigo, dData, nValor, cSenha)
        Local lRet := .T.
    
        @ 00,00 VTSay "Codigo: "
        @ 00,08 VTGet cCodigo PICT "@!" VALID ValidCod(cCodigo) WHEN WhenCod()
        VTRead
        If VTLastKey() == 27
            lRet := .F.
            Return lRet
        EndIf
    
        @ 01,00 VTSay "Data: "
        @ 01,07 VTGet dData PICT "99/99/99" VALID ValidData(dData) WHEN WhenData()
        VTRead
        If VTLastKey() == 27
            lRet := .F.
            Return lRet
        EndIf
    
        VTClear()
        VTClearBuffer()
    
        @ 00,00 VTSay "Valor: "
        @ 00,07 VTGet nValor PICT "@E 999.99" WHEN WhenValor()
        VTRead
        If VTLastKey() == 27
            lRet := .F.
            Return lRet
        EndIf
    
        @ 01,00 VTSay "Senha: "
        @ 01,07 VTGet cSenha PASSWORD VALID (VTAlert(cSenha, "Senha Digitada", .T., 1500), .T.) WHEN WhenSenha()
        VTRead
    
        If VTLastKey() == 27
            lRet := .F.
            Return lRet
        EndIf
    
    Return lRet
    
    /*/{Protheus.doc} ShowMenuOptions
    Exibe opções de menu
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param aOpcoes, array, opções do menu
    @param nPos, numeric, posição selecionada
    @return logical, verdadeiro se uma opção foi selecionada
    /*/
    Static Function ShowMenuOptions(aOpcoes, nPos)
        Local lRet := .T.
    
        VTClear()
        VTAlert("Entrando no Achoice...","[-]", .T., 1500)
        VTClear()
        VTClearBuffer()
    
        aOpcoes := {"Opcao 1", "Opcao 2", "Opcao 3", "Opcao 4", "Opcao 5"}
        nPos := VTaChoice(0, 0, VTMaxRow(), VTMaxCol(), aOpcoes, , "U_VldAchVT", nPos)
    
        If VTLastKey() == 27
            lRet := .F.
        EndIf
    
    Return lRet
    
    /*/{Protheus.doc} ShowBrowserExample
    Exibe exemplo de browser
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param aItens, array, itens do browser
    @param aCab, array, cabeçalho do browser
    @param aSize, array, tamanhos das colunas
    @param nPos, numeric, posição selecionada
    /*/
    Static Function ShowBrowserExample(aItens, aCab, aSize, nPos)
        VTAlert("Entrando no aBrowser... aguarde...", "[-]", .T., 1500)
    
        aItens := {{"1010 ",10, "DESCRICAO1","UN "},;
                    {"2010 ",20,"DESCRICAO2","CX "},;
                    {"2020 ",30,"DESCRICAO3","CX "},;
                    {"2010 ",40,"DESCRICAO4","CX "},;
                    {"2020 ",50,"DESCRICAO5","CX "},;
                    {"3010 ",60,"DESCRICAO6","CX "},;
                    {"3020 ",70,"DESCRICAO7","CX "},;
                    {"3030 ",80,"DESCRICAO7","CX "},;
                    {"3040 ",90,"DESCRICAO7","CX "},;
                    {"2010 ",100,"DESCRICAO4","CX "},;
                    {"2010 ",110,"DESCRICAO4","CX "},;
                    {"2020 ",120,"DESCRICAO5","CX "},;
                    {"3010 ",130,"DESCRICAO6","CX "},;
                    {"3020 ",140,"DESCRICAO7","CX "},;
                    {"3030 ",150,"DESCRICAO7","CX "},;
                    {"3050 ",160,"DESCRICAO7","CX "}}
    
        aCab  := {"Codigo","Cod","Descricao","UM"}
        aSize := {10,4,20,10}
        nPos  := 1
        nPos  := VTaBrowse(,,,,aCab,aItens,aSize,,nPos)
    Return
    
    /*/{Protheus.doc} ShowDBBrowserExample
    Exibe exemplo de DBBrowser
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param aFields, array, campos do DBBrowser
    @param aSize, array, tamanhos das colunas
    @param aHeader, array, cabeçalho do DBBrowser
    /*/
    Static Function ShowDBBrowserExample(aFields, aSize, aHeader)
        VTAlert("Entrando no DBBrowser... aguarde...", "[-]", .T., 2000)
    
        aFields := {"B1_COD", "B1_DESC", "B1_UM", "B1_PICM"}
        aSize   := {16, 20, 10, 15}
        aHeader := {"COD", "DESCRICAO", "UM", "% ICM"}
    
        SB1->( dbSeek(xFilial()) )
        VTDBBrowse(,,,, "SB1", aHeader, aFields, aSize)
    Return
    
    /*/{Protheus.doc} FinishDemo
    Verifica se o usuário deseja finalizar o demo
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @return logical, verdadeiro se o usuário deseja finalizar
    /*/
    Static Function FinishDemo()
        Local lRet := .F.
    
        VTClearBuffer()
        If VTYesNo("Deseja finalizar?", "Pergunta")
            lRet := .T.
        EndIf
    
        If VTLastKey() == 27
            lRet := .F.
        EndIf
    
    Return lRet
    
    /*/{Protheus.doc} ValidCod
    Valida o código inserido
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param cCodigo, character, código a ser validado
    @return logical, sempre retorna verdadeiro
    /*/
    Static Function ValidCod(cCodigo)
        Local aTela := VTSave(0, 0, VTMaxRow(), VTMaxCol())
    
        VTAlert("Total de bytes:" + AllTrim( Str(Len(AllTrim(cCodigo))) ), "Validando:", .T., 2000)
        VTClear()
        VTRestore(0, 0, VTMaxRow(), VTMaxCol(), aTela)
    
    Return .T.
    
    /*/{Protheus.doc} WhenCod
    Função executada antes da entrada do código
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @return logical, sempre retorna verdadeiro
    /*/
    Static Function WhenCod()
        Local aTela := VTSave(0, 0, VTMaxRow(), VTMaxCol())
    
        VTAlert("Exemplo de Get" + Chr(13) + Chr(10) + "com Caracter", "[-]ATENCAO", .T., 2000)
        VTClear()
        VTRestore(0, 0, VTMaxRow(), VTMaxCol(), aTela)
    
    Return .T.
    
    /*/{Protheus.doc} WhenData
    Função executada antes da entrada da data
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @return logical, sempre retorna verdadeiro
    /*/
    Static Function WhenData()
        Local aTela := VTSave(0, 0, VTMaxRow(), VTMaxCol())
    
        VTAlert("Exemplo de Get" + Chr(13) + Chr(10) + "com Data", "[-]ATENCAO", .T., 2000)
        VTClear()
        VTRestore(0, 0, VTMaxRow(), VTMaxCol(), aTela)
    
    Return .T.
    
    /*/{Protheus.doc} WhenValor
    Função executada antes da entrada do valor
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @return logical, sempre retorna verdadeiro
    /*/
    Static Function WhenValor()
        Local aTela := VTSave(0, 0, VTMaxRow(), VTMaxCol())
    
        VTAlert("Exemplo de Get" + Chr(13) + Chr(10) + "com Numerico", "[-]ATENCAO", .T., 2000)
        VTClear()
        VTRestore(0, 0, VTMaxRow(), VTMaxCol(), aTela)
    
    Return .T.
    
    /*/{Protheus.doc} WhenSenha
    Função executada antes da entrada da senha
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @return logical, sempre retorna verdadeiro
    /*/
    Static Function WhenSenha()
        Local aTela := VTSave(0, 0, VTMaxRow(), VTMaxCol())
    
        VTAlert("Exemplo de Get" + Chr(13) + Chr(10) + "com Senha", "[-]ATENCAO", .T., 2000)
        VTClear()
        VTRestore(0, 0, VTMaxRow(), VTMaxCol(), aTela)
    
    Return .T.
    
    /*/{Protheus.doc} ValidData
    Valida a data inserida
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param dData, date, data a ser validada
    @return logical, verdadeiro se a data for válida
    /*/
    Static Function ValidData(dData)
        Local lRet := .T.
    
        If Empty(dData)
            lRet := .F.
            VTAlert("Data Invalida", "Atencao", .T., 2000)
        EndIf
    
    Return lRet
    
    /*/{Protheus.doc} VldAchVT
    Função de validação para VTAChoice
    @type function
    @author DOTHINK - ERIKE
    @since 10/11/2023
    @param modo, numeric, modo de operação
    @param nElem, numeric, elemento atual
    @param nElemW, numeric, elemento em foco
    @return numeric, código de retorno para VTAChoice
    /*/
    User Function VldAchVT(modo, nElem, nElemW)
        Local nRet := 2
    
        If modo == 1
            VTAlert("Inicio do Achoice", "-", .T., 1000)
        ElseIf modo == 2
            VTAlert("Fim do Achoice", "-", .T., 1000)
        Else
            If VTLastKey() == 27
                VTAlert("Saindo do Achoice", "-", .T., 1000)
                VTBeep(1)
                nRet := 0
            ElseIf VTLastKey() == 13
                VTAlert("Tecla  pressionada", "-", .T., 1000)
                VTBeep(1)
                nRet := 1
            EndIf
        EndIf
    
    Return nRet


    Conclusão: Dominando VT100 em ADVPL com a DOTHINK

    Ao longo deste guia abrangente, exploramos o universo da programação VT100 em ADVPL, uma habilidade essencial para desenvolvedores que trabalham com o TOTVS Protheus. Como especialistas em VT100 na consultoria Protheus DO THINK entendemos a importância crucial dessas técnicas para o desenvolvimento de soluções eficientes e robustas.

    Recapitulando os pontos-chave:

    1. Versatilidade em Coletores de Dados e Microterminais: As funções VT100 oferecem um conjunto poderoso de ferramentas para criar interfaces eficientes em diversos modelos de coletores de dados e microterminais. Esta versatilidade permite que desenvolvedores criem soluções adaptáveis a diferentes ambientes operacionais, desde armazéns e linhas de produção até operações de campo. Na fábrica de sofware da DOTHINK, aproveitamos essa flexibilidade para desenvolver aplicações personalizadas que atendem às necessidades específicas de cada cliente, garantindo eficiência e precisão na coleta de dados em qualquer cenário.
    2. Eficiência na Coleta de Dados: A implementação precisa dessas funções resulta em aplicações ágeis e responsivas, cruciais para operações de coleta de dados em tempo real, inventário e logística - áreas onde a DOTHINK possui extensa experiência e expertise.
    3. Integração Perfeita com Protheus: A integração seamless das soluções VT100 com o ecossistema Protheus permite estender as funcionalidades do ERP para dispositivos móveis de coleta, um aspecto que nossa fábrica de software prioriza em cada projeto de automação.
    4. Boas Práticas para Soluções Móveis:Adotar código limpo e seguir as melhores práticas não só melhora a qualidade do software para coletores de dados, mas também facilita a manutenção e atualização - princípios fundamentais na fábrica de software da DOTHINK.

    Para saber mais sobre como podemos ajudar sua empresa a maximizar o potencial do Protheus com soluções VT100 personalizadas para coletores de dados e microterminais, entre em contato para uma consultoria especializada em soluções de mobilidade e coleta de dados.



    Dúvidas? Fale com um de nossos especialistas!

    Somos uma empresa de desenvolvimento, suporte e soluções em Software de Gestão Empresarial com a missão de trazer resultados efetivos para o seu negócio.

    Do Think Soluções Inteligentes

    Se você esta pensando em implantar, potencializar, suportar seu Software de Gestão, ou se quiser apenas obter mais informações, teremos o maior prazer em responder a todas as suas perguntas. Basta preencher o formulário ao lado com a sua solicitação.