I'm getting the following errors in one, but not both, of my if statements.
165 IGYPS2000-S Expected a data-name, but found "TO". The "ADD" statement was discarded.
169 IGYPS2096-S An incomplete condition was found in a conditional expression. The operand(s) was(were) discarded.
169 IGYPS2079-S Expected a verb or "NEXT SENTENCE", but found ""F"". The statement was discarded.
IF MARITAL-STATUS-IN = "S"
ADD 1 TO SINGLE-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
ADD SALARY-IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF.
IF MARITAL-STATUS-IN = "M"
ADD 1 TO MARRIED-COUNT
ADD 1 TO OVERALL-COUNT line 165
ADD SALARY-IN TO MARRIED-TOTAL
ADD SALARY IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
IF GENDER-IN "F"
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF.
If you need to see anymore of my code just let me know. This is my first time writing nested if's.
piet.t and Bruce Martin have correctly spotted the errors which are giving you those compiler diagnostics. You did not help by listing the wrong line as number 165.
An easy thing to do to avoid this problem is to get the compiler to embed the diagnostics, as well as listing them at the end of the compile. Indeed it is unusual for this not to be the default at your installation.
To get around it not being the default you can do this:
CBL FLAG(I,I)
Start that in column 12, and make it the first line in the program source whilst you are testing.
The first I says "list diagnostic messages at the end of the compile listing, from severity I upwards". The second I says "embed diagnostic messages in the compile listing of the source, from severity I upwards".
All compiler options and information about ways to use them is included in the Enterprise COBOL Programming Guide, available for free on the internet from IBM.
The relevant part of the listing would look something like this (I'm just pasting in without reference to an actual listing):
IF MARITAL-STATUS-IN = "S"
ADD 1 TO SINGLE-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
ADD SALARY-IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF.
IF MARITAL-STATUS-IN = "M"
ADD 1 TO MARRIED-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO MARRIED-TOTAL
ADD SALARY IN TO OVERALL-TOTAL
165 IGYPS2000-S Expected a data-name, but found "TO". The "ADD" statement was discarded.
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
IF GENDER-IN "F"
169 IGYPS2096-S An incomplete condition was found in a conditional expression. The operand(s) was(were) discarded.
169 IGYPS2079-S Expected a verb or "NEXT SENTENCE", but found ""F"". The statement was discarded.
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF.
As has been pointed out, you have some problems with the way you have constructed your IFs as well:
IF MARITAL-STATUS-IN = "S"
ADD 1 TO SINGLE-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
ADD SALARY-IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF.
IF MARITAL-STATUS-IN = "M"
ADD 1 TO MARRIED-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO MARRIED-TOTAL
ADD SALARY IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
IF GENDER-IN "F"
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF.
You are using two different methods to terminate your IFs. The END-IF scope-delimiter and the full-stop/period. The use of the second means that your indentation does not match the "logical" indentation.
IF MARITAL-STATUS-IN = "S"
ADD 1 TO SINGLE-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
ADD SALARY-IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF.
IF MARITAL-STATUS-IN = "M"
ADD 1 TO MARRIED-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO MARRIED-TOTAL
ADD SALARY IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
IF GENDER-IN "F"
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF.
Note, I have not corrected your nesting for the GENDER-IN test.
It is much, much better to just use the scope-delimiter to end any conditions. Use an absolute minimum of full-stops/periods.
PROCEDURE DIVISION.
any-paragraph-name-or-SECTION-name.
some code
.
That is: end of PROCEDURE DIVISION header (after the items on USING if you have one of those); before a paragraph/SECTION; end of a paragraph/SECTION label; end of a paragraph/SECTION; end of the program.
There is some overlap there, as a program does not require that there are paragraphs/SECTIONS within it.
Keep the content of your IFs simple. Avoid repeated code. I've put an example of your code, re-arranged, following. There are two styles, the nested-IF for the Single (since the purpose of this work is probably the nested-IF) and a different way for the Married.
IF MARITAL-STATUS-IN = "S"
PERFORM COUNT-ANY-PERSON
PERFORM COUNT-SINGLE-PEOPLE
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
END-IF
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF
END-IF
IF MARITAL-STATUS-IN = "M"
PERFORM COUNT-ANY-PERSON
PERFORM COUNT-MARRIED-PEOPLE
END-IF
.
COUNT-ANY-PERSON.
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO OVERALL-TOTAL
.
COUNT-SINGLE-PEOPLE.
ADD 1 TO SINGLE-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
.
COUNT-MARRIED-PEOPLE.
ADD 1 TO MARRIED-COUNT
ADD SALARY-IN TO MARRIED-TOTAL
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
END-IF
IF GENDER-IN = "F"
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF
.
Married/single may be mutually exclusive. If so, use ELSE rather than the second test. Male/female may be mutually exclusive. If so, use ELSE rather than the second test. If they are not mutually exclusive, find out what else you need to count, rather then just have data slip through the program.
You should look to use 88-level condition names, rather that test for literals. Makes your program easier to understand, and easier to maintain.
Since this line
IF GENDER-IN "F"
seems to be line 169 (judging from the error message), line 165 should be this one:
ADD SALARY IN TO OVERALL-TOTAL
and you seem to be missing a - between SALARY and IN.
In line 169 you have
IF GENDER-IN "F"
and are missing a =.
So much for your typos, but your logic structure is also in error because of missing END-IFs.
Adjusting the indentation to what the compiler sees it's:
IF MARITAL-STATUS-IN = "S"
ADD 1 TO SINGLE-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO SINGLE-TOTAL
ADD SALARY-IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO SINGLE-MALE-COUNT
ADD SALARY-IN TO SINGLE-MALE-TOTAL
IF GENDER-IN = "F"
ADD 1 TO SINGLE-FEMALE-COUNT
ADD SALARY-IN TO SINGLE-FEMALE-TOTAL
END-IF.
IF MARITAL-STATUS-IN = "M"
ADD 1 TO MARRIED-COUNT
ADD 1 TO OVERALL-COUNT
ADD SALARY-IN TO MARRIED-TOTAL
ADD SALARY IN TO OVERALL-TOTAL
IF GENDER-IN = "M"
ADD 1 TO MARRIED-MALE-COUNT
ADD SALARY-IN TO MARRIED-MALE-TOTAL
IF GENDER-IN "F"
ADD 1 TO MARRIED-FEMALE-COUNT
ADD SALARY-IN TO MARRIED-FEMALE-TOTAL
END-IF.
Related
I have an employees table with mutations to their contracts
EmpID Start End Function Hours SalesPercentage
1 01-01-2020 31-12-2020 FO Desk 40 1
1 01-01-2020 31-01-2021 FO Desk 32 1
1 01-02-2021 FO Desk 32 0.50
2 01-01-2021 31-01-2021 BO 32 0
2 01-02-2021 BO/FO 32 .25
For dynamic calculation of the amount of emplyees and their sales percentages I need to turn this into a tabel with an entry per month:
Year Month EmpID Hours SalesPercentage
2020 1 1 40 1
2020 2 1 40 1
..
2020 12 1 40 1
2021 1 1 32 1
2021 1 2 32 0
2021 2 1 32 0.50
2021 2 2 32 0.25
I have a simple Year Month table that I would like to append the mutation data to, but joining on multiple columns is not possible as far as I can tell. Is there a way around this?
Try this below
It generates a list of all year/month combinations for each row, then expands it and removes extra columns
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{ {"Start", type date}, {"End", type date}}),
#"Added Custom" = Table.AddColumn(
#"Changed Type",
"newcol",
each
let
begin = Date.StartOfMonth([Start]),
End2 = if [End] = null then [Start] else [End]
in
List.Accumulate(
{0..(Date.Year(End2)-Date.Year([Start]))*12+(Date.Month(End2)-Date.Month([Start]))},
{},
(s,c) => s&{Date.AddMonths(begin,c)}
)
),
#"Expanded newcol" = Table.ExpandListColumn(#"Added Custom", "newcol"),
#"Added Custom2" = Table.AddColumn(#"Expanded newcol", "Year", each Date.Year([newcol])),
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Month", each Date.Month([newcol])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom3",{"Start", "End", "Function", "newcol"})
in #"Removed Columns"
After I apply a filter in A1 I get a result like:
A B C D
Uno 1 3 1
Uno 1 2 2
Tres 2 2 3
I want to replace "Uno" for "Dos" in the same cells.
A B C D
Dos 1 3 1
Dos 1 2 2
Tres 2 2 3
I have seen SUBSTITUTE() and REPLACE() functions, but, they put the replacement in another cells.
I have tried:
A1: SUBSTITUTE(A1:A)
try:
=ARRAYFORMULA(REGEXREPLACE(IFERROR(FILTER(K:N, L:L="ok"), " "), "Uno", "Dos"))
REGEXREPLACE(range, "replace this", "to this")
ARRAYFORMULA - for continuity
=ARRAYFORMULA(REGEXREPLACE(REGEXREPLACE(IFERROR(FILTER(K:N, L:L="ok"), " "),
"Uno", "Dos"), "Tres", "Cuatro")
I would like to do something like this (Formula to find the header index of the first non blank cell of a range in Excel?) except that I want to capture all the nonblank cells.
An application of what I am expecting would produce column "prod"
2 3 5 7 11 13 | prod |
2 1 2^1
3 1 3^1
4 2 2^2
5 1 5^1
6 1 1 2^1 3^1
7 1 7^1
8 3 2^3
9 2 3^2
10 1 1 2^1 5^1
11 1 11^1
12 2 1 2^2 3^1
13 1 13^1
14 1 1 2^1 7^1
15 1 1 3^1 5^1
16 4 2^4
I wouldn't mind a result with multiple separators ie. 6= 2^1*3^1**** , as they could be removed.
This user defined function will stitch together the header value with the range value.
In a standard public module code sheet:
Option Explicit
Function prodJoin(rng As Range, hdr As Range, _
Optional op As String = "^", _
Optional delim As String = " ")
Dim tmp As String, i As Long
For i = 1 To rng.Count
If Not IsEmpty(rng.Cells(i)) Then
tmp = tmp & delim & hdr.Cells(i).Text & op & rng.Cells(i).Text
End If
Next i
prodJoin = Mid(tmp, Len(delim) + 1)
End Function
On the worksheet as,
If you absolutely must use worksheet functions then stitch 6 conditional concatenations together.
=TRIM(IF(B2, B$1&"^"&B2&" ", TEXT(,))&
IF(C2, C$1&"^"&C2&" ", TEXT(,))&
IF(D2, D$1&"^"&D2&" ", TEXT(,))&
IF(E2, E$1&"^"&E2&" ", TEXT(,))&
IF(F2, F$1&"^"&F2&" ", TEXT(,))&
IF(G2, G$1&"^"&G2&" ", TEXT(,)))
This is my basic IF statement. I need to preface this statement so that if the referenced cell is blank it returns a blank field instead of a 0.
=IF( (G19) < 9 , 0 , 100 )
Try below formula -
=IF(ISBLANK(G19),"", IF(G19 < 9 , 0 , 100 ))
I am really sorry for this. I am new oracle and I have created following block which is resulting output and then error.
First cursor is generating output and then error and so second cursor is not generating output.
Please help for error free output .
thanks and regards
Error:
END;
Error report:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 36
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause:
*Action:
Block:
DECLARE
c_dbuser SYS_REFCURSOR;
c_dbuser1 SYS_REFCURSOR;
temp_dbuser FIT_SCHEMA.fxf_inspt_insp_main%ROWTYPE;
year_date varchar2(20):='2014';
typeOfGraph varchar2(50):='InspectionByInspection';
division varchar2(20):='Division';
subDiv varchar2(20):='ALL';
emp varchar2(20):='';
TYPE t_name IS RECORD( --Error is at this line :(
inspectiondate varchar2(20),
totalcount number(38),
inspectionDesc varchar2(20)
);
r_name t_name; -- name record
TYPE t_monthwise is record (
month_number varchar2(20),
inspcount number(38),
inspectionDesc varchar2(20)
);
t_month t_monthwise;
BEGIN
fit_schema.My_manager(typeOfGraph,year_date,division,subDiv,emp,c_dbuser,c_dbuser1);
LOOP
FETCH c_dbuser INTO r_name ;
EXIT WHEN c_dbuser%NOTFOUND;
dbms_output.put_line( r_name.inspectiondate ||' '||r_name.totalcount||' '||r_name.inspectionDesc);
END LOOP;
LOOP
FETCH c_dbuser1 INTO t_month ;
EXIT WHEN c_dbuser1%NOTFOUND;
dbms_output.put_line( t_month.month_number ||' '||t_month.inspcount||' '||t_month.inspectionDesc);
END LOOP;
CLOSE c_dbuser;
CLOSE c_dbuser1;
END;
Output :
13-DEC-2014 1 3#CPLD Only
13-DEC-2014 4 0#Class Only
14-DEC-2014 1 0#Class Only
15-DEC-2014 2 0#Class Only
16-DEC-2014 1 0#Class Only
17-DEC-2014 1 7#Negative Class
17-DEC-2014 9 0#Class Only
19-DEC-2014 15 0#Class Only
22-DEC-2014 1 11#65% Rule
23-DEC-2014 1 8#XLGH & Class
30-DEC-2014 1 0#Class Only
31-DEC-2014 1 10#Mixed Articles
31-DEC-2014 3 0#Class Only
02-JAN-2015 2 0#Class Only
05-JAN-2015 2 0#Class Only
07-JAN-2015 2 9#XLGH Only
07-JAN-2015 3 1#Class & Reweigh
07-JAN-2015 1 10#Mixed Articles
07-JAN-2015 4 0#Class Only
07-JAN-2015 2 11#65% Rule
08-JAN-2015 5 0#Class Only
08-JAN-2015 1 9#XLGH Only
09-JAN-2015 1 3#CPLD Only
09-JAN-2015 1 11#65% Rule
09-JAN-2015 4 0#Class Only
09-JAN-2015 1 1#Class & Reweigh
12-JAN-2015 1 5#CCD Only
12-JAN-2015 1 3#CPLD Only
19-JAN-2015 1 11#65% Rule
20-JAN-2015 1 0#Class Only
21-JAN-2015 4 0#Class Only
23-JAN-2015 1 10#Mixed Articles
26-JAN-2015 1 7#Negative Class
26-JAN-2015 2 0#Class Only
27-JAN-2015 1 3#CPLD Only
27-JAN-2015 3 0#Class Only
27-JAN-2015 1 6#CCD & Class
28-JAN-2015 6 0#Class Only
29-JAN-2015 3 0#Class Only
29-JAN-2015 1 5#CCD Only
30-JAN-2015 1 3#CPLD Only
30-JAN-2015 1 1#Class & Reweigh
01-FEB-2015 3 0#Class Only
02-FEB-2015 1 4#CPLD & Class
02-FEB-2015 1 8#XLGH & Class
04-FEB-2015 1 0#Class Only
Queries from Procedure :-
SELECT TO_CHAR(MAINTABLE.INSP_CREATED_TMSTP,'dd-MON-yyyy') inspectiondate, --varchar2
COUNT(MAINTABLE.insp_id) AS totalinspection, --count is number
MAINTABLE.insp_type_id ||'#'||ISNPTYPETABLE.INSP_TYPE_DESC AS INSPECTIONDESCRIPTION-- varchar2
FROM FIT_SCHEMA.fxf_inspt_insp_main MAINTABLE
JOIN FIT_SCHEMA.fxf_inspt_emp_detail EMPTABLE
ON(MAINTABLE.inspector_emp_nbr=EMPTABLE.inspector_emp_nbr)
JOIN FIT_SCHEMA.fxf_inspt_drop_down DROPDOWNTABLE
ON (emptable.division_id = DROPDOWNTABLE.drop_down_id)
JOIN FIT_SCHEMA.fxf_inspt_insp_type ISNPTYPETABLE
ON(MAINTABLE.insp_type_id =isnptypetable.insp_type_id)
WHERE dropdowntable.is_active_flg = 1
AND MAINTABLE.STATUS_ID = 8
AND MAINTABLE.insp_type_id IN (0,1,3,4,5,6,7,8,9,10,11,12)
AND TRUNC(MAINTABLE.insp_created_tmstp) between TRUNC(EMPTABLE.EFFECTIVE_FROM_TMSTP)
And Nvl(Trunc(Emptable.Effective_To_Tmstp),Sysdate) AND UPPER(dropdowntable.drop_down_grp) =UPPER('division') AND TRUNC(MAINTABLE.insp_created_tmstp) between '01-JUN-14' AND '31-MAY-15' GROUP BY TO_CHAR(MAINTABLE.INSP_CREATED_TMSTP,'dd-MON-yyyy')
, TRUNC(MAINTABLE.INSP_CREATED_TMSTP), MAINTABLE.insp_type_id ||'#'|| ISNPTYPETABLE.INSP_TYPE_DESC ORDER BY TRUNC(MAINTABLE.INSP_CREATED_TMSTP)
SELECT TO_CHAR(MAINTABLE.insp_created_tmstp,'MM') AS MONTHNUMBER,
COUNT(MAINTABLE.INSP_ID) AS INSPCOUNT ,
MAINTABLE.insp_type_id ||'#'
||ISNPTYPETABLE.INSP_TYPE_DESC AS INSPECTIONDESCRIPTION
FROM FIT_SCHEMA.fxf_inspt_insp_main MAINTABLE
JOIN FIT_SCHEMA.fxf_inspt_emp_detail EMPTABLE
ON(MAINTABLE.inspector_emp_nbr=EMPTABLE.inspector_emp_nbr)
JOIN FIT_SCHEMA.fxf_inspt_drop_down DROPDOWNTABLE
ON (emptable.division_id = DROPDOWNTABLE.drop_down_id)
JOIN FIT_SCHEMA.fxf_inspt_insp_type ISNPTYPETABLE
ON(MAINTABLE.insp_type_id =isnptypetable.insp_type_id)
WHERE dropdowntable.is_active_flg = 1
AND MAINTABLE.insp_type_id IN (0,1,3,4,5,6,7,8,9,10,11,12)
AND dropdowntable.is_active_flg = 1
AND MAINTABLE.STATUS_ID = 8
AND TRUNC(MAINTABLE.insp_created_tmstp) between TRUNC(EMPTABLE.EFFECTIVE_FROM_TMSTP)
And Nvl(Trunc(Emptable.Effective_To_Tmstp),Sysdate) AND UPPER(dropdowntable.drop_down_grp) =UPPER('division')
AND TRUNC(MAINTABLE.insp_created_tmstp) between '01-JUN-14'
AND '31-MAY-15' GROUP BY TO_CHAR(MAINTABLE.insp_created_tmstp,'MM'), MAINTABLE.insp_type_id ||'#'||ISNPTYPETABLE.INSP_TYPE_DESC ORDER BY TO_CHAR(MAINTABLE.insp_created_tmstp,'MM')
Line 36 is:
FETCH c_dbuser INTO r_name ;
So one of the values being returned in your c_dbuser ref cursor is too big. Your date format mask will only generate string 11 characters long so inspectiondate is (more than) adequate, and the count seems unlikely to exceed number(38) so totalcount also seems fine. Which suggests that inspectionDesc is too small for some of the values in the data.
You're generating that from:
MAINTABLE.insp_type_id ||'#'||ISNPTYPETABLE.INSP_TYPE_DESC
If the total length of that concatenated string exceeds 20 characters then you'll get an error on fetch.
If INSP_TYPE_DESC is defined as varchar2(20) then you aren't allowing any room for the rest; you need one extra character for the fixed #, and at least two for the insp_type_id - more if the highest ID can be three digits or more. If it isn't constrained then you'll need to decide the highest number you expect to ever see and allow for that. So if you expect up to three digits for an ID, define inspectionDesc as varchar2(24), etc.