Wilberhg's blog

Automação de até 6 Sessões SAP GUI

Entendendo o Conceito

A automação do SAP GUI por meio de scripts externos é viabilizada pela interface de Component Object Model (COM) do Windows, acessível em Python através da biblioteca pywin32 [7]. O SAP GUI Scripting permite simular interações humanas diretamente nos elementos da interface de usuário das transações.

Para processar uma fila volumosa de itens, como um lote de 1.000 registros, a execução sequencial em uma única janela pode apresentar lentidão considerável. A utilização de uma fila compartilhada (queue.Queue) para alimentar múltiplas threads paralelas que processam itens sob demanda reduz drasticamente o tempo total de execução e balanceia a carga de trabalho de forma automática [1, 7].

A classe ThreadPoolExecutor, contida no módulo concurrent.futures, simplifica o gerenciamento de threads ao encapsular a criação, inicialização e finalização das threads em um pool sob demanda [7]. Ao definir max_workers=3, o executor garante que exatamente três threads concorrentes sejam mantidas ativas para processar a fila compartilhada. Como o SAP GUI limita o número de sessões simultâneas a até seis por conexão, o script realiza o login inicial com o Usuário X e cria duas novas janelas [2]. As três threads do pool assumem, individualmente, uma das três sessões ativas do SAP GUI (índices 0, 1 e 2), inicializando e liberando as dependências COM de forma isolada dentro de cada thread de execução do pool [7].

Passo a Passo

  1. Instalar a biblioteca do sistema operacional para gerenciamento COM com o comando pip install pywin32 [3].
  2. Configurar o ambiente cliente do SAP GUI para habilitar a execução de scripts nas opções de acessibilidade da ferramenta [3].
  3. Garantir que o parâmetro de sistema sapgui/user_scripting esteja ativo com valor verdadeiro no servidor SAP [3].
  4. Desenvolver o script Python importando os módulos concurrent.futures, queue e win32com.client [7].
  5. Inicializar o SAP Logon, realizar o login com o Usuário X e criar duas novas sessões adicionais utilizando o comando session.CreateSession() [2, 7].
  6. Instanciar uma fila thread-safe (queue.Queue()) e preenchê-la com os 1.000 itens de processamento.
  7. Declarar um bloco gerenciador de contexto with ThreadPoolExecutor(max_workers=3) as executor: para instanciar o pool de threads.
  8. Enviar as três tarefas de processamento de fila ao executor através do método executor.submit(), mapeando os índices de sessão 0, 1 e 2.
  9. Utilizar o método queue.join() para suspender a execução da thread principal até que os 1.000 itens tenham sido processados pelas threads do pool [7].

Explicando o código

import queue
import time
import win32com.client
import pythoncom
from concurrent.futures import ThreadPoolExecutor

CONNECTION_NAME = "Conexao_Producao"
USER_X = "USUARIO_X"
PASSWORD_X = "SENHA_X"
LANGUAGE = "PT"

fila_compartilhada = queue.Queue()

for i in range(1, 1001):
    fila_compartilhada.put(f"Item_{i}")

def processar_fila_sap(session_index):
    pythoncom.CoInitialize()
    try:
        sap_gui = win32com.client.GetObject("SAPGUI")
        application = sap_gui.GetScriptingEngine
        connection = application.Connections(0)
        session = connection.Sessions(session_index)
        
        while True:
            try:
                item = fila_compartilhada.get_nowait()
            except queue.Empty:
                break
                
            try:
                session.findById("wnd[0]/usr/txtRSYST-BNAME").text = item
                session.findById("wnd[0]").sendVKey(0)
                time.sleep(0.1)
            except Exception as e:
                print(f"Erro ao processar item {item} na sessao {session_index}: {str(e)}")
            finally:
                fila_compartilhada.task_done()
                
    except Exception as e:
        print(f"Erro critico na thread da sessao {session_index}: {str(e)}")
    finally:
        pythoncom.CoUninitialize()

def main():
    sap_gui = win32com.client.GetObject("SAPGUI")
    application = sap_gui.GetScriptingEngine
    connection = application.OpenConnection(CONNECTION_NAME, True)
    session = connection.Sessions(0)
    
    session.findById("wnd[0]/usr/txtRSYST-BNAME").text = USER_X
    session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = PASSWORD_X
    session.findById("wnd[0]/usr/txtRSYST-LANGU").text = LANGUAGE
    session.findById("wnd[0]").sendVKey(0)
    
    session.CreateSession()
    session.CreateSession()
    
    time.sleep(3)
    
    with ThreadPoolExecutor(max_workers=3) as executor:
        for i in range(3):
            executor.submit(processar_fila_sap, i)
        
        fila_compartilhada.join()

if __name__ == "__main__":
    main()

Observações

Referências

  1. SAP Community. How to Execute SAP GUI Scripting Parallel. Disponível em: https://community.sap.com/t5/technology-blog-posts-by-members/how-to-execute-sap-gui-scripting-parallel/ba-p/13509718.
  2. SAP Help Portal. SAP GUI - Working with Multiple Sessions. Disponível em: https://help.sap.com/docs/SAP_NETWEAVER_740/b1c834a22d05483b8a75710743b5ff26/9c7810c251d345aabe5a01845372ac14.html.
  3. Stack Overflow. Multiprocessing in SAP GUI using Python. Disponível em: https://stackoverflow.com/questions/72533754/multiprocessing-in-sap-gui-using-python.

#automation #python #queue #sap #threadpoolexecutor