How to increase the process performance by reducing following codes? - openedge

I have written a program using progress 4GL. The syntax is correct but don't know how to reduce the codes..We are the company working for seats and using progress 4gl..we have one table called shift maintenance which has shift time for every hours.Let explain with an example.
DEFINE VARIABLE FistshiftStartHour AS INTEGER NO-UNDO.
DEFINE VARIABLE FistShiftEnddHour AS INTEGER NO-UNDO.
DEFINE VARIABLE SecshiftStartHour AS INTEGER NO-UNDO.
DEFINE VARIABLE SecShiftEnddHour AS INTEGER NO-UNDO.
FIND FIRST shift WHERE shift.shiftsequence = 1 NO-LOCK NO-ERROR.
ASSIGN
FistshiftStartHour = shift.starthour
FistShiftEnddHour = shift.endhour.
FIND FIRST shift WHERE shift.shiftsequence = 2 NO-LOCK NO-ERROR.
ASSIGN
SecshiftStartHour = shift.starthour
SecShiftEnddHour = shift.endhour.
Like this i need to write a query for every shift hours and assign to two variables for 21 shift sequence.Is there any chance for reducing so much queries?(Note-I must to assign start and end time to individual variables).

You can handle the shift time with array variable and assign it when doing loop in your table / temp-table:
DEFINE VARIABLE sSeq AS INTEGER EXTENT 21 NO-UNDO. /* start hour */
DEFINE VARIABLE eSeq AS INTEGER EXTENT 21 NO-UNDO. /* end hour */
FOR EACH shift WHERE shift.shiftsequence LE 21 NO-LOCK BY shift.shiftsequence:
sSeq[shift.shiftsequence] = shift.starthour.
eSeq[shift.shiftsequence] = shift.endhour.
DISP sSeq[shift.shiftsequence] eSeq[shift.shiftsequence].
END.

Related

Algorithm to count instances of a value from a file

I am reading through a file of financial data with beneficiaries. I need to count the number of beneficiaries and then calculate their allocated percentage. If there is 1 beneficiary, the allocation is 100%, if there are 2, if there are 3, 33.33%, etc. The file is sorted by investment then beneficiary, so if there is more than one beneficiary per investment they will be in order in the file. Here's an example:
input file data
the output that I want
Here is my code, but it's wrong because this way I am assigning 100% to the first beneficiary, 50% to the second beneficiary, 33.333% to the third, etc. How can I change it to do the count, then create the beneficiaries with the right count? (There is an outer loop which is a table of investments.)
iBeneficiaryCount = 0.
dTempPercentage = 100.
FOR EACH ttJointData WHERE ttJointData.inv-num EQ ttInvestment.inv-num:
IF ttJointData.Joint_Type EQ "Joint" THEN DO:
cTemp = "JT".
RUN CreateOwner (....).
END.
ELSE IF ttJointData.Joint_Type EQ "Beneficiary" THEN DO:
iBeneficiaryCount = iBeneficiaryCount + 1.
dTempPercentage = 100 / iBeneficiaryCount.
RUN AddBeneficiary(ttJointData.investment-num,ttInvestment.benficiary-id,dTempPercentage).
END.
END.
What are the best ways to capture that beneficiary percentage? I am thinking that I need to read through the data and put that value into the ttJointData table. Or is there a way to do it on the loop? Regardless, I need a neat algorithm to count up the instances from an input file and create and assign a percentage value.
You can use a query to calculate the number of beneficiaries before you loop through them.
Something like
DEFINE VARIABLE dTempPercentage AS DECIMAL NO-UNDO.
DEFINE VARIABLE iBeneficiaryCount AS INTEGER NO-UNDO.
DEFINE QUERY qryJD FOR ttJointData.
dTempPercentage = 100.
FOR EACH ttInvestment:
// calculate how many beneficiaries; must use PRESELECT here
OPEN QUERY qryJD PRESELECT EACH ttJointData WHERE ttJointData.inv-num EQ ttInvestment.inv-num.
iBeneficiaryCount = QUERY qryJD:NUM-RESULTS.
dTempPercentage = 100 / iBeneficiaryCount.
GET FIRST qryJD .
DO WHILE AVAILABLE ttJointData :
IF ttJointData.Joint_Type EQ "Joint" THEN DO:
cTemp = "JT".
RUN CreateOwner (....).
END.
ELSE IF ttJointData.Joint_Type EQ "Beneficiary" THEN DO:
RUN AddBeneficiary(ttJointData.investment-num,ttInvestment.benficiary-id,dTempPercentage).
END.
GET NEXT qryJD .
END.
CLOSE QUERY qryJD.
END.

how to create convert octal to biner?

I have a problem when I input numbers 2,5,7 the results are ok and when I input numbers 1,3,4,6 the results don't match.
define variable oct as character.
define variable l-oct as integer.
define variable oktal as integer.
define variable l-oktal as integer.
define variable count as integer.
define variable i as integer.
define variable bin as character.
define variable bin2 as character.
end.
do i = length(bin) to 1 by -1:
bin2 = bin2 + substring(bin, i, 1).
end.
display bin2 with frame a down.
Your if else if train is missing an else if. An if else if train is usually better served by a case statement.
Additionally, you are first constructing a back to front in groups of three digits binary string and subsequently reversing this at the end per digit.
So where octal 1 becomes binary 001 you are flipping this to 100. Instead of flipping afterwards, concatenate your string correctly to start with, so replace all occurrences of:
bin = bin + 'xxx'
with:
bin = 'xxx' + bin

SQLite3 - Calculated SELECT with padding and concatenation

I have the following SQLite table (a stub of the real table which has a few other columns)
CREATE TABLE IF NOT EXISTS fingers(id INTEGER,intLL INTEGER,fracLat INTEGER,fracLng INTEGER,PRIMARY KEY(id)) WITHOUT ROWID;
A typical entry in this table would be along the lines of
INSERT INTO fingers(id,intLL,fracLat,fracLng) VALUES(1,12899,42513,4025);
From time-to-time I need to query this table to pull out rows for matching intLL values in such a way that a calculated value meets a variable condition. For example
SELECT * FROM fingers WHERE intLL = 12899 AND ('8508' = (CAST((ROUND(CAST(fracLat AS REAL)/500))
AS INTEGER) || CAST((ROUND(CAST(fraCLng AS REAL)/500)) AS INTEGER)));
Explanation
Transform the fractLat and fracLng columns by dividing them by 10,250 or 500. The CAST AS REAL is required to prevent the default integer division that would be performed by SQLite
Round the decimal result to the closest integer. After rounding you will by default get a value with a trailing .0. The CAST AS INTEGER ensures that this is removed
Concatenate the two parts. The concatenation is going wrong. In the present case the concatenated result would be 858 which is not what I want
Compare against an incoming value: 8508 in this case.
My questions
How can I pad the two parts with 0s when required prior to concatenation so as to ensure that they have the same number of digits
Is there a simpler way of achieving this?
One way to pad 0s is to concatenate 00 at the start of the number and with SUBSTR() return the last 2 chars.
Also, you can divide by 500.0 to avoid integer division:
SELECT * FROM fingers
WHERE intLL = 12899
AND '8508' = SUBSTR('00' || CAST(fracLat / 500.0 AS INTEGER), -2) ||
SUBSTR('00' || CAST(fraCLng / 500.0 AS INTEGER), -2)
Another way to do it is with the function printf() which formats a number:
SELECT * FROM fingers
WHERE intLL = 12899
AND '8508' = printf('%02d', fracLat / 500.0) ||
printf('%02d', fraCLng / 500.0)
See the demo.

How to calculate total sum in one field in progress 4GL?

I have written a query for calculating total sum in one field but i could get total records. Let me share what i written.
DEFINE VARIABLE I AS INTEGER NO-UNDO.
FIND FIRST shth_pus_head WHERE shth_pus_head.push_id = "P0000078" NO-LOCK
NO-ERROR.
FOR EACH shtd_pus_det OF shth_pus_head NO-LOCK:
i = i + 1.
END.
DISPLAY i.
What i need is when i calculate total sum in qty column i want sum = 1560.
(Note- qty column table field is shtd_pus_det.qty)
Check the attached image
Your code does not calculate a total sum. It counts the number of records. To sum up the shtd_pus_det.qty fields in those records you could code something like:
define variable tot_qty as integer no-undo.
for each shtd_pus_det no-lock where shtd_pus_det.push_id = "P0000078":
tot_qty = tot_qty + shtd_pus_det.qty.
end.
display tot_qty.

Randomize numbers in VB.NET without using a range i.e. Min and Max

I was wondering if anyone can point me in the right direction please? Say I am pulling the following table, I would then like to select an ID randomly. I understand how to select a random number using a Randomize() call followed by the relevant syntax but I want to pre-define the range.
i.e. Table Data
ID | Name
4345 Mike
3456 Lee
4567 John
There will be many more names but for this example you could use 3 or 4 etc..
Please help I'm starting to itch :o|
Just to make sure I understand what you want:
Given a table, you want to randomly select one of the ID values from that table.
If so, this should do it:
Dim rand As New Random()
Dim record As Integer = rand.[Next](0, myDataTable.Rows.Count)
Dim randomID As Integer = CInt(myDataTable.Rows(record)("ID"))
We have all the information we need to randomly select a row, and by extension randomly select one of the ID values in the table.
In old Vb you would do
Dim i as integer
i = (Rnd * (maxval-minval)) + minval
Since rnd returns a random number between 0 and 1 you would scale the number to the right range.

Resources