2012 Nov 20 7:42 AM
Hi all,
I have a new requirement which seems pretty complicated to me:
In SAP, there is a number of SAPScript forms. To each of these is assigned a specific print_program which essentially gets the data out of the DB_tables and puts it in the form.
Now, I don't want to rebuild any of the forms. They are a SAP thing all right. What I want is only the information which tables and fields a specific form is using. These I could collect simply by reading the print_program.
I wonder if there would be a possibility to dynamically read the code of a print_program and just single out the tables and fields used. Again, I am not interested in the form itself, the "where does this go" part, only in the underlying data.
Can anybody help me there, please?
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 21 8:47 AM
Hi,
You can develop a utility from the sample code which I have provided in this link List the environment variables used in a program | ABAP Help Blog
Pass the print program to the sample program and mark the relevant option as X to be searched.
In you case mark environment_selection-tabl, environment_selection-view etc as 'X'. The underlying function REPOSITORY_ENVIRONMENT_SET_RFC does all the search.
Hi all,
I have a new requirement which seems pretty complicated to me:
In SAP, there is a number of SAPScript forms. To each of these is assigned a specific print_program which essentially gets the data out of the DB_tables and puts it in the form.
Now, I don't want to rebuild any of the forms. They are a SAP thing all right. What I want is only the information which tables and fields a specific form is using. These I could collect simply by reading the print_program.
I wonder if there would be a possibility to dynamically read the code of a print_program and just single out the tables and fields used. Again, I am not interested in the form itself, the "where does this go" part, only in the underlying data.
Can anybody help me there, please?
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 20 8:29 AM
hi,
go to nace transaction to see the output types .
Goto nace->outputtypes -> choose accoding to your requirement (ex : sales, Billing,etc)->
choose output types -> processing routines -> there you can find the form name and the driver program which is assigned for that perticular output. From the routine and the driver program you can find out from which tables data is fetching from.
Hope my answer will be helpful,
Thanks and regards,
Vinoth Aruldass.
2012 Nov 20 8:35 AM
Hi vinoth,
I cannot say yet how far your answer will take me, but I am more than thankful for any help. I am trying to find something online - and I have found sth on executing ABAP code from a PC file, which might be helpful - but since there's a lot on the line for me and I am by no means an expert myself, any help is highly appreciated.
I will see.
Thanks!
Best regards,
Sapperdapper
2012 Nov 20 8:34 AM
Check the below program and Keywords..
RPR_ABAP_SOURCE_SCAN
Scan Abap-Source TB_INCLUDELINES Tokens Into TB_TOKENS
With Includes
Statements Into TB_STATEMENTS
Keywords From TB_KEYWORDS.
Hope this helps
2012 Nov 20 8:41 AM
Hi Venkat,
I repeat myself 😉 I cannot say yet, I am no expert myself, I have a huge task and there's a lot on the line, so any help is highly appreciated.
I guess from the wording of your sample code that the INCLUDE structures of a program can also be scanned. That is of course important as the use of INCLUDEs is just good programming and thus an omnipresent concept. Too bad the print_programs I need to scan also contain function calls. Well, taking one step at a time will be more likely to help than trying to take a big leap.
I will see.
Thanks!
Best regards,
Sapperdapper
2012 Nov 20 8:54 AM
Hi Friedrich.
Check the below code to scan all the things.. Includes and Functioncalls everything...
Remember Function Module is nothing but a Include Program..(You can check that in Func Grp/Main Program of that Function Module)
Just check the below code and see the result I have maximum logic you require.. Sorry,cannot copy paste the whole program here.. But this will help u...
Start-Of-Selection.
* From to Get the Data for Checking Hard Codes
Perform GET_DATA.
In the Get Data Routine
*Read Includes of the program need to be searched
Perform SCANFORINCLUDEPROGRAMS Using PPROG
PRECI
PINC"C_X
TB_PROGRAM.
*----------------------------------------------------------------------
* scanForIncludePrograms... Search each program for include programs
*----------------------------------------------------------------------
FORM SCANFORINCLUDEPROGRAMS Using Value(PROGRAMNAME)
Value(RECURSIVEINCLUDES)
Value(CUSTOMERONLY)
TB_LOCINCLUDES Like TB_PROGRAM.
* Local Declarations
Data: TB_INCLUDELINES Type Standard Table OF TEXT200 With Header Line,
TB_TOKENS Type Standard Table OF STOKEN With Header Line,
TB_KEYWORDS Type Standard Table OF TEXT20 With Header Line,
TB_STATEMENTS Type Standard Table OF SSTMNT With Header Line.
Data: WATOKENS Type STOKEN,
WAINCLUDE Type T_PROGRAM,
WAINCLUDEEXISTS Type T_PROGRAM,
MAXLINES Type I,
NEXTLINE Type I,
CASTPROGRAMNAME Type PROGRAM.
* Read the program code from the textpool.
CASTPROGRAMNAME = PROGRAMNAME.
".
Read Report CASTPROGRAMNAME Into TB_INCLUDELINES.
Append 'INCLUDE' To TB_KEYWORDS.
Scan Abap-Source TB_INCLUDELINES Tokens Into TB_TOKENS
With Includes
Statements Into TB_STATEMENTS
Keywords From TB_KEYWORDS.
".
Scan Abap-Source TB_INCLUDELINES Tokens Into TB_TOKENS
With Includes
Statements Into TB_STATEMENTS
Keywords From TB_KEYWORDS.
Clear TB_INCLUDELINES[].
Describe Table TB_TOKENS Lines MAXLINES.
Loop At TB_TOKENS Where STR = 'INCLUDE' And TYPE = 'I'.
NEXTLINE = SY-TABIX + 1.
If NEXTLINE <= MAXLINES.
Read Table TB_TOKENS Index NEXTLINE Into WATOKENS.
* Are we only to find customer includes?
".
If Not CUSTOMERONLY Is Initial.--------------------------> When Customer Includes only need to
If WATOKENS-STR+0(1) = 'Y' be searched...
OR WATOKENS-STR+0(1) = 'Z'
OR WATOKENS-STR+0(2) = 'MZ'
OR WATOKENS-STR+0(2) = 'MY'.
Else.
* Continue to the Next Iteration
Continue.
Endif.
Endif.
WAINCLUDE-PGNAME = WATOKENS-STR.
* Don't append the include if we already have it listed
".
Read Table TB_LOCINCLUDES Into WAINCLUDEEXISTS
With Key PGNAME = WAINCLUDE-PGNAME.
IF Sy-Subrc <> 0.
Append WAINCLUDE TO TB_LOCINCLUDES.
If Not RECURSIVEINCLUDES Is Initial And
Not WAINCLUDE Eq 'STRUCTURE'.
* Do a recursive search for other includes
".
Perform SCANFORINCLUDEPROGRAMS Using WAINCLUDE-PGNAME
RECURSIVEINCLUDES
CUSTOMERONLY
TB_LOCINCLUDES[].
Endif.
Endif.
Endif.
Endloop.
ENDFORM. "scanForIncludePrograms
In Top Include
Parameters: PPROG Type TRDIR-NAME.
Selection-Screen Begin Of Line.
Selection-Screen Comment 1(22) TEXT-007.
Parameters: PINC As Checkbox Default 'X' Memory Id MINC.
Selection-Screen Comment 35(20) TEXT-008.
Parameters: PRECI As Checkbox Default 'X' Memory ID mreci.
Selection-Screen End OF Line.
2012 Nov 20 8:40 AM
Hello Friedrich,
Will Syntax
READ REPORT prog INTO itab [MAXIMUM WIDTH INTO wid].
help you ?
And then further you can parce it using Regular Expression / or Ucan use Function module to get the Local / Global Fields etc to carry on further processing
Hope this helps ..
Anup Deshmukh
2012 Nov 20 8:48 AM
Hi Anup,
Yes, I think that might actually help me. I can LOOP through that table then and when I meet something like "CALL FUNCTION" or so, I have to access that and do the same over.
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 20 9:01 AM
Hi,
A rough idea I have is as follows:
if you know the print program name, you can read that program code into an internal table of your new program using READ REPORT statement. On the internal table, you can use FIND ALL OCCURRENCES of SELECT keyword to get the select queries list. from that use SPLIT commands (might be other string operations) to get field names & table (after keyword FROM).
also check program RS_ABAP_SOURCE_SCAN.
Regards,
SG.
2012 Nov 20 9:11 AM
Hi Sravan
I have a question.
Do we have this program in ECC / 4.6/7...
2012 Nov 20 9:23 AM
Hi Venkat,
I just saw you posted a page of code here. That's just great! I will see what that does and where it takes me.
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 20 9:32 AM
Yes, Venkat. we are on ECC 6.0 EHP5 and have this program. I remember using this program before upgrade to EHP5 also. I am not sure about 4.6/7.
I was late in replying previous thread, by the time I posted so many replies appeared (hence my reply became redundant). which version are you on?
2012 Nov 20 9:39 AM
You could also try: SE38, enter print program name, choose Utilities -> Environment analysis, and check "database table".
Or try running an ST12 analysis for the print process, the "SQL summary" will give you all tables that were actually accessed.
Thomas
2012 Nov 20 10:51 AM
Hi,
@Venkat
I have the program RPR_ABAP_SOURCE_SCAN all right. I was sceptical about that because this system here is really outdated. That doesn't go quite in the same direction I need because it scans for a particular string (or set of strings) while I don't even know what those might be.
I'm just working through that code of yours. Am I right that in that GET_DATA routine I would have to fill in something and that other form is only to scan the INCLUDE structures too?
If so, I could combine that with what Anup and Sravan have said, that READ REPORT command. Putting it all into an internal table and parsing that for the kind of strings I'm looking seems a good idea, attractive to me because I've done that kind of thing before - in another, simpler language and scanning relatively well-structured ASCII files, but anyway.
Thanks a lot!
Regards,
Sapperdapper
2012 Nov 20 11:30 AM
Actually Friedrich I provided two Checkboxes in the Selection Screen.
Customer Includes Only --- Which will search in Z/Y Programs
Recursive Includes --- Which will search in Recursive Includes (example Include A contains Include Top and Include Forms etc...)
First thing is you need to check both the checkboxes
second thing code part.. Coming to your question.
In GET_DATA You just need to fill TB_PROGRAM.. That means what are the programs(Include Programs or Modulepool or FM Includes) that you want to search the String you want.
Example Get NAME from TRDIR where NAME = XXX or wild search with Z/y etc...
Then remaining thing goes as usual.. In GET_DATA you will have
Perform SCANFORINCLUDEPROGRAMS Using PPROG
PRECI--------> Recursive Includes Checkbox
PINC"C_X----> Customer Includes Only Checkbox (Uncheck if u want to search SAP also)
TB_PROGRAM.
Then Everything is same... Hope this helps
2012 Nov 20 12:39 PM
Hi Venkat,
I don't quite understand that TB_PROGRAM. The other parameters I have to pass to that subroutine I understand. What is TB_PROGRAM, though? Is that a fixed internal table? What fields does it need to have?
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 20 12:48 PM
ok sorry .. forgot to tell you this..
here we go..
Types: Begin OF T_PROGRAM,
PGNAME Like TRDIR-NAME,
End OF T_PROGRAM.
DATA : TB_PROGRAM Type Table OF T_PROGRAM.
*Put a Parameter or Select-Option like this
Parameters: PPROG Type TRDIR-NAME. You can enter the programs you want to search..
Append PPROG to TB_PROGRAM..
Hope this clears..
2012 Nov 20 12:58 PM
Hi Venkat,
yes, this certainly clears up that question. I'm sure I will be back in a short while with the next question 😉 I hope I won't end up annoying you too much.
So I can pass that code the name of an ABAP program I want to search. That's a good start. I'm sure there is a table that I can use to map the corresp. ABAP program to any form. Well, first things first. I'll start by giving the name of one program I know and if I can automatically read that and its INCLUDEs, so much the better.
Thanks a lot!
Best regards,
Sapperdapper
P.S.: Ok, I think it's making progress. I go stepwise, always activating just a piece of the code up to a point, then putting in a BREAK-POINT and deactivating the rest - ABAP has an annoying habit of stopping because of syntax errors in the parts after the BREAK-POINT which I'm not interested in for the moment...
Anyway, I can read the code into that internal table now. There isn't much to see, there are only INCLUDEs on the top-level, just as it should be actually, but I guess that is what the rest of the code is about. Here we go...
P.P.S.: Immediately following the line >> Append 'INCLUDE' To TB_KEYWORDS. << you have the same SCAN command twice. Was that on purpose or just a copy-paste-error?
2012 Nov 20 1:33 PM
No Friedrich.. It is for Scaning recursive includes. Here we go I shortened the code without any syntax error or anything. One thing I need to tell is.. In the Selection Screen Enter the program name as SAPMV45A which is a Sales order program name (Just for test) and execute. inthe TB_OUT_TMP you will see the result of all hardcoded values in the program and its respective includes..
REPORT YCR_HARD_CODE_TEMP.
*&---------------------------------------------------------------------*
*& Report : YCR_HARD_CODE
*& Author : Venkat Sesha, MYLAVABH, 01/18/2011
*& Descrption : This Report will give the detailed comments
*& on the Hardcoded Values in a Program Including
*& the Includes of that particular Program.
*& Note : Please do not Pretty Print the Program
*&---------------------------------------------------------------------*
Type-Pools: SLIS, ICON.
Tables : TRDIR.
* Include program names
Types: Begin OF T_PROGRAM,
PGNAME Like TRDIR-NAME,
End OF T_PROGRAM.
Types: Begin Of T_OUT_TMP,
PGType Type C, "A: Program B: Includes used for sorting
PGNAME Like TRDIR-NAME,
HDCDEXIST Type C,
TIMES Type I,
LINENO Type I,
PGLINE Type TEXT200,
End OF T_OUT_TMP.
Data: X_OUT_TMP Type T_OUT_TMP,
X_PROGRAM Type T_PROGRAM.
Data: TB_OUT_TMP Type Table OF T_OUT_TMP,
TB_PROGRAM Type Table OF T_PROGRAM.
* Declarations for Obsolete & Unicode Check search
Data : TB_RODIR Type Table Of RODIR,
X_RODIR Type RODIR.
Constants: C_YES(1) Value 'Y',
C_NO(1) Value 'N',
C_ASTERIX(1) Value '*',
C_DQUOTATION(2) Value '"',
C_X Value 'X',
C_A Value 'A',
C_B Value 'B',
C_S Value 'S',
C_Q Value ''''''.
Parameters: PPROG Type TRDIR-NAME Obligatory.
Selection-Screen Begin Of Line.
Selection-Screen Comment 1(22) TEXT-007.
Parameters: PINC As Checkbox Default 'X' Memory Id MINC.
Selection-Screen Comment 35(20) TEXT-008.
Parameters: PRECI As Checkbox Default 'X' Memory ID mreci.
Selection-Screen End OF Line.
*----------------------------------------------------------------------*
* S T A R T O F S E L E C T I O N *
*----------------------------------------------------------------------*
Start-Of-Selection.
* From to Get the Data for Checking Hard Codes
Perform GET_DATA.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM get_data .
* Local Declarations
Data: L_PRELEN Type I,
L_PRESTRING Type TEXT200,
L_LINE_NO Type I,
L_TMP_RCD Type TEXT200,
LX_LINES Type TEXT200,
LTB_LINES Type Standard Table Of TEXT200,
LTB_TMP_RCD Type Standard Table Of TEXT200,
LX_DDO7V Type DD07V,
LTB_DD07V Type Table Of DD07V,
LTB_SPLIT Type Table Of TEXT200,
LX_SPLIT Like Line Of LTB_SPLIT,
A Type Char2.
* Append the Program Name
Append PPROG To TB_PROGRAM.
*Read Includes of the program need to be searched
Perform SCANFORINCLUDEPROGRAMS Using PPROG
PRECI
PINC"C_X
TB_PROGRAM.
* Process the Program lines
Loop At TB_PROGRAM Into X_PROGRAM.
*Read program codes into an internal table
Read Report X_PROGRAM-PGNAME Into LTB_LINES.
* If Found.
If Sy-Subrc = 0.
* Process the data
Loop At LTB_LINES Into LX_LINES.
* Capture the Table Index
L_LINE_NO = SY-TABIX.
Condense LX_LINES.
***Omit comment lines and blank lines.
If LX_LINES+0(1) = C_ASTERIX Or LX_LINES = SPACE.
Continue.
Endif.
"LOOP AT TB_yerphardcode INTO X_yerphardcode.
Search LX_LINES For C_Q.
IF Sy-Subrc EQ 0.
*Omit the comments beginning with double qutation
Clear: L_PRELEN, L_PRESTRING.
L_PRELEN = SY-FDPOS.
If L_PRELEN Ne 0.
L_PRESTRING = LX_LINES+0(L_PRELEN).
Search L_PRESTRING For C_DQUOTATION.
* If Found
If Sy-Subrc = 0.
Continue.
Endif.
Endif.
*Get the values for the output list
"MOVE-CORRESPONDING X_yerphardcode TO X_out_tmp.
If X_PROGRAM-PGNAME = PPROG. "used for sorting of list
X_OUT_TMP-PGTYPE = C_A.
Else.
X_OUT_TMP-PGTYPE = C_B.
Endif.
X_OUT_TMP-PGNAME = X_PROGRAM-PGNAME.
X_OUT_TMP-HDCDEXIST = C_YES.
X_OUT_TMP-TIMES = 1.
X_OUT_TMP-LINENO = L_LINE_NO.
X_OUT_TMP-PGLINE = LX_LINES.
Append X_OUT_TMP To TB_OUT_TMP.
Clear X_OUT_TMP.
ENDIF.
"ENDLOOP.
Endloop.
Endif.
Sort TB_OUT_TMP By PGTYPE PGNAME." zfarea zcode.
Endloop.
".
*If no data found,leave to selection screen.
Read Table TB_OUT_TMP Transporting No Fields
With Key HDCDEXIST = 'Y'.
* If Not Found
If Sy-Subrc NE 0.
* Status Message
Message 'No data found' Type C_S.
* leave the program
Leave List-Processing.
Endif.
ENDFORM. " GET_DATA
*----------------------------------------------------------------------
* scanForIncludePrograms... Search each program for include programs
*----------------------------------------------------------------------
FORM SCANFORINCLUDEPROGRAMS Using Value(PROGRAMNAME)
Value(RECURSIVEINCLUDES)
Value(CUSTOMERONLY)
TB_LOCINCLUDES Like TB_PROGRAM.
* Local Declarations
Data: TB_INCLUDELINES Type Standard Table OF TEXT200 With Header Line,
TB_TOKENS Type Standard Table OF STOKEN With Header Line,
TB_KEYWORDS Type Standard Table OF TEXT20 With Header Line,
TB_STATEMENTS Type Standard Table OF SSTMNT With Header Line.
Data: WATOKENS Type STOKEN,
WAINCLUDE Type T_PROGRAM,
WAINCLUDEEXISTS Type T_PROGRAM,
MAXLINES Type I,
NEXTLINE Type I,
CASTPROGRAMNAME Type PROGRAM.
* Read the program code from the textpool.
CASTPROGRAMNAME = PROGRAMNAME.
".
Read Report CASTPROGRAMNAME Into TB_INCLUDELINES.
Append 'INCLUDE' To TB_KEYWORDS.
Scan Abap-Source TB_INCLUDELINES Tokens Into TB_TOKENS
With Includes
Statements Into TB_STATEMENTS
Keywords From TB_KEYWORDS.
".
Scan Abap-Source TB_INCLUDELINES Tokens Into TB_TOKENS
With Includes
Statements Into TB_STATEMENTS
Keywords From TB_KEYWORDS.
Clear TB_INCLUDELINES[].
Describe Table TB_TOKENS Lines MAXLINES.
Loop At TB_TOKENS Where STR = 'INCLUDE' And TYPE = 'I'.
NEXTLINE = SY-TABIX + 1.
If NEXTLINE <= MAXLINES.
Read Table TB_TOKENS Index NEXTLINE Into WATOKENS.
* Are we only to find customer includes?
".
If Not CUSTOMERONLY Is Initial.
If WATOKENS-STR+0(1) = 'Y'
OR WATOKENS-STR+0(1) = 'Z'
OR WATOKENS-STR+0(2) = 'MZ'
OR WATOKENS-STR+0(2) = 'MY'.
Else.
* Continue to the Next Iteration
Continue.
Endif.
Endif.
WAINCLUDE-PGNAME = WATOKENS-STR.
* Don't append the include if we already have it listed
".
Read Table TB_LOCINCLUDES Into WAINCLUDEEXISTS
With Key PGNAME = WAINCLUDE-PGNAME.
IF Sy-Subrc <> 0.
Append WAINCLUDE TO TB_LOCINCLUDES.
If Not RECURSIVEINCLUDES Is Initial And
Not WAINCLUDE Eq 'STRUCTURE'.
* Do a recursive search for other includes
".
Perform SCANFORINCLUDEPROGRAMS Using WAINCLUDE-PGNAME
RECURSIVEINCLUDES
CUSTOMERONLY
TB_LOCINCLUDES[].
Endif.
Endif.
Endif.
Endloop.
ENDFORM. "scanForIncludePrograms
where ever you find code "Search LX_LINES For C_Q." in the place or C_Q('''') you need to enter a string or something what you want to search.. in the End-of-selection event Write : TB_OUT_TMP.
Hope this Solves...
2012 Nov 20 1:44 PM
Thanks a lot!
I will try it immediately.
P.S.: Okay, it executes error-free. Only, it does not find any data yet although that program (SAPMV45A) is there all right and it has a number of INCLUDEs. I must be getting it wrong with what I have to replace for C_Q. I am trying to understand just what your code is doing. Maybe it will become clearer. Maybe you could help me there?
Thanks a lot indeed!
Best regards,
Sapperdapper
P.P.S.: Okay - when I deselect the checkbox for "customer-INCLUDEs only" - I want to search SAP's own code - then the code does return data. It's not quite right yet, but I guess it's working, only I haven't yet figured out how to use it.
P.P.P.S.: I guess inputting 'vbak' for that C_Q was not the best idea as I want that to be generic, but at least it's returning data. The interesting part seems to be in the field PGLINE. That's the one I will have to work on using some REGEX to single out the tables and fields.
2012 Nov 21 6:23 AM
Make the C_Q as a Parameter in the selection Screen to be that as generic.. Where you can enter the Table Name or Field Name etc...
PGLINE returns the Program line Number. Where it is been hardcoded/used in the program.
Hope this helps..
2012 Nov 21 7:49 AM
Hi Venkat,
yes, that would certainly be a possibility. Actually, however, I don't want to input any specific search string - for the moment I rather want to parse all the code and then single out all the tables and fields used by the printprogram. For that reason, I'm not actually interested in knowing where in the code a specific table is named. I just want to draw them all out. I'm sure that way I will get a lot of stuff that I don't want, which is all about the form itself while I just want the contents, but that would be a start.
I will see, maybe I can simply deactivate that SEARCH line.
Thanks a lot!
Best regards,
Sapperdapper
2012 Nov 21 8:23 AM
ok thats a better idea.. Just a heads up for you..
Select all the Table Names and field names (from DD02L) into a ITAB and later populate them into a Table TB_MARK with Typed as follows. TB_MARK Type Table of String With Header Line.
Now Populate all records of ITAB into TB_MARK. then use the below logic
The below logic will work like this. First in X_OUT_TMP-PGLINE you will get a program line(Code line from a Program(ommiting the Comments**"")) now Search will search each and every table and field in that particular line.
Loop At TB_MARK.
If X_OUT_TMP-PGLINE CS TB_MARK.
Search X_OUT_TMP-PGLINE For TB_MARK And Mark. -----> This will help you I hope.
If Sy-Subrc = 0.
* Fill data into a Final Table for display
Endif.
Else.
Continue.
Endif.
Endloop.
Remember the time constraints/performance Issues may occur with this logic. Hope this clears...
2012 Nov 21 8:47 AM
Hi,
You can develop a utility from the sample code which I have provided in this link List the environment variables used in a program | ABAP Help Blog
Pass the print program to the sample program and mark the relevant option as X to be searched.
In you case mark environment_selection-tabl, environment_selection-view etc as 'X'. The underlying function REPOSITORY_ENVIRONMENT_SET_RFC does all the search.
2012 Nov 21 9:00 AM
Agreed with Kesavadas.
It will return out only in a single program. You need search in Recursive Includes and need to write a logic for that where you already have it.
Now just use that FM to search what you need..
@ Kesavadas.. Good Job ..
2012 Nov 21 9:22 AM
Hi Kesavadas, Hi Venkat,
thanks for the help! I was going to tell you about a possible alternative way I have been thinking about, where I might be able to find all the info on one level instead of the multiple nested levels of a PrintProgram, but now I will first work through the code proposed by Kesavadas. The idea behind it seems to be brillant, Thomas also proposed the way via SE38 and that works, but to automate sth is always a different matter. I only hope that function is available on this system - as I mentioned before, it is really outdated...
I'm sure I will be back 😉
Until then, many thanks!
Best regards,
Sapperdapper
2012 Nov 21 10:18 AM
Hi Kesavadas,
I copied, read through and executed your code - it is awesome!
It does not go all the way, but that's not a problem in the code itself: I checked >Database tables< and >Programs< to search and the code returned six entries: The name of the INCLUDEs - two of them nested, too - and three table_names.
What I would thus need to do is loop backwards, input the name of one of the INCLUDEs the code has found and do the same thing again. I don't know how to program something to parse multiple nested levels, which is like an unknown number of nested loops, but I can just hold on to one example where I know the number of levels and write a set of loops for that.
The remaining problem is: In the INCLUDEs within that print program, there's no mention of the DB tables - not in the activated part, anyway. The only place where there are any table_names is in a function call in one of the includes - but I cannot open that in SE38, so I probably can't get that in that way?
Best regards,
Sapperdapper
2012 Nov 21 10:43 AM
For searching in function module pass 'FUNC' as obj_type along with the fm name and other parameters.
2012 Nov 21 11:05 AM
2012 Nov 21 11:06 AM
Great! Thanks a lot!
It seems that this PrintProgram is like an iceberg - in that function module, there is - a series of other function modules 😉 Well, I will work through all that heap manually for now and see how many and what DB_tables I find there, maybe try it out for two or three Printprograms. Then, when I see that I get a list of tables that looks complete and sensible - I don't know yet how to check whether I really have all the tables - then I can go about running that code recursively through all the levels. Maybe if I can work out exactly how the code I have from Venkat is working, I can combine that - that code is recursive all right, it just seems to do a lot more than I need, returning a lot more data. Performance is not supposed to be the first priority when writing a new program, but I have to think of it from the beginning and not selecting unnecessary data is better than later discarding it.
Thanks again!
Best regards,
Sapperdapper
2012 Nov 21 11:09 AM
Oh my,
you were faster than I was. You mention that method in that blog also. I assume it's essentially doing the same thing?
I will try understanding just what it does.
Thank you!
Best regards,
Sapperdapper
2012 Nov 21 11:33 AM
I have edited my previous post, when passing DEEP into the fm, it searches deep from an object type ie. TABL->DTEL->..., not deep inside the objects included in the main program.In your case, you have to change the object type and use it in recursive loops.
2012 Nov 21 11:45 AM
Hi Kesavadas,
I don't understand the term "deep search" by heart, but the way you tell I guess that every time that code encounters a table, it searches out all fields in that table, right?
Well, that can be done another way. Also, my primary task is only to make available all the tables (and all the fields) which are available for a specific form. I guess that once a user has generated a form, there is some kind of file holding the information what he actually used.
Well, I will go with what I understand, that seems the better way to go. I will thus do as I was planning, first I will do all the necessary iterations of that code manually and assemble a table_list and then I can think about making it run recursive and making the object_type change when necessary.
Thanks a lot!
Regards,
Sapperdapper
2012 Nov 21 1:22 PM
Hi Kesavadas,
either I have been getting something wrong with the settings or the code is omitting something: Three levels into one PrintProgram, searching function_modules (object_type FUNC), the code didn't return anything though there was another FM inside that - I cannot test that, I get a message "This is a SAP object and may not be checked". There were no DB_tables in those FMs that the code did not return, but I'm not sure about that when I use it on other PrintPrograms - can I be sure that I will not miss out on any tables because of that?
The list of tables I got is rather short and it does not, for ex., contain any vendor masterdata - which is likely necessary for a PO. That makes me wonder, are the necessary DB_tables listed somewhere else?
Best regards,
Sapperdapper
P.S.: Okay, I talked to a colleague who knows my situation as well as the overall task and right now, the important thing for me is getting all the tables which are in the printprogram out dynamically. Whether those are all the tables needed, which I doubt, is another matter and not prio1 for me right now.
2012 Nov 21 4:23 PM
I think my other recommendation drowned a little bit, and that is running an ST12 for the process and look at the resulting "SQL analysis". This is a compact form of the ST05 SQL trace.
No matter how deep the tables are hidden in the call stack, all that are actually accessed by the process will be found.
Thomas
2012 Nov 21 5:26 PM
Hi Thomas,
no, I didn't forget that recommendation. I know the SQL trace, I have used it myself quite a few times.
I am not sure that would help in the overall picture - the goal is reading the tables dynamically. I'm not sure how the results of an SQL trace can be accessed dynamically, but they should be accessible since they are no doubt saved somewhere. That will be the next thing I try since it seems that everything is not in the code itself although it goes approx. eight levels down...
Talk to you tomorrow!
Best regards,
Sapperdapper
P.S.: I just go about this thing stepwise - first, to have something to compare my code - to know what my code would have to do so I can say it works - I just read through the PrintProgram including all sub-levels. Any table_names I cannot find that way, any parsing done by a code will not find as it's not in the code. I will still try to complete the code then so I can find in the code all that is there, but in the long run, we will have to try something different, including the SQL trace.
I have also found another way, but I'm not sure about it, in part because I don't know for sure how to use SAPScript forms at all yet: There is a program - with the typical well-sounding ABAP name - to download the layout incl. all possible text elements to PC, which includes a number of table_names. That might be a way - parsing an ASCII file is relatively easy, so that may be worth a shot.
2012 Nov 22 10:07 AM
Hi all,
@ Kesavadas
I have now m.o.l. completed a "manual scan" of the PrintProgram - it goes about eight levels down, that's a lot. The problem is, when I try manually running your code for each of those levels - prior to making it run recursively - then on the third level, there are about five more FMs that it doesn't return - it does return some, but by no means all. That means when used recursively, as of now it won't go to certain sub-levels. Certain tables - like, for ex., LFA1 (vendor masterdata) I have found only on the seventh or so sub-level - precisely in one of the sub-structures that the code won't go to.
I will now try other possibilities, including that other function you mentioned. However, I am not sure whether I'm doing something wrong, causing the code to not go there or whether those paths are blocked on the system-side (possible?) or whatever the reason might be, for in principle the code works fine - also, it does return some FMs on the level in question, just not all the FMs in there.
Best regards,
Sapperdapper
P.S.: A possible reason could be that the environment_variables which are returned by that code are just not filled correctly on all levels by SAP. I am not sure about this, but - on the 7th sub-level of one PrintProgram, I found a comment by a SAP employee that something was not done properly, so he built a kind of workaround...
2012 Nov 22 1:32 PM
Hi,
I am not yet at the point where I need to be, but in the meantime, after all the help I got here, it would not be fair to hold back what I (think I) know in the meantime:
From reading the manual I understand that meta-information about all the DB_fields (and -tables) available in a form are in the text_elements that can be downloaded, along with the layout, on the PC in ASCII format, relatively easy to parse.
There is, however, also mention of the fact that design of a form is limited to using only those DB_tables which are defined in the PrintProgram using the keyword TABLES - so the world revolves, back to the PrintProgram.
The question is only, is the entirety of tables AVAILABLE - which is defined in the PrintProgram - really of importance or rather the subset of those tables that has actually been USED, which is indeed in the text_elements.
There are possibilities in the forms, like SAPScript_control_statements and variables and internal tables filled by the PrintProgram before even opening the form, which might make matters more complicated and might make parsing the code of the PrintProgram necessary after all, but since SAPScript_forms is a very old product, the fact that the data is all pretty much visible from the layout is plausible.
Best regards,
Sapperdapper
P.S.: Also, using the code by Venkat, I tried searching for that keyword TABLES - if I could find that, reading out all the subsequent lines of the code would be possible - but it doesn't seem to be there in the one PrintProgram I have picked as an example. Not very plausible given what the manual says, but apparently a fact.
| User | Count |
|---|---|
| 3 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |