No artigo anterior, link no estará no rodapé, aprendemos como garantir que a tela do Mainframe esteja pronta para leitura. Agora, o desafio é outro: como extrair informações específicas de uma grade de 24x80 caracteres sem transformar seu código em uma “sopa de números”.

O Sistema de Coordenadas 3270 Link para o cabeçalho

Diferente de sistemas web onde os elementos são identificados por IDs ou Classes, no Mainframe tudo é baseado em posição fixa. A tela é uma matriz rígida.

  • Linhas: Geralmente de 1 a 24.

  • Colunas: Geralmente de 1 a 80.

  • Total de Caracteres: 1.920.

Quando o s3270 retorna o conteúdo da tela (através do comando rectangle), ele entrega uma string linear de quase 2 mil caracteres. Para ler um dado, você precisa saber onde ele começa e quantos caracteres ele ocupa.


/**
 * Extrai texto de coordenadas específicas da tela 3270.
 */
public function capturarCampo($tela, $linha, $coluna, $tamanho)
{
    // Cálculo: (Linha anterior * largura da tela) + (Coluna anterior)
    $posicaoInicial = (($linha - 1) * 80) + ($coluna - 1);
    
    // Extraímos o pedaço da string
    $campo = substr($tela, $posicaoInicial, $tamanho);
    
    // Retornamos com trim para limpar espaços vazios do terminal
    return trim($campo);
}

Organizando com Data Mapping (Mapas de Tela) Link para o cabeçalho

A maior causa de erros em robôs legados é a mudança sutil de uma tela que quebra as coordenadas no código. A melhor forma de evitar isso é criar Mapas de Dados. Em vez de espalhar substr() pelo código, você define um “dicionário” para cada tela.

Exemplo Prático: Tela de Consulta de Saldo Link para o cabeçalho

Imagine uma tela onde o nome do cliente está na linha 5 e o saldo na linha 10.

// Definimos o mapa da tela
$mapaSaldo = [
    'nome_cliente' => ['L' => 5,  'C' => 20, 'T' => 30],
    'numero_conta' => ['L' => 6,  'C' => 20, 'T' => 15],
    'saldo_atual'  => ['L' => 10, 'C' => 20, 'T' => 12],
    'data_extrato' => ['L' => 2,  'C' => 70, 'T' => 10],
];

// Executamos a extração em lote
$telaBruta = $this->lerComSeguranca("CONSULTA SALDO");
$dadosExtraidos = [];

foreach ($mapaSaldo as $campo => $pos) {
    $dadosExtraidos[$campo] = $this->capturarCampo(
        $telaBruta, 
        $pos['L'], 
        $pos['C'], 
        $pos['T']
    );
}

// Resultado: ['nome_cliente' => 'JOÃO DA SILVA', 'saldo_atual' => '1.500,00', ...]

Dicas para uma Extração sem Erros Link para o cabeçalho

  1. Cuidado com os Atributos: No 3270, antes de cada campo existe um “byte de atributo” (invisível, que define cor ou proteção). Às vezes, o texto começa na coluna 21, mas o atributo está na 20. Se sua captura trouxer um caractere estranho no início, aumente a coluna em 1.

  2. Tratamento de Números: O Mainframe costuma alinhar números à direita. O trim() é essencial para remover os espaços que preenchem o campo à esquerda.

  3. Logs de Falha: Se a extração falhar, salve a string $telaBruta em um log. Isso permite que você simule a tela offline para ajustar as coordenadas depois.


Conclusão Link para o cabeçalho

Mapear campos transforma uma string confusa em um Array Associativo limpo e pronto para ser inserido em um banco de dados ou retornado em uma API. É a camada de tradução necessária entre o passado (Mainframe) e o presente (PHP).

Link artigo anterior:

https://tiagoscosta.com.br/posts/automa%C3%A7%C3%A3o-de-mainframe-com-php-o-guia-de-sobreviv%C3%AAncia-ao-s3270/