Manipular outros programas a partir do Java

Boa tarde!

Pessoal trabalho em uma empresa onde estão utilizando o excel (Visual Basic) para extrair informação de um outro sistema (aqueles sistemas de banco, sabe de tela toda preta com o DOS) em imprimindo relatórios a partir destes dados. Estão tendo alguns problemas com estes arquivos então junto com um colega estamos tentando substituir por um pequeno aplicativo em java.

Estou tendo algumas dificuldades para fazer a mesma coisa em java aqui segue um pedaço do código em VB que faz a mesma coisa que desejo fazer:

Método do VB para acessar o sistema
Private Sub CmdoPesquisarDoc_Click()

Declaração das variaveis necessarias para acessar o sistema
Dim PgInicio As Integer
Dim PgFim As Integer
Dim Sys, Sess, MyScreen As Object
Dim x, Linha As Integer
Dim pg, LinhaDoc As Variant
Dim OpRej, Matr, Sen, Agencia As String

Carrega informações da planilha de excel onde esta o login em senha necessarios para acessar o sistema
Matr = Sheets(“Auxiliar”).Cells(4, 2)
Sen = Sheets(“Auxiliar”).Cells(6, 2)
Agencia = Cells(1, 10).Value

Aparentemente cria uma “conexão” com o sistema
Set Sys = CreateObject(“Sistema.exe”)
Set Sess = Sys.ActiveSession
Set MyScreen = Sess.Screen

Até aqui tudo bem consigo fazer isto tranquilamente no java e daqui para baixo que estou tendo dificuldades tanto para enviar quanto para receber as informações no outro sistema.

Move o cursor para uma determinada posição na tela
MyScreen.Moveto 17, 38

Envia uma determinada informação para o posição em que o cursor foi parar. (Este é um subsistema dentro do sistema, acho…)
MyScreen.SendKeys (“522”)

“Pressiona” a tecla enter do teclado para acessar o subsistema
MyScreen.SendKeys ("")
MyScreen.WaitHostQuiet (100)

A partir deste ponto envia as informações de login e senha para logar no subsistema
MyScreen.SendKeys (Matr)
MyScreen.SendKeys ("")
MyScreen.SendKeys (Sen)
MyScreen.SendKeys ("")
MyScreen.WaitHostQuiet (100)

E aqui ele pega as informações da tela e envia para determinadas células do Excel
For pg = PgInicio To PgFim
For Linha = 10 To 18
OpRej = MyScreen.GetString(Linha, 23, 3)
If OpRej = “000” Then
LinhaDoc = Cells(4, 18)
Cells(LinhaDoc, 1) = Cells(1, 6)
Cells(LinhaDoc, 5) = MyScreen.GetString(Linha, 38, 6) 'NDoc
Cells(LinhaDoc, 4) = MyScreen.GetString(Linha, 47, 12) * 1 'Valor
MyScreen.Moveto Linha, 2
MyScreen.SendKeys (“X”)
MyScreen.SendKeys ("")
MyScreen.WaitHostQuiet (100)
Cells(LinhaDoc, 2) = MyScreen.GetString(20, 12, 30) 'Nome
Cells(LinhaDoc, 3) = MyScreen.GetString(20, 63, 14) 'CpfCnpj
MyScreen.SendKeys ("")
MyScreen.WaitHostQuiet (100)
End If
Next
MyScreen.SendKeys ("")
MyScreen.WaitHostQuiet (100)

Ai encima esta o código em VB gostaria de fazer a mesma coisa em java, será que é possível??? Se sim, primeiro alguém pode me “dar uma luz” de como envio informações e movo o cursor.

Grato
Murillo Pontes

Será que ninguém tem alguma ideia de qual classe devo usar??

Grato
Murillo

Você pode usar a Apache POI para manipular arquivos do Excel.

http://poi.apache.org/

[]'s

[quote=davidbuzatto]Você pode usar a Apache POI para manipular arquivos do Excel.

http://poi.apache.org/

[]'s[/quote]

Primeiro obrigado pela ajuda,

mas o que quero fazer na verdade não é manipular o excel, e sim um outro sistema. Acho que não fui muito claro mas este código ai de cima e um exemplo do que quero fazer em java. Este código em vc manipula um outro sistema e gostaria de fazer o mesmo em Java, mas apesar de pesquisar bastante não achei nada parecido com o código ai de cima.

O programa a ser manipulado tem que oferecer algum canal de comunicação.
O que você pode fazer é executar o programa através do Java usando um Process (através do método exec() da classe Runtime) e enviar dados desejados através do stream de entrada do processo em questão.

O exemplo abaixo obtém o Input Stream e o Error Stream (ambos InputStreams) e consome os dados enviados através deles.

Você pode agir de forma análoga, obtendo o OutputStream através do método getOutputStream() de Process e escrever os dados desejados neste stream, dando um flush quando desejar que o comando seja enviado.

Veja um exemplo:

Programa em C que vai ser manipulado.

[code]#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

int main() {

char mensagem[50] = {0};

while ( true ) {

    gets( mensagem );
    printf( "string \"%s\" recebida...\n", mensagem );

    // força o flush dos streams de saída e de erro para poder ver a saída do processo
    fflush( stdout );
    fflush( stderr ); // como não está escrevendo nada no stream de erro, essa linha acaba sendo irrelevante...

    if ( !strcmp( "fim", mensagem ) ) {
        break;
    }

}

return 0;

}[/code]
Programa em Java que manipula o programa em C.

[code]/**
*

  • @author David Buzatto
    */
    public class Teste {

    /**

    • @param args the command line arguments
      */
      public static void main( String[] args ) {
      new Teste().testar();
      }

    public void testar() {

     try {
         
         // executa o comando
         Process processo = Runtime.getRuntime().exec( "C:/Mensagem.exe" );
    
         // cria os stream gobblers, um para o stream de entrada e um para o
         // stream de erro. os gobblers vão consumir os streams do processo
         StreamGobbler sgInput = new StreamGobbler(
                 processo.getInputStream(), "input" );
         StreamGobbler sgError = new StreamGobbler(
                 processo.getErrorStream(), "error" );
    
         // cria uma thread para cada stream gobbler e as inicia
         new Thread( sgInput ).start();
         new Thread( sgError ).start();
         
         // cria um PrintWriter usando o output stream do processo
         PrintWriter writer = new PrintWriter( processo.getOutputStream() );
         
         Scanner scan = new Scanner( System.in );
         
         while ( true ) {
             
             System.out.println( "Entre com uma frase: " );
             String frase = scan.nextLine();
             
             // simula a entrada do teclado
             writer.write( frase );
             writer.write( "\n" );
             writer.flush();
             
             if ( frase.equals( "fim" ) ) {
                 // se a frase entrada for fim, finaliza o while
                 break;
             }
             
         }
     
     } catch ( IOException ioe ) {
         ioe.printStackTrace();
     }
    

    }

    /**

    • Thread para consumir os streams de processos.

    • Baseada na implementação apresentada em:

    • http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1

    • @author David Buzatto
      */
      private class StreamGobbler implements Runnable {

      private InputStream is;
      private String type;
      private FileWriter fw;

      public StreamGobbler( InputStream is, String type ) {
      this.is = is;
      this.type = type;
      }

      public StreamGobbler( InputStream is, String type, File file )
      throws IOException {
      this.is = is;
      this.type = type;
      this.fw = new FileWriter( file );
      }

      @Override
      public void run() {
      try {
      InputStreamReader isr = new InputStreamReader( is );
      BufferedReader br = new BufferedReader( isr );
      String line = null;
      while ( ( line = br.readLine() ) != null ) {
      if ( fw != null ) {
      fw.write( line + “\n” );
      } else {
      System.out.println( type + “>” + line );
      }
      }
      if ( fw != null ) {
      fw.close();
      }
      } catch ( IOException ioe ) {
      ioe.printStackTrace();
      }
      }
      }

}[/code]

No meu caso, o programa executável do código em C que postei está no C: e se chama “Mensagem.exe”.
Note que fiz o exemplo assim pois parece que é assim que você quer fazer pela dúvida que você postou. Eu “simulo” o teclado ao escrever algo no writer mais um “\n” e dar o flush.
Mais um detalhe. Defini a classe StreamGobbler como uma classe interna privada, mas você deve criá-la como uma classe normal para poder reaproveitá-la.

[]'s

Ok obrigado!!

Vou estudar o código acima e tentar implantar no meu sistema, mas só vou saber se vai funcionar amanhã na empresa!!

De qualquer maneira muito obrigado pela ajuda!

[quote=Murillo Pontes]Ok obrigado!!

Vou estudar o código acima e tentar implantar no meu sistema, mas só vou saber se vai funcionar amanhã na empresa!!

De qualquer maneira muito obrigado pela ajuda![/quote]

Beleza Murillo.
Poste se conseguiu ou não. O caminho provavelmente é esse que te passei.
Só fiquei preocupado que você falou que o programa é igual de banco. Aquela interface modo texto que os bancos usam na verdade é um emulador de terminal de mainframe. Se seu programa em Java vai lidar com um emulador desses, temo que o meu exemplo não funcionará, entretanto, se for um programa em modo texto, você vai conseguir resolver seu problema usando como base o que postei.

[]'s

David na verdade é isto mesmo!

O sistema que preciso tirar e enviar informações e uma sessão em um terminal qualquer, e o código em VB que postei troca informações com este emulador (não conheço nada em VB, mas parece ser de forma bem simples, tanto que mesmo sem conhecer a linguagem consegui adaptar aquela planilha para fazer outras coisas).
Como estou estudando Java a um ano + ou - gostaria de fazer isto em java, além do aprendizado vai ficar bem mais profissional.

Obrigado

Entendi.

Enfim, teste e veja se consegue conversar com o emulador e poste seus resultados. É provável que funcione, visto que você vai conseguir obter os streams do emulador, mas não tenho certeza.

[]'s

Olha,

http://www.devmedia.com.br/post-4082-Rob%C3%B4-Criando-uma-macro-em-vb-para-acesso-ao-terminal-de-um-sistema-mainframe-.html

é isto aqui mas em Java.

Obrigado

Boa noite!

1º - Alguém sabe se existe um programa para download parecido com os emuladores de mainframe? Só consigo fazer os testes no trabalho e gostaria de fazer isto em casa.

2º - Como faço para mandar uma informação ou posicionar um cursor em uma posição especifica da tela deste emulador?

davidbuzatto não consegui fazer os testes hoje, só estou conseguindo estudar as classes e seu código agora!!

Vlw