I am working on a requirement to display warning message on MIRO when information entered meets required criteria. I have implemented BADI 'INVOICE_UPDATE' and using method "CHANGE_AT_SAVE".However i noticed the message is not being displayed even after my BADI implementation is being called.
I noticed that after BADI is called the following code executed to check and message are display if the transaction/posting is done in dialog mode. Is there a other user exit where i can display warning messages to the user?
IF sy-subrc <> 0.
IF s_rbkp-ivtyp NE c_ivtyp_dialog. " dialog...
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
CALL FUNCTION 'MESSAGE_STORE'
EXPORTING
arbgb = sy-msgid
msgty = sy-msgty
msgv1 = sy-msgv1
msgv2 = sy-msgv2
msgv3 = sy-msgv3
msgv4 = sy-msgv4
txtnr = sy-msgno.
ENDIF.
ENDIF.
are these variables filled? You can always use (if u have) message class and create a new one that suits what you need. EX:
MESSAGE e081(zdssd_exits) WITH i_vbrk-sfakn. "error message, stop action, keeps track
OR simple way without class (canĀ“t track error message)
MESSAGE 'whatever you want' TYPE 'I'. "Check all the types and what suits you
https://wiki.scn.sap.com/wiki/display/ABAP/ABAP+Message+Error+Handling+Standards
https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapmessage.htm
Hope it helped
Cheers
Related
I have a Modify statement to update a custom table after which I am calling BAPI_CONTRACT_CHANGE. When BAPI failed to change the document it's calling BAPI_TRANSACTION_ROLLBACK. However, it's not changing the data back in my custom table which was updated by Modify statement.
IF gt_return[] IS NOT INITIAL.
READ TABLE gt_return INTO gwa_return WITH KEY type = 'E'.
IF sy-subrc EQ 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
MESSAGE i021(zxx).
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = abap_true.
ENDIF.
ENDIF.
Appreciate your response.
Modify statement is present somewhere before the bapi call.and also this program can be run from external portal . The behaviour is as expected when I run it from the portal i.e, BAPI_TRANSACTION_ROLLBACK works and data doesn't get updated in the custom table. It fails only when I run it from ECC.
You get an implicit commit on each PBO screen interaction.
So any user interaction after the Insert/modify/update DB will be committed without code needing to issuing a commit work.
if you want to rollback , it must be done before the next PBO cycle.
I have a report, let's call it REPORT_A, and I'd like to clone it to REPORT_B, execute REPORT_B, and then come back.
I'm doing the following:
DATA: lv_report_name TYPE c LENGTH 30 VALUE `DEMO_LIST_OUTPUT`,
lv_new_report_name TYPE c LENGTH 30 VALUE `ZZ_DEMO_LIST_OUTPUT`,
lt_report_code TYPE abaptxt255_tab,
lv_message TYPE abaptxt255,
lv_line TYPE i,
lv_word TYPE abaptxt255.
READ REPORT lv_report_name INTO lt_report_code.
SYNTAX-CHECK FOR lt_report_code
MESSAGE lv_message
LINE lv_line
WORD lv_word.
IF sy-subrc = 0.
INSERT REPORT lv_new_report_name FROM lt_report_code STATE 'A'.
GENERATE REPORT lv_new_report_name.
SUBMIT (lv_new_report_name) VIA SELECTION-SCREEN AND RETURN.
ENDIF.
The syntax-check statement is returning sy-subrc = 4, and lv_message contains:
PERNR is not defined for the current logical database
This is the issue -> REPORT_A uses PNP logical database and has a get pernrstatement, so it fails the syntax-check.
Detail: REPORT_A is working just fine, tables pernr is declared in it. If I run it alone in SE38, it executes perfectly.
But, due to this weird error, I am always failing to generate REPORT_B.
Even if I skip the IF condition, it will then DUMP in the submit line, pointing a syntax error referring to the same error, "pernr is not defined for the current logical database".
Is there a way around it?
Can I call get pernr dynamically, so it doesn't fail the syntax check?
First of all, be careful, INSERT REPORT and GENERATE REPORT are statements for internal use (reserved to SAP).
If you still want to use the internal statements, see the rest of my answer.
Otherwise the workaround is to use GENERATE SUBROUTINE POOL. But it won't work for a logical database. If you copy a standard program maybe it's not a good idea of copying it (no note assistant to help you in case of patch/upgrade), so the classic workarounds are to add implicit enhancement options, or use eventual user exits proposed by SAP in this particular program (if any). There might be other options, but it depends on your exact goal, which you didn't share (yet).
The statement INSERT REPORT creates a source code module with a program entry (in table TRDIR) which by default corresponds to an Executable program (A.K.A. "report"), and so can be executed with SUBMIT.
But in your case, the program you want to generate is a program using a Logical Database, so you must assign the program attribute Logical database (TRDIR-LDBNAME).
The program attributes are to be passed via the words DIRECTORY ENTRY in the following statements:
SYNTAX-CHECK ... DIRECTORY ENTRY ls_trdir
INSERT REPORT ... DIRECTORY ENTRY ls_trdir
An easy solution for copying an existing program is to read its program attributes from the table TRDIR, change the name of the program (TRDIR-NAME) that you are creating, and pass them after the words DIRECTORY ENTRY.
Additional comments:
COMMIT WORK should be placed after GENERATE REPORT as explained in the documentation.
SY-SUBRC should be checked after INSERT REPORT and GENERATE REPORT.
Consequently, the following code will work:
DATA: lv_report_name TYPE c LENGTH 30 VALUE `DEMO_LIST_OUTPUT`,
lv_new_report_name TYPE c LENGTH 30 VALUE `ZZ_DEMO_LIST_OUTPUT`,
lt_report_code TYPE abaptxt255_tab,
lv_message TYPE abaptxt255,
lv_line TYPE i,
lv_word TYPE abaptxt255,
ls_trdir TYPE trdir.
READ REPORT lv_report_name INTO lt_report_code.
SELECT SINGLE * FROM trdir INTO ls_trdir WHERE name = lv_report_name.
ls_trdir-name = lv_new_report_name.
SYNTAX-CHECK FOR lt_report_code
MESSAGE lv_message
LINE lv_line
WORD lv_word
DIRECTORY ENTRY ls_trdir.
IF sy-subrc = 0.
INSERT REPORT lv_new_report_name FROM lt_report_code STATE 'A' DIRECTORY ENTRY ls_trdir.
IF sy-subrc = 0.
GENERATE REPORT lv_new_report_name.
IF sy-subrc = 0.
COMMIT WORK.
SUBMIT (lv_new_report_name) VIA SELECTION-SCREEN AND RETURN.
ELSE.
* Handle the error + rollback
ENDIF.
ELSE.
* Handle the error + rollback
ENDIF.
ELSE.
* Handle the error
ENDIF.
When I'm creating a purchase order that have 10 items (or above), a run time error occurred. Below is the error message.
Category: ABAP Programming Error
Runtime Errors: CONVT_NO_NUMBER
ABAP Program: SAPLMEPO
Include MM06EF0B_BUCHEN
Application Component MM-PUR
An exception occurred that is explained in detail below.
This exception cannot be caught in the context of the current statement. The reason for the exception is: An attempt was made to interpret value "*" as a number. As this value contravenes the rules for displaying numbers correctly, this was not possible.
Below is the code where an exception occurred:
DATA indx.
indx = 1.
* Need to merge KNT and XEKKN
* algorithm is: if knt is old, use knt. Else use the equivalent from xekkn
LOOP AT knt.
IF knt-updkz EQ oldpos.
MOVE-CORRESPONDING knt TO lt_ekkn.
ELSE.
READ TABLE xekkn INDEX indx.
MOVE-CORRESPONDING xekkn to lt_ekkn.
indx = indx + 1.
ENDIF.
APPEND lt_ekkn.
ENDLOOP. "v 2068862
It seems that the data type of indx (char 1), but when PO item index = 9, then index = 10 (actual value is * in debug mode ), so exception is happened.
How should I solve this problem?
I also post this issue here: https://scn.sap.com/message/16146617
You are right in assuming that indx is a C(1) since you (or the author of the code) did not specify a type. Changing the line to
DATA indx TYPE i.
should solve the issue.
Currently I have a script that checks to make sure that a test card was not submitted in production (since Authorize.net accepts test credit cards in live mode) and I add an error message to the credit card number if the one submitted is in the Test_Credit_Cards array like so:
TEST_CREDIT_CARDS = ['370000000000002', '6011000000000012', '4007000000027', '4012888818888']
validate :not_a_test_credit_card
def not_a_test_credit_card
self.errors[:cc_number] << "number is invalid!" if TEST_CREDIT_CARDS.include?(cc_number) and Rails.env.production?
end
Now on the front end the error message appears like so:
Credit card cc number is invalid!
Is there anyway to change the message to read Credit Card number is invalid! I just want to remove the cc portion from the message.
First, remove the number from the error message:
self.errors[:cc_number] << "is invalid!" if TEST_CREDIT_CARDS.include?(cc_number) and Rails.env.production?
Next, put a translation for cc_number in config/locales/en.yml:
en:
activerecord:
attributes:
credit_card:
cc_number: "number"
I prefer this answer over Anthony Alberto's answer for three reasons:
It is always a good idea to use ActiveRecord existing translation engine.
This way, cc_number will be translated to number whenever you add errors on it.
It is not true that the error is on the CreditCard instance itself, it is specifically related to the cc_number field.
That should do it :
self.errors[:base] << "number is invalid!" if TEST_CREDIT_CARDS.include?(cc_number) and Rails.env.production?
base refers to the object as a whole, not a specific attribute.
i wan to create a program that can get the application name
i can start the program but cant get the program name
<br/><br/>
a = Process.Start("calc").Handle<br/>
MsgBox(a)<br/>
MsgBox(Process.GetProcessById(a).ToSt</ br>ring)<br/>
<br/>
it show Process with an Id of 1796 is not running, but the program already opened
Handle!=Id, and ToString() won't give you the process name:
Dim a = Process.Start("calc").Id
MsgBox(a)
MsgBox(Process.GetProcessById(a).ProcessName)
Displays a process ID in one message box, then "calc" in the next.
If you had Option Strict On, you'd have received a warning already about your mixup between Handle and Id, since Handle returns an IntPtr, but GetProcessById expects an Integer.