Critical

CASE expressions should end with ELSE clauses

Description

    The "CASE expressions should end with ELSE clauses" rule states that all CASE expressions used in PowerBuilder code should be concluded with an ELSE clause, regardless of whether the ELSE clause contains any code or not. This is done to ensure that all possible cases are accounted for in the CASE expression, and that the code is robust and reliable. Without an ELSE clause, a CASE expression may not be able to handle unexpected inputs or values, which can cause the code to fail or produce unexpected results.

Key Benefits

  • Easier to read: CASE expressions are easier to read than nested IF statements, as they are more concise and structured.
  • More efficient: CASE expressions can be more efficient to execute than nested IF statements.
  • ELSE clause: CASE expressions should end with ELSE clauses to ensure that an output is returned, regardless of the condition evaluated.

 

Non-compliant Code Example

private function string TestFunctionaCall (int cnt)

string sle_message

CHOOSE CASE Real(cnt)

CASE is < 10
		sle_message = " is < 10"
CASE 11 to 20
        sle_message = "is 11 to 20"
END CHOOSE  //Non compliant code (Case statements ends without ELSE clauses)

return ""

end function
event vg_extendedaction;

integer 	i_colnum, i
String s_modify, s_objecttype
datawindow ldw_target
string ls_column
CHOOSE CASE as_action
	CASE "disable column" // Extend 'disable column' action
		// Verify if the type of the target object is correct for this action
		IF TypeOf (apo_target_object) = datawindow! THEN
			// This action can disable a group of columns. Each column is separated by comma.
			ldw_target = apo_target_object
			DO WHILE as_param <> ""
				ls_column = vg_f_get_token(as_param,",")
				// Make the column's background opaque
				IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN 
					Return -1
				END IF
			LOOP

			Return 1

		ELSE
			Return -1
		END IF
	CASE "enable column" // Extend 'enable column' action
		// Verify if the type of the target object is correct for this action
		IF TypeOf (apo_target_object) = datawindow! THEN
			// This action can disable a group of columns. Each column is separated by comma.
			ldw_target = apo_target_object
			DO WHILE as_param <> ""
				ls_column = vg_f_get_token(as_param,",")
				// Make the column's background transparent
				IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN 
					Return -1
				END IF
			LOOP
			Return 1
		ELSE
			Return -1
		END IF
	CASE "extended readonly" // Add a specific action
		if TypeOf (apo_target_object) <> datawindow! THEN Return -1
		ldw_target = apo_target_object
		IF ldw_target.Modify ("DataWindow.ReadOnly='Yes'") <> "" THEN 
			Return -1
		END IF

		i_colnum = Integer(ldw_target.Describe("datawindow.column.count"))
		IF i_colnum < 1 THEN Return -1 
		FOR i = 1 TO i_colnum
			IF Long(ldw_target.describe("#" + String(i) + ".x")) <> 0  THEN
				s_modify = s_modify + " #"+String(i)+".background.mode = '1'"
			END IF
		NEXT
		
		IF ldw_target.Modify(s_modify) <> "" THEN 
			Return -1
		END IF
		Return 1
END CHOOSE //Non compliant code(Case statements ends without ELSE clauses)

Return 2

end event

Compliant Code Example

private function string TestFunctionaCall (int cnt)

string sle_message

CHOOSE CASE Real(cnt)

CASE is < 10
		sle_message = "" is < 10""
CASE 11 to 20
        sle_message = ""is 11 to 20""
CASE Else //Compliant code
    sle_message = ""is > 20""
END CHOOSE  

return ""

end function
event vg_extendedaction;

integer 	i_colnum, i
String s_modify, s_objecttype
datawindow ldw_target
string ls_column
CHOOSE CASE as_action
	CASE "disable column" // Extend 'disable column' action
		// Verify if the type of the target object is correct for this action
		IF TypeOf (apo_target_object) = datawindow! THEN
			// This action can disable a group of columns. Each column is separated by comma.
			ldw_target = apo_target_object
			DO WHILE as_param <> ""
				ls_column = vg_f_get_token(as_param,",")
				// Make the column's background opaque
				IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN 
					Return -1
				END IF
			LOOP

			Return 1

		ELSE
			Return -1
		END IF
	CASE "enable column" // Extend 'enable column' action
		// Verify if the type of the target object is correct for this action
		IF TypeOf (apo_target_object) = datawindow! THEN
			// This action can disable a group of columns. Each column is separated by comma.
			ldw_target = apo_target_object
			DO WHILE as_param <> ""
				ls_column = vg_f_get_token(as_param,",")
				// Make the column's background transparent
				IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN 
					Return -1
				END IF
			LOOP
			Return 1
		ELSE
			Return -1
		END IF
	CASE "extended readonly" // Add a specific action
		if TypeOf (apo_target_object) <> datawindow! THEN Return -1
		ldw_target = apo_target_object
		IF ldw_target.Modify ("DataWindow.ReadOnly='Yes'") <> "" THEN 
			Return -1
		END IF

		i_colnum = Integer(ldw_target.Describe("datawindow.column.count"))
		IF i_colnum < 1 THEN Return -1 
		FOR i = 1 TO i_colnum
			IF Long(ldw_target.describe("#" + String(i) + ".x")) <> 0  THEN
				s_modify = s_modify + " #"+String(i)+".background.mode = '1'"
			END IF
		NEXT
		
		IF ldw_target.Modify(s_modify) <> "" THEN 
			Return -1
		END IF
		Return 1
    CASE Else //Compliant code
        Return -1
END CHOOSE 

Return 2

end event
Visual Expert 2023
 VEPBRULE35