Ho pensato che sarebbe stato comodo anche un semplice foglio Excel dove l'operatore inserisce il numero cartellino (ID kanban), letto magari con un barcode-reader, poi un tasto per procedere allo svuotamento, con gestione dei messaggi ed eventuali errori di ritorno.
In questo post la spiegazione di come realizzarlo.
Si deve prima costruire un Function Module, chiamabile da remoto, che effettua i controlli, esegue l'operazione e gestisce i messaggi all'operatore.
Definizione del FM Z_EMPTY_KANBAN:
Nota Bene: è necessario definire che il modulo sia accessibile da remoto.
Importazione:
Esportazione:
Più sotto trovate il codice.
Questo è come si presenta il foglio Excel all'avvio (una macro automatica cancella eventuali dati precedenti)
L'operatore inserisce il suo CID (eventualmente da togliere se non codificato in SAP), l'ID del Kanban e preme il pulsante.
- Logon al sistema SAP.
- Chiama il FM Z_EMPTY_KANBAN.
- Gestione messaggi di ritorno.
Questo il messaggio di esito corretto, dove viene riportato materiale, descrizione e quantità Kanban.
Il file Excel contiene un foglio dove devono essere inseriti i dati di logon:
Potete scaricare il foglio excel di esempio: Z_SVUOTA_KANBAN.xls
Password di protezione foglio: kanban
Alcune annotazioni generali:
- Di norma includo le informazioni di Logon nel codice VBA e poi lo proteggo con una password poichè altrimenti sono in chiaro. Anche così non è che sia una protezione molto solida, ma mi sembra il minimo.
- nel PC deve essere installata la SAPGUI (che contiene le DLL per poter attivare il collegamento).
- se nel server SAP è attivo il firewall deve essere aperta in ingresso la porta tcp 33nn (nn=<system number>), normalmente per le connessioni sapgui è aperta la 32nn.
- consiglio di definire un utente di tipo S (servizio) che, in pratica, non può effettuare il logon da GUI.
Elenco codice VBA Excel:
Public ok_login As Integer
Sub main()
Dim R3 As Object
Set R3 = CreateObject("SAP.Functions")
zlogin R3
If ok_login = 0 Then
callRFC R3
R3.Connection.Logoff
End If
End Sub
Sub zlogin(R3 As Object)
R3.Connection.ApplicationServer = Sheets("Logon").Cells(1, 2).Value
R3.Connection.SystemNumber = Sheets("Logon").Cells(2, 2).Value
R3.Connection.User = Sheets("Logon").Cells(3, 2).Value
R3.Connection.Password = Sheets("Logon").Cells(4, 2).Value
R3.Connection.client = Sheets("Logon").Cells(5, 2).Value
R3.Connection.Language = Sheets("Logon").Cells(6, 2).Value
'R3.Connection.ApplicationServer = ""
'R3.Connection.SystemNumber = nn
'R3.Connection.User = ""
'R3.Connection.Password = ""
'R3.Connection.client = nnn
'R3.Connection.Language = ""
' Logon a SAP e controllo se la connessione è stabilita
If R3.Connection.Logon(0, True) <> True Then
MsgBox "Impossibile collegarsi a SAP!" 'Messaggio di errore
ok_login = 1
Exit Sub
Else
'MsgBox "OK: Collegato a SAP!"
ok_login = 0
End If
End Sub
Sub Auto_Open()
'
' Auto_Open Macro
' Macro all'avvio
'
' Pulisco celle
Sheets("Kanban").Select
Range("B1:B2").Select
Selection.ClearContents
Range("D1:D2").Select
Selection.ClearContents
Range("B1:B1").Select
End Sub
Sub callRFC(R3 As Object)
' Cancello esito precedente
Sheets("Kanban").Select
Range("D2:D2").Select
Selection.ClearContents
Range("B2:B2").Select
' Definizione funzione RFC
Set myFuncRFC = R3.Add("Z_EMPTY_KANBAN")
' Definizione degli oggetti di interfaccia
Dim i_PKKEY As Object
Dim i_PERNR As Object
' Parametri in ingresso
Set i_PKKEY = myFuncRFC.exports("I_PKKEY")
Set i_PERNR = myFuncRFC.exports("I_PERNR")
' Valorizzo i parametri in ingresso con i campi del foglio
i_PKKEY.Value = Sheets("Kanban").Cells(2, 2).Value
i_PERNR.Value = Sheets("Kanban").Cells(1, 2).Value
wa_ID = Sheets("Kanban").Cells(2, 2).Value
wa_CID = Sheets("Kanban").Cells(1, 2).Value
If wa_CID = "" Then
MsgBox "Inserire CID operatore!"
Range("B1:B1").Select
Exit Sub
End If
If wa_ID = "" Then
MsgBox "Inserire ID Kanban!"
Exit Sub
End If
' Chiamata alla funzione SAP
If myFuncRFC.call = False Then
MsgBox myFuncRFC.Exception
Exit Sub
End If
' Ricevo i valori di ritorno dalla funzione
Set O_ESITO = myFuncRFC.imports("O_ESITO")
Set O_MATNR = myFuncRFC.imports("O_MATNR")
Set O_MAKTX = myFuncRFC.imports("O_MAKTX")
Set O_BEHMG = myFuncRFC.imports("O_BEHMG")
Set O_NOME = myFuncRFC.imports("O_NOME")
Set O_MESSAGGIO = myFuncRFC.imports("O_MESSAGGIO")
' Porto i valori di ritorno nel foglio
Sheets("Kanban").Cells(1, 4) = O_NOME
Sheets("Kanban").Cells(2, 4) = O_MESSAGGIO
Dim w_mess As String
If O_ESITO = 0 Then
w_mess = O_MESSAGGIO & vbCrLf & vbCrLf & "Materiale : " & O_MATNR & vbCrLf & "Descrizione: " & O_MAKTX & vbCrLf & "Quantità : " & O_BEHMG
Else
w_mess = O_MESSAGGIO
End If
MsgBox w_mess 'Messaggio all'operatore
' Se esito positivo cancello ID Kanban
If O_ESITO = 0 Then
Sheets("Kanban").Select
Range("B2:B2").Select
Selection.ClearContents
End If
Set myFuncRFC = Nothing
End Sub
Codice FM Z_EMPTY_KANBAN
FUNCTION z_empty_kanban.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*" IMPORTING
*" VALUE(I_PKKEY) TYPE PKKEY
*" VALUE(I_PERNR) TYPE PERSNO OPTIONAL
*" EXPORTING
*" VALUE(O_ESITO) TYPE CHAR01
*" VALUE(O_MATNR) TYPE MATNR
*" VALUE(O_MAKTX) TYPE MAKTX
*" VALUE(O_BEHMG) TYPE CHAR20
*" VALUE(O_NOME) TYPE CHAR40
*" VALUE(O_MESSAGGIO) TYPE CHAR80
*"----------------------------------------------------------------------
* Autore : Fabio Giacobbe - 26/08/2019 |
* Descrizione: Dichiarazione di svuotamento Kanban pieno |
*----------------------------------------------------------------------+
* Modifiche : by |
* Note : |
*----------------------------------------------------------------------+
* parametri
* ingresso:
* I_PKKEY : ID kanban
* I_PERNR : C.I.D.
*
* uscita:
* O_ESITO: 0 = Operazione eseguita correttamente.
* 1 = Errore di lettura dati.
* 2 = Kanban non PIENO.
* 3 = Il Kanban non può cambiare stato per tempo attesa
* 4 = Lock di dati
* 9 = errore generico.
* O_MATNR: Codice materiale
* O_MAKTX: Testo breve materiale
* O_BEHMG: Qtà Kanban
* O_NOME : Nome Operatore
* O_MESSAGGIO: Messaggio
*----------------------------------------------------------------------+
DATA: wa_pkhd LIKE pkhd,
wa_pkps LIKE pkps,
wa_tpk01 LIKE tpk01,
wa_tpk02 LIKE tpk02,
wa_tpk03 LIKE tpk03,
wa_tpk00 LIKE tpk00,
wa_qta_int TYPE p DECIMALS 0,
wa_nextstatus LIKE pkps-pkbst,
return LIKE bapiret2,
kanban_pieno TYPE pkbst VALUE '5',
l_nachn TYPE pa0002-nachn,
l_vorna TYPE pa0002-vorna.
* Lettura ID cartellino Kanban
SELECT SINGLE * FROM pkps INTO wa_pkps
WHERE pkkey = i_pkkey.
IF sy-subrc NE 0.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 004 WITH i_pkkey INTO o_messaggio.
o_esito = 1.
EXIT.
ENDIF.
* Lettura ciclo di controllo Kanban
SELECT SINGLE * FROM pkhd INTO wa_pkhd
WHERE pknum = wa_pkps-pknum.
IF sy-subrc NE 0.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 015 WITH wa_pkps-pknum INTO o_messaggio.
o_esito = 1.
EXIT.
ENDIF.
* Verifico CID operatore
IF i_pernr IS NOT INITIAL.
SELECT SINGLE nachn vorna INTO (l_nachn,l_vorna) FROM pa0002
WHERE pernr EQ i_pernr
AND sprps EQ '' "Non bloccato
AND begda LE sy-datum AND endda GE sy-datum.
IF sy-subrc = 0.
CONCATENATE l_nachn l_vorna
INTO o_nome SEPARATED BY space.
ELSE.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 017 WITH i_pernr INTO o_messaggio.
o_esito = 1.
EXIT.
ENDIF.
ENDIF.
o_matnr = wa_pkhd-matnr.
* Riporto q.tà kanban in uscita usando un campo di testo
wa_qta_int = wa_pkhd-behmg.
IF wa_qta_int = wa_pkhd-behmg.
WRITE wa_qta_int TO o_behmg.
ELSE.
WRITE wa_pkhd-behmg TO o_behmg.
ENDIF.
CONDENSE o_behmg.
* ricerco descrizione per lingua logon
SELECT SINGLE maktx FROM makt INTO o_maktx
WHERE matnr = o_matnr
AND spras = sy-langu.
IF sy-subrc <> 0.
IF sy-langu <> 'IT'.
IF sy-langu <> 'EN'.
SELECT SINGLE maktx FROM makt INTO o_maktx
WHERE matnr = o_matnr
AND spras = 'EN'.
IF sy-subrc <> 0.
SELECT SINGLE maktx FROM makt INTO o_maktx
WHERE matnr = o_matnr
AND spras = 'IT'.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
* controllo stato
IF wa_pkps-pkbst NE kanban_pieno.
DATA tab_a LIKE dd07v OCCURS 0 WITH HEADER LINE.
DATA tab_n LIKE dd07v OCCURS 0 WITH HEADER LINE.
CALL FUNCTION 'DD_DOMA_GET'
EXPORTING
domain_name = 'PKBST'
TABLES
dd07v_tab_a = tab_a
dd07v_tab_n = tab_n
EXCEPTIONS
illegal_value = 1
op_failure = 2
OTHERS = 3.
LOOP AT tab_a WHERE domvalue_l = kanban_pieno.
ENDLOOP.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 005
WITH i_pkkey kanban_pieno tab_a-ddtext
INTO o_messaggio.
o_esito = 2.
EXIT.
ENDIF.
* controllo che lo stato sia modificabile
CALL FUNCTION 'Z_CHECK_KANBAN'
EXPORTING
i_pkkey = i_pkkey
IMPORTING
esito = o_esito.
IF o_esito <> 0.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 016
INTO o_messaggio.
o_esito = 3.
EXIT.
ENDIF.
* Verifico che il Kanban non abbia blocchi
CALL FUNCTION 'PK_ENQUEUE_KANBAN'
EXPORTING
i_scope = '2'
i_pkkey = i_pkkey
EXCEPTIONS
error_message = 1.
IF sy-subrc <> 0.
MESSAGE ID 'ZPP_KANBAN' TYPE 'E' NUMBER 014 WITH i_pkkey INTO o_messaggio.
o_esito = 4.
EXIT.
ENDIF.
* Trovo lo stato successivo previsto da ciclo Kanban
IF NOT wa_pkhd-pkste IS INITIAL.
SELECT SINGLE * FROM tpk01 INTO wa_tpk01
WHERE werks EQ wa_pkhd-werks
AND pkste EQ wa_pkhd-pkste.
MOVE-CORRESPONDING wa_tpk01 TO wa_tpk00.
ELSEIF NOT wa_pkhd-pkstf IS INITIAL.
SELECT SINGLE * FROM tpk02 INTO wa_tpk02
WHERE werks EQ wa_pkhd-werks
AND pkstf EQ wa_pkhd-pkstf.
MOVE-CORRESPONDING wa_tpk02 TO wa_tpk00.
ELSEIF NOT wa_pkhd-pkstu IS INITIAL.
SELECT SINGLE * FROM tpk03 INTO wa_tpk03
WHERE werks EQ wa_pkhd-werks
AND pkstu EQ wa_pkhd-pkstu.
MOVE-CORRESPONDING wa_tpk03 TO wa_tpk00.
ENDIF.
CALL FUNCTION 'PK_GET_STATUS'
EXPORTING
pksae_iv = wa_tpk01-pksae
pkhd_is = wa_pkhd
pkps_is = wa_pkps
tpk00_is = wa_tpk00
* no_status_restr_iv = exclude_status_restriction
IMPORTING
nextstatus_ev = wa_nextstatus
EXCEPTIONS
error_message = 1.
IF wa_nextstatus IS INITIAL.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 019 INTO o_messaggio.
o_esito = 9.
ENDIF.
* chiamo FM per cambio stato
CALL FUNCTION 'BAPI_KANBAN_CHANGESTATUS1'
EXPORTING
kanbanidnumber = i_pkkey
nextstatus = wa_nextstatus
IMPORTING
return = return.
IF return-type IS INITIAL.
MESSAGE ID 'ZPP_KANBAN' TYPE 'S' NUMBER 018 INTO o_messaggio.
o_esito = 0.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ELSE.
MESSAGE ID return-id
TYPE return-type
NUMBER return-number
WITH
return-message_v1
return-message_v2
return-message_v3
return-message_v4 INTO return-message.
o_messaggio = return-message.
o_esito = 9.
ENDIF.
ENDFUNCTION.
Codifica messaggi:
004 Il Numero Identificativo &1 non esiste
005 Identificativo &1 non ha lo stato &2 &3
014 ID &1 blocc.!
015 Ciclo Kanban &1 inesistente.
016 Stato non modificabile per tempo attesa.
017 C.I.D. &1 non trovato.
018 Operazione eseguita correttamente.
019 Errore generico.
Nota: all'interno del codice uso una funzione Z (Z_CHECK_KANBAN) che controlla se è possibile effettuare il cambio stato di un cartellino verificando il tempo minimo di attesa previsto. (Vedi questo post per come è definito). Si può anche commentare tutta questa parte se non si vuole definire il FM di controllo.
Nessun commento:
Posta un commento