Custom fields not showing on table output - abap

I'm having trouble figuring out why two custom fields are not showing up in transaction VA05 (its output to be specific).
Before reading below: I didn't make any changes to the program because I wasn't assigned to this task. One of my colleagues did this change.
I followed this tutorial, which explains how to expand the VA05 output table with custom fields.
I didn't actually followed this guide. I followed this tutorial only to understand what my colleague might have done to achieve what we need and what might be needed to fix the issue.
So, as the tutorial suggests, this is what should be done in short:
Go to SE11 and search for VBEP Database table and click display.
Click on Append Structure
Click on Create Append
Insert the name of the append name, in my case it's ZZVBEP_MECC
Insert two fields: ZZDELIVERYDATE and ZZREQDELIVERYDATE
Save and activate
If you go to VBEP table now, you'll see at the bottom the field .APPEND with the column Data Element set to ZZVBEP_MECC.
Now, following the tutorial, the include program V05TZZMO need to be changed, and here's ours:
***INCLUDE V05TZZMO .
* This form is called in the include LV05TFMO.
FORM MOVE_USERFIELDS USING ZP.
CASE ZP.
WHEN 'VBAK'.
WHEN 'VBAP'.
CHECK LVBAP-PSTYV NE 'ZRAC'.
CHECK LVBAP-PSTYV NE 'ZCAC'. "Escl.acconti
MOVE LVBAP-KDMAT TO LVBMTV-ZZKDMAT.
PERFORM OFFENE_AUFTRAGSMENGE.
SELECT SINGLE * FROM VBKD WHERE VBELN = LVBAP-VBELN.
IF SUBRC = 0.
MOVE VBKD-KDGRP TO LVBMTV-ZZKDGRP.
ENDIF.
WHEN 'VBEP'.
MOVE LVBEP-ZZDELIVERYDATE TO LVBMTV-ZZDELIVERYDATE.
MOVE LVBEP-ZZREQDELIVERYDATE TO LVBMTV-ZZREQDELIVERYDATE.
ENDCASE.
ENDFORM.
When I run VA05 however, these two custom fields are not there nor are in the Change Layout screen.
Is it possible that the code in V05TZZMO is not in the right place? Looking at the tutorial's code I saw that they put those statements in WHEN 'VBAK' instead of WHEN 'VBEP'.
Also, the ENHANCEMENT 1 ZZ_SD_VBAK_VA05 is not present in my code.
There might be something I missed. As I said above, I didn't make these changes so I cannot tell exactly what my colleague did.

Custom fileds also must be included in the structure VBMTVZ.
Regards

Finally solved.
Here's the procedure step-by-step we followed in order to fix the issue:
Create an Append Structure
Go to TCode SE11 and open database table VBMTVZ
Click on Append Structure...(It's in the program's toolbar) - or Goto > Append Structure
Create a new Append Structure(There's a button for it)
Enter the name of the structure(in our case was ZZVBMTVZ_MECC
A new structure is then created. Enter the needed components/fields
Save and activate the structure.
Note: To check if the structure is actually appended, go back and open table VBMTVZ again. At the end of the list of fields there must be one field called .APPEND with the type set to the name of the structure you created. After this field, there's also all your fields you created on that structure. See the image below for reference.
Change V05T program
Now you'll need to make some changes to the program linked to the TCode VA05.
To do this:
Go to TCode SE80.
Select Function Group and insert V05T as the name of the group.
Open the sub-folder called Includes and look for V05TZZMO
Open this include file in change mode.
The file should look like this:
***INCLUDE V05TZZMO .
* This form is called in the include LV05TFMO.
FORM MOVE_USERFIELDS USING ZP.
CASE ZP.
WHEN 'VBAK'.
* header
* MOVE LVBAK-XXXXX TO LVBMTV-ZZXXXXX.
WHEN 'VBAP'.
* item
* MOVE LVBAP-XXXXX TO LVBMTV-ZZXXXXX.
WHEN 'VBEP'.
* schedule line
* MOVE LVBEP-XXXXX TO LVBMTV-ZZXXXXX.
ENDCASE.
ENDFORM.
Add the following line of code to the WHEN 'VBEP'. code block.
MOVE LVBEP-name_of_your_field TO LVBMTV-name_of_your_field
You need to add that line for each field you appended.
In my case, the final result was the following:
***INCLUDE V05TZZMO .
* This form is called in the include LV05TFMO.
FORM MOVE_USERFIELDS USING ZP.
CASE ZP.
WHEN 'VBAK'.
* header
* MOVE LVBAK-XXXXX TO LVBMTV-ZZXXXXX.
WHEN 'VBAP'.
* item
* MOVE LVBAP-XXXXX TO LVBMTV-ZZXXXXX.
WHEN 'VBEP'.
* schedule line
* MOVE LVBEP-XXXXX TO LVBMTV-ZZXXXXX.
move LVBEP-zzdeliverydate to lvbmtv-zzdeliverydate.
move LVBEP-zzreqdeliverydate to lvbmtv-zzreqdeliverydate.
ENDCASE.
ENDFORM.
Save the file and activate the program.
At this point you should be able to see your fields in the output of TCode VA05.
Notes
In order to be able to change the include program V05TZZMO you need an Access Key. Without that you cannot change the program.
If the fields you appended aren't showing even after activating, try:
To logout and log back in or
reset the buffer with this TCode /$SYNC

Related

SubmitForm then Patch results in "The data returned by the service was invalid"

I'm building a PowerApps app on Azure SQL
The requirement
I have a form which has "Save" and "Confirm" buttons.
Both buttons should save the form data. The Commit button should also set database column "Confirm" to 1
I've read at length about how I can programatically override the update value of a hidden control for this. But I'm not satisfied with the level of complexity (maintenance) required to get this working, i.e.
Populate a variable with the current db value
In the button code set the variable value
In the form field, set the update property to the variable
What I'm Trying
So I'm trying a different approach: SubmitForm then Patch. Even though this requires an extra database call, I'd like to understand if this will work. This is the code for OnSelect in the commit button:
// Save the record
SubmitForm(frmEdit);
// Update confirmed to 1
Patch('[dbo].[Comments]',cRecord,{Confirmed:1});
Some Complexities
Note that my record is a variable, cRecord. In short I want this app to be able to upsert based on URL parameters.
This is my App.OnStart which captures URL values, inserts a record if required. Regardless, the result of this event is that cRecord is set to the record to be edited.
// Cache employees and store lookups (as they are in a different db)
Concurrent(Collect(cEmployees, Filter('[dbo].[SalesPerson]', Status = "A")),Collect(cStores, '[dbo].[Store]'));
// Check for parameters in the URL. If found, set to Edit/Add mode
Set(bURLRecord,If((!IsBlank(Param("PersonId")) && !IsBlank(Param("Date"))),true,false));
// If URL Parameters were passed, create the record if it doesn't exist
If(bURLRecord,
Set(pPersonId,Value(Param("PersonId")));
Set(pDate,DateValue(Param("Date")));
// Try and find the record
Set(cRecord,LookUp('[dbo].[Comments]',SalesPersonId=pPersonId && TransactionDate = pDate));
If(IsBlank(cRecord),
// If the record doesn't exist, create it with Patch and capture the resulting record
Set(cRecord,Patch('[dbo].[Comments]',Defaults('[dbo].[Comments]'),{SalesPersonId:pPersonId,TransactionDate:pDate}))
);
// Navigate to the data entry screen. This screen uses cRecord as its item
Navigate(scrEdit);
)
frmEdit.Item is set to cRecord. As an aside I also have a gallery that sets this variable value when clicked so we can also navigate here from a gallery.
The navigating using new and existing URL parameters works. Navigating from the gallery works.
The problem
When I press the Commit button against a record which has Confirmed=0 I get this popup error:
The data returned by the service is invalid
When I run this code against a record which already has Confirmed=1 I don't get an error
If I run the PowerApps monitor it doesn't show any errors but it does show some counts being run after the update. I can paste it here if required.
I also tried wrapping the Path in a Set in case it's result was confusing the button event but it didn't make a difference.
What I want
So can anyone offer me any of the following info:
How can I get more info about "The data returned by the service is invalid"?
How can I get this to run without erroring?
Is there a simpler way to do the initial upsert? I was hoping a function called Patch could upsert in one call but it seems it can't
With regards to the setting field beforehand approach, I'm happy to try this again but I had some issues implementing it - understanding which control where to edit.
Any assistance appreciated.
Edit
As per recommendations in the answer, I moved the patch code into OnSuccess
If(Confirmed=1,Patch('[dbo].[CoachingComments]',cRecord,{Confirmed:1}));
But now I get the same error there. Worse I cleared out OnSucces and just put SubmitForm(frmEdit); into the OnSelect event and it is saving data but still saying
The data returned by the service was invalid
First things first,
Refactoring has multiple steps,
I can t type all out at once...
The submitform and patch issue:
Never use the submitforn with extra conplexity
Submitform is only the trigger to send the form out,
The form handler will work with your data...
If you hsven t filled out the form correctly, u don t want to trigger your patch action...
So:
On your form, you have an OnSucces property,
Place your patch code there...
Change your cRecord in your patch statement:
YourForm.LastSubmit

SSRS - How to show external image based on URL inside column

I am trying to show images for products inside a basic report. The image needs to be dynamic, meaning the image should change based on the SKU value.
Right now I am inserting an image into a table, setting to external, and i've tried:
=Fields!URL.Value
=http://externalwebservername/sku= & Fields!SKU.Value
="http://externalwebservername/sku=" & Fields!SKU.Value
I do not get any images in my table.
My stored proc has all the data, including a URL with the image I wan't to show. Here is a sample of what the URL looks like:
http://externalwebservername/sku=123456
If I enter the URL in the field without "=" it will show that ONE image only.
How should I set up the expression to properly show the external image based on a dynamic URL? Running SQL 2016
Alan's answer should work, but in our environment we have strict proxy/firewall rules, so the two servers could not contact each other.
Instead we are navigating to the file stored on our storage system.
We altered the URL column to point to file path in the stored procedure. Insert image, set Source to External and Value set to [URL].
URL= file://server\imagepath.jpg
As long as the account executing the report has permissions to access the URLs then your 3rd expression should have worked.
I put together a simple example as follows.
I created a new blank report then added a Data Source. It doesn't matter where this points, we won't use it directly.
Then I created a dataset (Dataset1) with the following SQL to give me list of image names.
SELECT '350x120' AS suffix
UNION SELECT '200x100'
UNION SELECT '500x500'
Actually, these are just parameters for the website http://placehold.it/ which will generate images based on the size you request, but that's not relevant for this exercise.
We'll be showing three images from the following URLs
http://placehold.it/350x120
http://placehold.it/200x100
http://placehold.it/500x500
Next, create a table, I used 3 columns to give me more testing options. Set the DataSetName to DataSet1 if it isn't already.
In the first column the expression is just =Fields!suffix.Value
In the second column I added an image, set it's source property to External and the Value to ="http://placehold.it/" & Fields!suffix.Value
I then added a 3rd column with the same expression as the image Value so I could see what was being used as the image URL. I also added an action that goes to the same URL, just to check the URL did not have any unprintable characters in it that might cause a problem.
The basic report design looks like this.
The rendered result looks like this.

Qlik View: Retrive Last Reload of another report

In a qlik report(Main Report) i have a text object with an action that open another report. Is there the possibility to show in the text object located in the Main Report the last Reloadtime date of the report that i open with the action ?
thank's
while reloading the other report,
use:
T1:
Load reloadtime() as reloadTime autogenerate(1);
store T1 into T1.qvd;
in the Main report file:
Load * from T1.qvd (qvd);
you can also use *add* Load * from T1.qvd (qvd); if you want to use partial reload.
thats it :)
i can use filetime() function but the last change is not necessarily the date of the last reloadtime().
I could store these information externally in a txt-file which you read in your target-application as include-variable. This will require a reload from the target. As alternatively could these value be stored in a database and read then per direct discovery without a reload.
A further option could be to transfer these information per selections by opening: AJAX and URL parameters maybe by selection a loosen dummy-date-table and these selection will then be queried per getfieldselections().

Can the user be forced to enter a non-initial value by the Table Maintenance screen in SM30?

I'd like to force the user to chose between Yes and No, and not let him add an entry where the value is initial.
This is regardless of whether I check the Initial checkbox in the table definition.
Can this be done?
Domain data type : CHAR, 1 character, no conversion routine.
Value range: single values:
'1' description = 'Yes'
'2' description = 'No'
By far the easiest way is to use a data element in the table that only allows non-initial values.
If you can't change the data element, you can try using table maintenance events in the table maintenance generator:
You may be able to use event 1 (Before save) or event 5 to build a manual check, but 5 does not kick off on change.
If that doesn't work, you can still manually add a check in the PAI of the screen, however you run the risk that if someone regenerates the maintenance scree, they will forget/not know to put the check back in.
You can set the compare flag:
But from what I've seen the flag doesn't actually force you to redo any of the changes, and is still pretty easy to miss.
You can edit the screen and set the field to mandatory. Be aware that you will loose the change if the screen is re-generated.
You can do that with that steps:
in SE11 choose the Utilities menu -> Table Maintenance Generator
in the Table Maintenance Generator go to menu Environment -> Modification -> Maintenance Screens, then select the screen (usually is 0001), in the Element List Tab you find the Special attr, in the field Input, you choose Required for the field you want obligatory.
Thanks.
Regards.
Gil Mota.

Suppress first screen of transaction

I want to call Z-transaction via "CALL TRANSACTION" statement and skip the first screen, but AND SKIP FIRST SCREEN statement doesn't work.
I've read that it has sense only when 'ENTER' function code is used for moving between screens of transaction. Is it true?
Therefore I decided to use batch input table (BDC) via CALL TRANSACTION...USING bdc_table statement in order to process first screen in background.
However that way processing is returned to the initial transaction which I don't want to do!
The statement LEAVE TO TRANSACTION doesn't work with BDC table. Is there any other solution?
Addition to tomdemuyt:
Now I'm using batch table but if I used SKIP, I would rather write like this:
AUTHORITY-CHECK OBJECT 'S_TCODE'
ID 'TCD' FIELD lv_tcode.
IF sy-subrc <> 0.
MESSAGE 'No authorization for this operation!' TYPE 'E'.
ELSE.
* CALL TRANSACTION lv_tcode USING bdc_tab
* MODE 'E'
* UPDATE 'A'.
SET PARAMETER ID 'EBELN' FIELD p_ebeln.
LEAVE TO TRANSACTION lv_tcode AND SKIP FIRST SCREEN.
ENDIF.
On the first screen (the selection screen) p_ebeln parameter has to be selected and passed to the second screen without showing first.
I'm not sure what you're trying to do. Are you trying to skip the first screen and go to the second screen? If the transactions you're trying to call are executable programs, you have a few more options with submitting the program directly:
SUBMIT zprogram
WITH param1 = 'VALUE'
WITH selopt BETWEEN 'a' AND 'b'.
Alternatively you change the batch table to a selection table of type RSPARAMS. There are many other options including submitting with a specific variant, or calling a specific screen etc.