Does a OUTER-JOIN always divide the query in two parts, leaving the part on the right empty if not complete in Progress? - openedge

I'm trying to do an OUTER-JOIN in progress using this page as inspiration. My code is as follows
OPEN QUERY qMovto
FOR EACH movto-estoq
WHERE movto-estoq.lote BEGINS pc-lote
AND movto-estoq.it-codigo BEGINS pc-it-codigo
AND movto-estoq.dt-trans >= pd-data1
AND movto-estoq.dt-trans <= pd-data2
AND movto-estoq.cod-emitente = pi-cod-emitente,
EACH item OUTER-JOIN
WHERE movto-estoq.it-codigo = item.it-codigo,
EACH item-cli OUTER-JOIN
WHERE item-cli.item-do-cli BEGINS pc-item-cli
AND movto-estoq.cod-emitente = item-cli.cod-emitente
AND movto-estoq.it-codigo = item-cli.it-codigo
AND movto-estoq.un = item-cli.unid-med-cli,
EACH nota-fiscal OUTER-JOIN
WHERE movto-estoq.nro-docto = nota-fiscal.nr-nota-fis
BY movto-estoq.dt-trans DESCENDING BY movto-estoq.hr-trans DESCENDING.
The problem that is happening is when 1 element in null, all the other elements that are in the OUTER-JOIN are appearing as null as well, even though they are not null. Is there a better way to write this code? Should I put 'LEFT' before the OUTER-JOIN? Thanks for your time.

To make your example easier, consider making it work from ABL dojo. The following code:
define temp-table ttone
field ii as int
.
define temp-table tttwo
field ii as int
field cc as char
.
create ttone. ttone.ii = 1.
create ttone. ttone.ii = 2.
create tttwo. tttwo.ii = 2. tttwo.cc = "inner".
create tttwo. tttwo.ii = 3. tttwo.cc = "orphan".
define query q for ttone, tttwo.
open query q
for each ttone,
each tttwo outer-join where tttwo.ii = ttone.ii.
get first q.
do while available ttone:
message ttone.ii tttwo.cc.
get next q.
end.
Can be run from https://abldojo.services.progress.com/?shareId=600f40919585066c219797ed
As you can see, this results in :
1 ?
2 inner
The join which is not available is shown as unknown. The value of the outer part of the join is shown.
Since you do not show how you are getting an unknown value for everything, maybe you are concatenating the unknown values?

Related

Updating fields from changes in scroll levels

I have a page that has 3 levels. Levels 0 & 1 are from the same record. Level 2 is from a second record.
When a change is made to level 1, I would like to apply that change to the same field in Level 2's record.
Basically, this deals with EFF_STATUS in peoplesoft. If an effective row gets added to the record, and the EFF_STATUS is changed to Active or Inactive, I'd like to update the EFF_STATUS in my second record to match.
Here is the code I'm trying to execute and it is giving me an error of.. "Invalid row number 2 for class Rowset method GetRow. (2,263) K_OFFNSV_REC_EX.EFF_STATUS.SaveEdit PCPC:267 Statement:8 "
If %Component = Component.K_OFFNSV_CMP Then
Local Rowset &LEVEL0, &Level1, &Level2;
Local Row &L1Row, &L2Row;
Local number &I, &J;
&LEVEL0 = GetLevel0();
&Level1 = &LEVEL0(1).GetRowset(Scroll.K_OFFNSV_REC);
&I = CurrentRowNumber();
&L1Row = &Level1(&I);
If &L1Row.IsNew Then
&L1Row.K_OFFNSV_REC.LASTUPDDTTM.Value = %Date;
&L1Row.K_OFFNSV_REC.OPRID.Value = %UserId;
End-If;
&Level2 = &L1Row.GetRowset(Scroll.K_OFFNSV_REC_EX);
For &J = 1 To &Level2.ActiveRowCount
&L2Row = &Level2(&J);
&L2Row.K_OFFNSV_REC_EX.EFFDT.Value = %Date;
&L2Row.K_OFFNSV_REC_EX.EFF_STATUS.Value = &L1Row.K_OFFNSV_REC.EFF_STATUS.Value;
End-For;
End-If;
A suggestion, change/set values on SavePreChange. SaveEdit should be use for validations only.
With that being said:
Your currentrownumber returns the current row, so probably it is returning the row #2 on the level #2.
You need CurrentRowNumber(1) to get the #1 level.
Also, why are you setting the EFFDT yourself on the save? Look at other peoplesoft pages, you will see it is populated on the add by PS itself.

javascript for Array how many and min

I am trying to create a form in Acrobat. I want it to do some calculations. I got almost all of them done aside from 2.
I have an array of cells DF1 to DF78 so I need a calculation script that will give me the minimum value in that array not counting the blank ones.
In the same array of cells DF1 to DF78 I need a calculation script to find how many fields in that array have value and bring me up the number.
I already tried using the min option on the acrobat DC and selecting the fields. Ii want to look at DF1 to DF78. However, it always shows 0 because it's counting the empty fields as well.
I tried looking online, but all the scripts that they show are very confusing. I can't find where to put the array in there.
I wish I had a script to put it in here... sorry.
I have fields DF1 to DF78 so a total of 78 fields, and I need to find the minimum value in that array not including the fields that are blank.
Another script for the same fields DF1 to DF78 needs to count how many of the fields actually have data ex: DF1, DF2, DF3 had data on it and the rest are empty so it should display the number 3 because 3 of the 78 fields have data in them.
I hope somebody can help me with this.
This should work... Add it to the calculate action of a new hidden field you want the numbers to show up. Fix the names on the last two lines first.
valueArray = [];
for (var i = 1; i <= 78 ; i++) {
//Get the fieldvalue by assembling the name with the prefix and the number increment
var fieldVal = this.getField("DF"+i).value;
//Acrobat field values are never null. The value of a blank field is an empty string
if (fieldVal != "") {
//Add non-empty field values to an Array.
valueArray.push(fieldValue);
}
}
// Get the minimum value in the array.
var minValue = Math.min.apply(null, valueArray);
// Get the number of non-blank fields.
var nonBlankFields = valueArray.length;
this.getField("RESULT FOR YOUR 1st QUESTION FIELD NAME HERE").value = minValue;
this.getField("RESULT FOR YOUR 2nd QUESTION FIELD NAME HERE").value = nonBlankFields;

Transform report with distribution by months

I have the following ALV report generated from the RFKSLD00 program:
I need to generate a report based on the above report like this one (as part of my work):
Any ideas how to do this? I am not asking for a solution but some steps on how to achieve this.
Each line of the original report is one line of your report, you need just to adjust the sums for local currency, i.e. multiply all values by local currency rate. The yellow totals lines shouldn't confuse you, they are generated by grid, not by report.
The only thing that is missing in original report is debit and credit of balance carryforward, I suppose in the original you have already reconciliated value. To get separate values for it you need inspecting the code.
The initial step would be to declare final structure and table based on it:
TYPES: BEGIN OF ty_report,
rec_acc TYPE skont,
vendor TYPE lifnr,
...
jan_deb TYPE wrbtr,
jan_cred TYPE wrbtr,
febr_deb TYPE wrbtr,
febr_cred TYPE wrbtr,
...
acc_bal_deb TYPE wrbtr,
acc_bal_cred TYPE wrbtr,
END OF ty_report,
tt_report TYPE TABLE OF ty_report.
DATA: lt_report TYPE tt_report.
Then you only need looping original report internal table and fill your final structure, not missing currency conversion:
select single * from tcurr
into #DATA(tcurr)
where fcurr = 'EUR'
and tcurr = 'AUD'. "<- your local currency
DATA(lv_ukurs) = tcurr-ukurs.
LOOP AT orig_table INTO DATA(orig_line).
APPEND INITIAL LINE INTO lt_report ASSIGNING FIELD-SYMBOL(<fs_rep>).
MOVE-CORRESPONDING orig_line TO <fs_rep>.
CASE orig_line-monat. "<- your period
WHEN '01'.
<fs_rep>-jan_deb = orig_line-debit.
<fs_rep>-jan_cred = orig_line-credit.
WHEN '02'.
<fs_rep>-febr_deb = orig_line-debit.
<fs_rep>-febr_cred = orig_line-credit.
...
ENDCASE.
DO 30 TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_rep> TO FIELD-SYMBOL(<field>).
CHECK sy-subrc = 0.
DESCRIBE FIELD <field> TYPE DATA(TYP).
CHECK TYP = 'P'.
CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
EXPORTING
DATE = sy-datum
FOREIGN_CURRENCY = 'EUR'
LOCAL_CURRENCY = 'AUD'
FOREIGN_AMOUNT = <field>
TYPE_OF_RATE = 'M'
IMPORTING
EXCHANGE_RATE = lv_ukurs
LOCAL_AMOUNT = <field>.
ENDDO.
ENDLOOP.
I recommend to name all components of your final structure ty_report the same as in original as much as possible. Thus you can maximally utilize MOVE-CORRESPONDING and avoid manual coding.
This is just quick shot and I may be missing some details and errors.

How to create add and subtract buttons to track inventory

I've been searching for similar solutions out there but am coming up short so far. Here is what I want to accomplish:
I need to come up with a basic solution to sync inventory quantities at the end of each day. We take physical counts of inventory sold throughout the day but need something to log these changes and share between users. I would like to utilize two buttons (click one to subtract amount of items sold at the end of the day and click one button to add newly received inventory).
This is how my sheet is set up:
Col A: Product Tag
Col B: Product sku
Col C: Amount Sold Today
Col D: Total Inventory Quantity
Col E: Add New Inventory
Column D will be pre-populated with initial inventory counts. At the end of each day, I would like to go down my product list and fill in the amount of each item sold that day in Column C. Once Column C is fully populated, I would like to click the "subtract" button and have Column C subtracted from Column D.
On the other side, once we receive new stock of an item I would like to enter these counts into Column E. Once this column is fully populated, I would like to click the "Add" button and have Column E added to Column D. Ideally once the add or subtract function has been completed, columns C or E will be cleared and ready for the next days entry.
I already have designed my buttons, I just need help coming up with the scripts to accomplish this.
You can use Google Apps Script for this.
If you are unfamiliar, in your particular spreadsheet, go to Tools → Script Editor and then select the Blank Project option.
Then you can write functions like this to achieve what you want!
function subtractSold() {
var sheet = SpreadsheetApp.getActiveSheet();
var c1 = sheet.getRange("C2");
var c2 = sheet.getRange("D2");
while (!c1.isBlank() && !c2.isBlank()){
c2.setValue(c2.getValue() - c1.getValue());
c1.clear();
c1 = c1.offset(1, 0);
c2 = c2.offset(1, 0);
}
}
Basically what the function does is:
Get a reference to the active spreadsheet
Get references to the cells C2 and D2, for the first row of data.
Use a while loop to repeated go through the rows. Terminate when either cell is empty.
In the loop, we get the appropriate values, subtract and set the value back into the cell. Then we clear the cell in column C. We then move both cell references down by one row (the offset method returns a reference to the original cell, but offset by row, column).
Then assign the script to the button image by entering the name of the function (subtractSold in this case) in the "Assign script" option for the button.
I have made an example sheet here (go to File → Make a Copy to try the scripts and see the code): https://docs.google.com/spreadsheets/d/1qIJdTvG0d7ttWAUEov23HY5aLhq5wgv9Tdzk531yhfU/edit?usp=sharing
A bit faster
If you try the sheet above you can see it processes one row at a time, which might get pretty slow when you have a lot of rows. It is probably faster to process the entire column in bulk, but it may be a bit more complicated to understand:
function subtractSoldBulk() {
var sheet = SpreadsheetApp.getActiveSheet();
var maxRows = sheet.getMaxRows();
var soldRange = sheet.getRange(2, 3, maxRows); // row, column, number of rows
var totalRange = sheet.getRange(2, 4, maxRows);
var soldValues = soldRange.getValues();
var totalValues = totalRange.getValues();
for (var row in soldValues) {
var soldCellData = soldValues[row][0];
var totalCellData = totalValues[row][0];
if (soldCellData != "" && totalCellData != "") {
totalValues[row][0] = totalCellData - soldCellData;
soldValues[row][0] = "";
}
}
soldRange.setValues(soldValues);
totalRange.setValues(totalValues);
}
The difference here is that instead of getting one cell, we get one range of cells. The getValues() method then gives us a 2D array of the data in that range. We do the calculations on the two arrays, update the data in the arrays, and then set the values of the ranges based on the array data.
You can find documentation for the methods used above from Google's documentation: https://developers.google.com/apps-script/reference/spreadsheet/sheet

Need help building a menuopt file for Jenzabar CX

I'm not sure if anyone out here uses Jenzabar & ACE reporting, but the question is specific to that as far as I know.
I'm building an ACE report and the menuopt file for it has to be modified to lookup values for a parameter based on several specific conditions.
The portion of the menuopt file I have now is:
LU7 = crs_rec.title1, optional;
PA7: optional,
comments = "Enter a course number - leave blank if for all"
default = "",
lookup LU7 joining *crs_rec.crs_no,
upshift,
length = 10;
I'm looking to modify the lookup so that it only lists courses that can be found by this SQL statement:
SELECT DISTINCT crs_no
FROM crs_rec
WHERE dept IN ( SELECT dept
FROM dept_table
WHERE div IN ('CCE','HLTH'));
If anyone is familiar with using Jenzabar CX & ACE reporting, any help would be appreciated.
Thanks
I got this answer from someone on a Jenzabar listserv....
Sometimes you can get the same effect by limiting it based on other params.
For example:
LU6 = cat_table.txt;
PA6: optional,
comments = "COMMENT_CAT_TBCODE",
lookup LU6 joining *cat_table.cat,
upshift,
length = 4;
LU7 = crs_rec.title1, optional;
LU7B = crs_rec.dept, optional,
qualifier = "#XXXX,YYYY,ZZZZ,DDDD,EEEE";
LU7C = crs_rec.cat, optional,
qualifier = "field:PA6";
PA7: optional,
comments = "COMMENT_CRS_NO - COMMENT_BLANK_ALL"
default = "",
lookup LU7,LU7B,LU7C joining *crs_rec.crs_no,
upshift,
length = 10;
This would show only the courses in departments XXXX,YYYY,ZZZZ,DDDD, and EEEE in the catalog entered as param PA6.
(the catalog param is basically the only way of doing the "distinct" for the crs_no in the menuopt).
You cannot do the dept in div thing unless you make dept another parameter in which case you could limit the dept selection with a div qualifier and change the LU7B to reference field:xxxx (the param for the dept).

Resources