Objectives
After completing this lesson, you will be able to:
- Descreva as funções de string integradas no ABAP.
- Trabalhe com funções de string integradas no ABAP.
- Explicar a utilização de expressões regulares no ABAP.
Funções de cadeia integradas
Além da concatenação de cadeia com o operador && e formatação com modelos de cadeia, o ABAP oferece uma grande variedade de funções de cadeia integradas. Com base no tipo do resultado, distinguimos entre três categorias de funções de cadeia:
Nota
Se a entrada de uma função de string integrada for composta por vários parâmetros, o nome do parâmetro de entrada principal será sempre val.
Parâmetros de funções de cadeia
Para algumas funções de string integradas, a entrada consiste em apenas um objeto de dados em forma de caractere. Essas funções não usam parâmetros de entrada. A entrada é especificada diretamente entre parênteses. A função de descrição NUMOFCHAR( ) é um bom exemplo para este tipo de funções.
Funções com mais de um parâmetro de utilização de entrada com nomes e a entrada é atribuída a esses parâmetros. Muitos parâmetros são um terreno comum entre diferentes funções de string incorporadas. Os parâmetros mais importantes são os seguintes:
- VAL
Você transfere a cadeia de texto a ser processada pela função para o valor de parâmetro. Você também pode indicar chamadas de método funcionais, expressões de tabela e expressões construtoras cujo valor de retorno é conversível para o tipo cadeia. Só é possível processar tipos de dados elementares. Se for indicado um objeto de dados em forma de caractere com um comprimento fixo, todos os espaços em branco posteriores são ignorados. Os valores de retorno não em forma de caractere são convertidos no tipo de dados string.
- SUB
O parâmetro sub é utilizado para transferir uma cadeia de caracteres cujos caracteres devem ser procurados ou inseridos. Somente argumentos com tipos elementares podem ser especificados. Se for indicado um objeto de dados em forma de caractere com um comprimento fixo, todos os espaços em branco posteriores são ignorados.
- CASE
As pesquisas e comparações em funções de cadeia são dependentes de maiúsculas/minúsculas por padrão, mas isso pode ser substituído, se necessário, utilizando o parâmetro maiúsculas/minúsculas. O caso de parâmetro requer a entrada do tipo abap_bool (C LENGTH 1) com o valor das constantes abap_true ('X') ou abap_false (' '). Se maiúsculas/minúsculas contiver o valor de abap_true, a pesquisa considera maiúsculas/minúsculas; se contiver o valor de abap_false, não é.
- OCC
Em funções de string onde as pesquisas são realizadas, o parâmetro occ especifica a ocorrência de uma correspondência. Se occ é positivo, as ocorrências são contadas a partir da esquerda; se occ é negativo, elas são contadas a partir da direita. Os valores 1, 2, .... indicam a primeira, a segunda, ... ocorrências. Os valores -1, -2, .... indicam as últimas, penúltimo, ... ocorrências. O valor padrão de occ é 1.
Nota
Exceto no caso da substituição da função de substituição, o valor 0 aciona a exceção CX_SY_STRG_PAR_VAL. Se for utilizado Substituir, o valor 0 substitui todas as ocorrências.
- OFF e LEN
O parâmetro off é utilizado para transferir um offset e o parâmetro len é utilizado para transferir um comprimento. Em funções em que off e len podem ser transferidos, eles determinam a subárea na qual uma cadeia deve ser processada.
O valor proposto de off é geralmente 0 e o valor proposto de len é definido para o comprimento da cadeia completa após o offset.
Nota
Combinações inadequadas de valores podem levar à exceção CX_SY_RANGE_OUT_OF_BOUNDS.
Vejamos alguns exemplos para ver o impacto desses parâmetros:
Testar: parâmetros comuns de funções de cadeia
- Crie uma nova classe global que implemente a interface IF_OO_ADT_CLASSRUN.
- Copie o seguinte snippet de código para a parte de implementação do método if_oo_adt_classrun~main( ):
12345678910111213141516171819
DATA text TYPE string VALUE ` Let's talk about ABAP `.
DATA result TYPE i.
out->write( text ).
result = find( val = text sub = 'A' ).
*
* result = find( val = text sub = 'A' case = abap_false ).
*
* result = find( val = text sub = 'A' case = abap_false occ = -1 ).
* result = find( val = text sub = 'A' case = abap_false occ = -2 ).
* result = find( val = text sub = 'A' case = abap_false occ = 2 ).
*
* result = find( val = text sub = 'A' case = abap_false occ = 2 off = 10 ).
* result = find( val = text sub = 'A' case = abap_false occ = 2 off = 10 len = 4 ).
out->write( |RESULT = { result } | ).
- Selecione CTRL + F3 para ativar a classe e F9 para executá-la como um aplicativo de console.
- Analise a saída do console.
- Remova os comentários antes das diferentes chamadas da função FIND( ) e ative o programa novamente.
- Depurar o programa e analisar o conteúdo do resultado do objeto de dados após cada atribuição. Você consegue entender os diferentes resultados?
- Jogue com os diferentes parâmetros para se familiarizar com seu significado.
Funções de descrição
- Funções de comprimento
Um grupo importante de funções de descrição para cadeias são as funções de comprimento NUMOFCHAR( ) e STRLEN( ). Na maioria das vezes, as duas funções retornam o mesmo resultado. No entanto, há uma exceção: se o argumento é do tipo string e contém um ou mais espaços em branco no final, o resultado de STRLEN( ) inclui esses espaços em branco à direita, enquanto NUMOFCHAR( ) os ignora. Para argumentos com comprimento fixo, por exemplo, argumentos de TYPE C ou N, ambas as funções ignoram os espaços em branco no final.
- Grupos de funções de pesquisa
Existem dois grupos de funções de pesquisa para cadeias:
A função COUNT( ) e as funções que começam com COUNT_...( ) retornam o número total de ocorrências de um argumento de pesquisa. A função FIND( ) e as funções que começam com FIND_( ) retornam a posição (offset) de uma determinada ocorrência de um argumento de pesquisa.
- Subparâmetro em funções de pesquisa
As funções COUNT( ) e FIND( ) podem procurar uma subcadeia (parâmetro opcional sub) ou uma expressão regular (parâmetro opcional pcre). Discutiremos as expressões regulares mais adiante neste curso.
No caso de funções que terminam com _ANY_OF, o nome do parâmetro sub é um pouco enganoso. Aqui, o valor do parâmetro sub não é uma subcadeia, mas sim uma lista de caracteres. Em vez de procurar a subcadeia, ou seja, a combinação exata de caracteres, essas funções avaliam os caracteres individuais e consideram cada caractere como uma correspondência que faz parte da lista fornecida. As funções que terminam com _ANY_NOT_OF funcionam de forma semelhante, mas aqui somente esses caracteres são considerados uma correspondência que são diferentes de todos os caracteres na lista.
Veja alguns exemplos das funções de descrição.
Testar: funções de descrição
- Crie uma nova classe global que implemente a interface IF_OO_ADT_CLASSRUN.
- Copie o seguinte snippet de código para a parte de implementação do método if_oo_adt_classrun~main( ):
1234567891011121314151617181920212223242526
DATA result TYPE i.
DATA text TYPE string VALUE ` ABAP `.
DATA substring TYPE string VALUE `AB`.
DATA offset TYPE i VALUE 1.
* Call different description functions
******************************************************************************
* result = strlen( text ).
* result = numofchar( text ).
result = count( val = text sub = substring off = offset ).
* result = find( val = text sub = substring off = offset ).
* result = count_any_of( val = text sub = substring off = offset ).
* result = find_any_of( val = text sub = substring off = offset ).
* result = count_any_not_of( val = text sub = substring off = offset ).
* result = find_any_not_of( val = text sub = substring off = offset ).
out->write( |Text = `{ text }`| ).
out->write( |Substring = `{ substring }` | ).
out->write( |Offset = { offset } | ).
out->write( |Result = { result } | ).
- Selecione Ctrl + F3 para ativar a classe e F9 para executá-la como um aplicativo de console.
- Analise a saída do console.
- Remova os comentários antes das diferentes avaliações do resultado variável e ative o programa novamente.
- Defina um ponto de parada e analise o conteúdo do resultado do objeto de dados após cada atribuição. Você consegue entender os diferentes resultados?
- Reproduza com os valores iniciais para texto e substring para se familiarizar com as funções.
Funções de processamento
Assista ao vídeo a seguir para saber mais sobre as funções de processamento.
Dica
Um bom caso de utilização para SEGMENT( ) é a importação e o processamento de dados em um formato de valores separados por vírgulas (csv).
Vejamos alguns exemplos para ilustrar o resultado de algumas funções de processamento de cadeia:
- Neste exemplo, a cadeia de entrada contém uma mistura de letras maiúsculas e minúsculas. A função TO_UPPER( ) transforma todos em letras maiúsculas.
- A função TO_MIXED( ) converte a cadeia em uma mistura de letras maiúsculas e minúsculas. Ele procura uma string separadora, remove a mesma e transforma o primeiro caractere após o separador em maiúsculas. Todos os outros caracteres são transformados em minúsculas. Considere que o parâmetro sep é opcional com o sinal de sublinhado (_) como seu valor proposto.
- A função REVERSE( ) retorna os caracteres em ordem inversa.
- O primeiro exemplo da função SHIFT_LEFT( ) especifica places = 2. Portanto, os dois primeiros caracteres (##) são removidos do resultado.
- O segundo exemplo para SHIFT_LEFT( ) especifica o parâmetro circular = 2. Por isso, os dois primeiros caracteres não são eliminados, mas deslocados para o fim.
- O exemplo da função SUBSTRING( ) extrai uma subcadeia de comprimento 4, começando com um offset de 2 caracteres, o que significa que retorna os caracteres nas posições 3, 4, 5 e 6.
- A função SUBSTRING_AFTER( ) procura a substring "is" e retorna todos os caracteres após esse resultado.
- A função SUBSTRING_FROM( ) faz o mesmo, mas o resultado também contém a subcadeia "is".
- O primeiro exemplo da função SEGMENT( ) procura todas as ocorrências da cadeia de separação, um único sublinhado. Ele encontra dois e divide a cadeia de entrada em três segmentos. Em seguida, ele retorna o segundo segmento.
- O segundo exemplo faz o mesmo, mas retorna o terceiro segmento. Considere que a própria cadeia de caracteres de separação não faz parte do resultado.
Testar: funções de processamento
- Crie uma nova classe global que implemente a interface IF_OO_ADT_CLASSRUN.
- Copie o seguinte snippet de código para a parte de implementação do método if_oo_adt_classrun~main( ):
12345678910111213141516171819202122232425262728293031323334353637
DATA text TYPE string VALUE ` SAP BTP, ABAP Environment `.
* Change Case of characters
**********************************************************************
out->write( |TO_UPPER = { to_upper( text ) } | ).
out->write( |TO_LOWER = { to_lower( text ) } | ).
out->write( |TO_MIXED = { to_mixed( text ) } | ).
out->write( |FROM_MIXED = { from_mixed( text ) } | ).
* Change order of characters
**********************************************************************
out->write( |REVERSE = { reverse( text ) } | ).
out->write( |SHIFT_LEFT (places)= { shift_left( val = text places = 3 ) } | ).
out->write( |SHIFT_RIGHT (places)= { shift_right( val = text places = 3 ) } | ).
out->write( |SHIFT_LEFT (circ) = { shift_left( val = text circular = 3 ) } | ).
out->write( |SHIFT_RIGHT (circ) = { shift_right( val = text circular = 3 ) } | ).
* Extract a Substring
**********************************************************************
out->write( |SUBSTRING = { substring( val = text off = 4 len = 10 ) } | ).
out->write( |SUBSTRING_FROM = { substring_from( val = text sub = 'ABAP' ) } | ).
out->write( |SUBSTRING_AFTER = { substring_after( val = text sub = 'ABAP' ) } | ).
out->write( |SUBSTRING_TO = { substring_to( val = text sub = 'ABAP' ) } | ).
out->write( |SUBSTRING_BEFORE= { substring_before( val = text sub = 'ABAP' ) } | ).
* Condense, REPEAT and Segment
**********************************************************************
out->write( |CONDENSE = { condense( val = text ) } | ).
out->write( |REPEAT = { repeat( val = text occ = 2 ) } | ).
out->write( |SEGMENT1 = { segment( val = text sep = ',' index = 1 ) } | ).
out->write( |SEGMENT2 = { segment( val = text sep = ',' index = 2 ) } | ).
- Selecione Ctrl + F3 para ativar a classe e F9 para executá-la como um aplicativo de console.
- Analise a saída do console. Você consegue entender os resultados das diferentes funções?
- Jogue com os valores iniciais de diferentes funções para se familiarizar com seus resultados.
- Reproduza com os valores iniciais para texto, substring e os valores dos diferentes parâmetros para se familiarizar com as funções.
Funções de predicado
A função de predicado CONTAINS( ) é verdadeira se uma substring especificada aparecer pelo menos uma vez na string de entrada. Em outras palavras, se CONTAINS( ) for verdadeiro, a função COUNT( ) retornará um resultado maior que 0.
A mesma relação existe entre as funções de predicado CONTAINS_ANY_OF( ) e CONTAINS_ANY_NOT_OF( ), e as funções de descrição correspondentes COUNT_ANY_OF( ) e COUNT_ANY_NOT_OF( ).
MATCHES( ) é uma função de predicado dedicada para comparar a string de entrada completa com uma expressão regular. Veremos expressões regulares na próxima seção.
Expressões regulares no ABAP
Uma expressão regular, ou Regex para abreviar, é um padrão de caracteres literais e especiais que descreve um conjunto de cadeias de caracteres. Expressões regulares são frequentemente usadas em pesquisas de texto, em operações de "busca e substituição", ou para validar o conteúdo de campos em forma de caractere. Uma pesquisa usando uma expressão regular é mais poderosa do que uma pesquisa por uma cadeia de caracteres simples porque a expressão regular representa um número maior (potencialmente infinito) de cadeias de caracteres e as procura simultaneamente.
A sintaxe de expressões regulares é amplamente padronizada, mas existem diferenças entre padrões comuns como Perl ou POSIX e diferentes variantes de sintaxe, como XPath ou expressões regulares XSD.
No ABAP, o padrão preferido é Perl Compatible Regular Expression (PCRE), mas o ABAP também suporta alguns outros padrões e variantes.
Nota
Os exemplos neste curso seguem o padrão PCRE. Para outros padrões e variantes de sintaxe, consulte a documentação de palavras-chave ABAP.
Exemplos de expressões regulares
Vejamos alguns exemplos de expressões regulares:
- A expressão regular mais simples é um literal.
- Usando um par de colchetes ( [ ] ), você pode especificar um conjunto de caracteres que são permitidos na posição específica. O primeiro exemplo indica um conjunto de caracteres composto pelos dois caracteres individuais B e S. Por isso, as letras B ou S são permitidas entre as duas letras A.
- O exemplo seguinte utiliza um hífen (-) para indicar um intervalo de caracteres permitidos. B-D define um conjunto de caracteres que inclui B, D, e todos os caracteres entre eles em uma ordem lexical. Obviamente, você pode combinar valores individuais e vários intervalos. [AL-NRX-Z], por exemplo, define um conjunto de caracteres que consiste nas letras A, L, M, N, R, X, Y, Z.
- O exemplo seguinte usa um sinal ^ após o parêntese de abertura para definir uma lista de exclusão em vez de uma lista positiva. [^LX] exclui os caracteres L e X, mas permite todos os outros caracteres.
- Para especificar um conjunto de caracteres que inclua todos os caracteres disponíveis e não exclua nenhum, as expressões regulares usam um único sinal de ponto final (.). No exemplo, qualquer caractere é permitido entre os dois As, mas esse caractere é necessário e somente um desses caracteres é permitido.
- Para maior flexibilidade, você pode introduzir quantificadores. Um quantificador é um par de chaves ( {} ). Ele especifica a frequência com que o elemento à esquerda deve ser repetido. No exemplo, o 3 no quantificador significa que exatamente 3 letras Bs são necessárias entre as duas As.
- Em vez de um valor fixo, um quantificador pode indicar um valor inferior e superior para a repetição. No exemplo, pelo menos um B é necessário entre os dois As, mas dois Bs também são permitidos.
- Quando você deixa de fora o valor superior, você só define um mínimo. No exemplo, pode haver qualquer número de letras B entre as duas As, mas deve haver pelo menos uma.
- Com parênteses normais ( ), você agrupa vários elementos. Um bom caso de utilização é um grupo à esquerda de um quantificador. Em vez de um único caractere, todo o grupo é repetido com base nos números no quantificador. No exemplo, o grupo BA é repetido entre as letras A e P.
- Por fim, queremos olhar para o operador de união |. Fora de um grupo, ele combina dois modelos e combina o conjunto de resultados dos dois modelos. No exemplo, usamos o operador de união dentro de um grupo. À esquerda do literal de fechamento AP, são permitidos dois padrões: ou existe o literal AB ou a letra única S.
Nota
Esses exemplos são bastante simples e seu objetivo é ilustrar alguns conceitos básicos. Muitos outros conceitos existem e, combinando todos esses conceitos, você pode construir expressões extremamente poderosas. Para a imagem completa, comece com a documentação ABAP a partir da qual você pode navegar para outras fontes de informação.
Funções de cadeia integradas e expressões regulares
Muitas funções de string incorporadas oferecem um parâmetro pcre, especialmente quando realizam pesquisas. Pcre é muitas vezes uma alternativa para um parâmetro sub. Quando você transfere uma sequência de caracteres para o parâmetro pcre, em vez do parâmetro sub, a função interpreta a entrada como uma Expressão regular compatível com Perl (PCRE) e procura substrings que correspondam a esse padrão. Se uma função tiver os dois parâmetros, sub e pcre, você só pode fornecer um deles.
Nota
Na documentação ABAP, você pode encontrar mais parâmetros para expressões regulares. Um deles, o parâmetro regex, foi utilizado para expressões regulares POSIX. É obsoleto e você não deve utilizá-lo.
Para funções como FIND( ) e COUNT( ) é óbvio que eles executam pesquisas de substrings. Mas outras funções também executam pesquisas. Exemplos são a função de predicado CONTAINS( ) e as funções de processamento REPLACE( ), SUBSTRING_FROM( ), SUBSTRING_AFTER( ), etc.
Também existem funções de string integradas que só funcionam com expressões regulares. A função de predicado MATCHES( ) é verdadeira se toda a cadeia de caracteres corresponder à expressão regular. MATCH( ) funciona de forma semelhante a FIND( ). Ele procura em uma cadeia de caracteres uma subcadeia que corresponda à expressão regular. Mas em que FIND( ) retorna o offset do resultado, MATCH( ) retorna a substring encontrada.
Este vídeo ilustra alguns exemplos com o parâmetro PCRE.
Nota
A função match( ) é uma ferramenta nítida e elegante quando você precisa implementar validações complicadas para campos de entrada em forma de caractere.
Utilizar funções de processamento de cadeia
Neste exercício, você usa funções de processamento de cadeia para enriquecer símbolos de texto com o conteúdo de variáveis antes de adicioná-los à saída do console.
Tarefa 1: Copiar modelo (opcional)
Copie a classe modelo /LRN/CL_S4D401_TCS_TEXT_POOL. Se você tiver concluído o exercício anterior, pode ignorar esta tarefa e continuar processando sua classe ZCL_##_SOLUTION.
Etapas
Copie a classe /LRN/CL_S4D401_TCS_TEXT_POOL para uma classe em seu próprio pacote (nome sugerido: ZCL_##_SOLUTION, onde ## representa seu número de grupo).
No Explorador de projetos, clique com o botão direito do mouse na classe /LRN/CL_S4D401_TCS_TEXT_POOL para abrir o menu de contexto.
No menu de contexto, selecione Duplicar....
Insira o nome do seu pacote no campo Pacote. No campo Nome, insira ZCL_##_SOLUTION, em que ## representa seu número de grupo.
Selecione Avançar.
Confirme a ordem de transporte e selecione Concluir.
Ative a cópia.
Pressione Ctrl + F3 para ativar a classe.
Tarefa 2: Utilizar funções de processamento de cadeia
Certifique-se de que você efetuou o logon com o idioma original de sua classe global. Em seguida, ajuste a implementação do método GET_DESCRIPTION da classe local LCL_PASSENGER_FLIGHT. Substitua o texto literal nos modelos de string pelo texto traduzível do pool de textos. Para o primeiro texto, crie um único símbolo de texto com caracteres de preenchimento e utilize uma função de processamento de cadeia para substituir os caracteres de preenchimento pelos valores de atributo.
Etapas
Exiba o idioma original de sua classe ABAP e certifique-se de que você efetuou o logon no mesmo idioma.
Abra o texto fonte de sua classe global ZCL_##_SOLUTION.
Nas abas abaixo do editor, selecione a aba Propriedades.
Anote a propriedade Idioma original. Ele deve ser definido como EN.
No Explorador de projetos, analise a descrição de seu projeto ABAP Cloud. Após o ID do sistema, o mandante de logon e o ID do usuário, ele exibe o idioma de logon.
Se o idioma de logon não corresponder ao idioma original da sua classe ABAP, crie um novo projeto com o idioma de logon correto.
Navegue para a implementação do método GET_DESCRIPTION na classe local LCL_PASSENGER_FLIGHT.
Por exemplo, você pode abrir a aba Tipos locais no editor e procurar METHOD get_description.
Como alternativa, você pode expandir ZCL_##_SOLUTION→LCL_PASSENGER_FLIGHT na visão Estrutura à esquerda e selecionar GET_DESCRIPTION.
Comente a primeira instrução APPEND e substitua-a por um APPEND de uma variável local do tipo STRING (nome sugerido: txt).
Selecione todas as linhas de código que pertencem à primeira instrução APPEND e pressione Ctrl + <.
Ajuste o código da seguinte forma:
123456
DATA txt TYPE string.
APPEND txt TO r_result.
Antes da instrução APPEND, preencha o objeto de dados com um literal de texto que reflita o modelo de cadeia anterior. Utilizar caracteres de preenchimento adequados onde o modelo de cadeia contém expressões integradas, por exemplo, &carrid&, &connid&, &date&, &from& e &to&.
Ajuste o código da seguinte forma:
123
DATA text TYPE string.
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'.
APPEND text TO r_result.
Vincule o literal de texto a um novo símbolo de texto (ID sugerido para o símbolo de texto: 005).
Ajuste o código da seguinte forma:
1
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'(005).
Use uma correção rápida para criar o novo texto no pool de texto com um comprimento máximo de 132.
Posicione o cursor em (005) e pressione Ctrl + 1.
Selecione Create text 005 in text pool.
Use o controle deslizante para definir o Comprimento máximo como 132 e selecione Concluir.
Volte para a codificação ABAP. Antes da instrução APPEND, utilize uma função de processamento de cadeia adequada para substituir o caractere de preenchimento &carrid& na variável de cadeia txt pelo conteúdo do atributo de instância carrier_id.
Ajuste o código da seguinte forma:
123
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'(005).
txt = replace( val = txt sub = '&carrid&' with = carrier_id ).
APPEND txt TO r_result.
Repita a etapa anterior adequadamente para os outros caracteres de preenchimento. Não se esqueça da formatação da data do voo de acordo com o formato de data preferido do usuário.
Ajuste o código da seguinte forma:
123456789
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'(005).
txt = replace( val = txt sub = '&carrid&' with = carrier_id ).
txt = replace( val = txt sub = '&connid&' with = connection_id ).
txt = replace( val = txt sub = '&date&' with = |{ flight_date DATE = USER }| ).
txt = replace( val = txt sub = '&from&' with = connection_details-airport_from_id ).
txt = replace( val = txt sub = '&to&' with = connection_details-airport_to_id ).
APPEND txt TO r_result.
Opcional: substitua o texto literal restante no método GET_DESCRIPTION por símbolos de texto.
Execute esta etapa como anteriormente.
Por fim, seu código deve ter a seguinte aparência:
12345678910111213141516171819202122232425
METHOD get_description.
DATA txt TYPE string.
txt = 'Flight &carrid& &connid& on &date& from &from& to &to&'(005).
txt = replace( val = txt sub = '&carrid&' with = carrier_id ).
txt = replace( val = txt sub = '&connid&' with = connection_id ).
txt = replace( val = txt sub = '&date&' with = |{ flight_date DATE = USER }| ).
txt = replace( val = txt sub = '&from&' with = connection_details-airport_from_id ).
txt = replace( val = txt sub = '&to&' with = connection_details-airport_to_id ).
APPEND txt TO r_result.
APPEND |{ 'Planetype:'(006) } { planetype }| TO r_result.
APPEND |{ 'Maximum Seats:'(007) } { seats_max }| TO r_result.
APPEND |{ 'Occupied Seats:'(008) } { seats_occ }| TO r_result.
APPEND |{ 'Free Seats:'(009) } { seats_free }| TO r_result.
APPEND |{ 'Ticket Price:'(010) } { price CURRENCY = currency } { currency }| TO r_result.
APPEND |{ 'Duration:'(011) } { connection_details-duration } { 'minutes'(012) }| TO r_result.
ENDMETHOD.
Ative e teste a classe global como um aplicativo de console.
Nota
Você não deve notar nenhuma diferença. A melhoria é que os textos agora são traduzíveis. No entanto, isso só terá efeito se o administrador do sistema realmente criar um projeto de tradução. Isso está além do escopo deste curso.
Pressione Ctrl + F3.
Pressione F9.