Example: Working with VARIANT data type variables

LYCIA


VARIANT is a data type intended to store values of different scalar data types. It is not a built-in 4gl data type - it was implemented specifically for Lycia and Lycia users. Variables defined as VARIANT take the type of a variable or a constant assigned to this VARIANT variable.

Full article about this data type is available here:


Below you can find a simple 4GL application which demonstrates the VARIANT variable dynamically changing its data type.

4GL:

MAIN
   DEFINE
      var_char     CHAR(40),
      var_datetime DATETIME YEAR TO FRACTION(5),
      var_integer  INTEGER,
      var_variant  VARIANT            

   ##### VARIANT as CHAR #####
   LET var_char = "abc"
   CALL my_func(var_char) RETURNING var_char
   DISPLAY "main: var_char = ", var_char

   ##### VARIANT as INT #####
   CALL my_func(123) RETURNING var_integer 
   DISPLAY "main: var_integer = ", var_integer

   ##### VARIANT as DATETIME #####
   LET var_datetime = "9999-12-31 23:59:59.99999"
   CALL my_func(var_datetime)RETURNING var_datetime
   DISPLAY "main: var_datetime = ", var_datetime

CALL fgl_getkey()
END MAIN

FUNCTION my_func(p_variant)
DEFINE p_variant VARIANT

DISPLAY "my_func():  p_variant is ", p_variant.gettypefullname()
RETURN p_variant

END FUNCTION



Using VARIANT variable as a parameter for functions.

4GL:

MAIN
   DEFINE
      var_char     CHAR(40),
      var_datetime DATETIME YEAR TO FRACTION(5),
      var_integer  INTEGER,
      var_variant  VARIANT            

   ##### VARIANT as CHAR #####
   LET var_char = "abc"
   CALL my_func(var_char) RETURNING var_char
   DISPLAY "main: var_char = ", var_char

   ##### VARIANT as INT #####
   CALL my_func(123) RETURNING var_integer 
   DISPLAY "main: var_integer = ", var_integer

   ##### VARIANT as DATETIME #####
   LET var_datetime = "9999-12-31 23:59:59.99999"
   CALL my_func(var_datetime)RETURNING var_datetime
   DISPLAY "main: var_datetime = ", var_datetime

CALL fgl_getkey()
END MAIN

FUNCTION my_func(p_variant)
DEFINE p_variant VARIANT

DISPLAY "my_func():  p_variant is ", p_variant.gettypefullname()
RETURN p_variant

END FUNCTION



Using VARIANT variables with databases. (Note: Currently, you can use VARIANT variables only with the Informix databases.)

4GL:

DATABASE stores
MAIN
   DEFINE
      var_char     CHAR(40),
      var_datetime DATETIME YEAR TO FRACTION(5),
      var_date     DATE,
      var_integer  INTEGER,
      var_decimal  DECIMAL(16,2),
      var_variant  VARIANT            

   WHENEVER ERROR CONTINUE
   DROP TABLE table_test
   CREATE TABLE table_test
   (
     col_char     CHAR(40),
     col_datetime DATETIME YEAR TO FRACTION(5),
     col_date     DATE,
     col_integer  INTEGER,
     col_decimal  DECIMAL(16,2)
   )

   ##### VARIANT as CHAR #####
   LET var_char = "abc"
   LET var_variant = var_char 
   INSERT INTO table_test(col_char) VALUES(var_variant)
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ", SQLCA.SQLCODE END IF
   SELECT col_char INTO var_variant FROM table_test WHERE col_char = var_variant
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ", SQLCA.SQLCODE END IF
   DISPLAY "var_variant is ",var_variant.gettypefullname(),",  var_variant = ",var_variant

   ##### VARIANT as DATETIME #####
   LET var_datetime = "9999-12-31 23:59:59.99999"
   LET var_variant = var_datetime 
   INSERT INTO table_test(col_datetime) VALUES(var_variant)
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   SELECT col_datetime INTO var_variant FROM table_test WHERE col_datetime = var_variant
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   DISPLAY "var_variant is ",var_variant.gettypefullname(),",  var_variant = ",var_variant

   ##### VARIANT as DATE #####
   LET var_date = "12/31/9999"
   LET var_variant = var_date 
   INSERT INTO table_test(col_date) VALUES(var_variant)
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   SELECT col_date INTO var_variant FROM table_test WHERE col_date = var_variant
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   DISPLAY "var_variant is ",var_variant.gettypefullname(),",  var_variant = ",var_variant

   ##### VARIANT as INT #####
   LET var_integer = 123
   LET var_variant = var_integer 
   INSERT INTO table_test(col_integer) VALUES(var_variant)
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   SELECT col_integer INTO var_variant FROM table_test WHERE col_integer = var_variant
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   DISPLAY "var_variant is ",var_variant.gettypefullname(),",  var_variant = ",var_variant

   ##### VARIANT as DECIMAL #####
   LET var_decimal = 123.45
   LET var_variant = var_decimal 
   INSERT INTO table_test(col_decimal) VALUES(var_variant)
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   SELECT col_decimal INTO var_variant FROM table_test WHERE col_decimal = var_variant
   IF SQLCA.SQLCODE <> 0 THEN DISPLAY "SQLCA.SQLCODE = ",SQLCA.SQLCODE END IF
   DISPLAY "var_variant is ",var_variant.gettypefullname(),",  var_variant = ",var_variant

END MAIN



Using DYNAMIC ARRAY of VARIANT (Display array).

4GL:

MAIN
  DEFINE DisplArr DYNAMIC ARRAY OF VARIANT
  DEFINE str STRING
  DEFINE tm DATETIME HOUR TO SECOND
  DEFINE dt DATE
  
  LET str = "string value"
  LET tm  = "15:22:35"  
  LET dt  = "01.05.2018"
  OPEN WINDOW w WITH FORM "variant_04_display_dynamic_array"  ATTRIBUTE(BORDER)

  LET DisplArr[1]= str
  LET DisplArr[2]= tm
  LET DisplArr[3]= dt

  DISPLAY DisplArr TO rec.* 
  CALL fgl_getkey()
  DISPLAY "ARRAY:",DisplArr
END MAIN

Form:

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://namespaces.querix.com/2015/fglForms" title="New Form 1">
	<form.rootContainer>
		<GridPanel identifier="rootContainer" visible="true">
			<GridPanel.gridColumnDefinitions>
				<GridColumnDefinition gridLengthValue=""/>
				<GridColumnDefinition gridLengthValue=""/>
				<GridColumnDefinition gridLengthValue=""/>
				<GridColumnDefinition gridLengthValue=""/>
				<GridColumnDefinition gridLengthValue=""/>
				<GridColumnDefinition gridLengthValue=""/>
			</GridPanel.gridColumnDefinitions>
			<GridPanel.gridRowDefinitions>
				<GridRowDefinition gridLengthValue=""/>
			</GridPanel.gridRowDefinitions>
			<Label text="Text" isDynamic="true" visible="true" identifier="lb4" gridItemLocation="0,0,1,1" verticalAlignment="Center"/>
			<TextField visible="true" identifier="f1" gridItemLocation="1,0,1,1"/>
			<Label text="Time" isDynamic="true" visible="true" identifier="lb5" gridItemLocation="2,0,1,1" verticalAlignment="Center"/>
			<TimeEditField dataType="DateTime,Hour,Minute,," visible="true" identifier="f2" gridItemLocation="3,0,1,1"/>
			<Label text="Date" isDynamic="true" visible="true" identifier="lb6" gridItemLocation="4,0,1,1" verticalAlignment="Center"/>
			<Calendar dataType="Date,,,," visible="true" identifier="f3" gridItemLocation="5,0,1,1" verticalAlignment="Center"/>
		</GridPanel>
	</form.rootContainer>
	<form.screenRecords>
		<ScreenRecord identifier="rec" fields="f1,f2,f3"/>
	</form.screenRecords>
</form>



Using DYNAMIC ARRAY of VARIANT (Input array).

4GL:

MAIN
  DEFINE tableRec DYNAMIC ARRAY OF DYNAMIC ARRAY OF VARIANT
  DEFINE numCol, numRow INTEGER
  DEFINE f1 BOOL,
		f2 STRING,
		f3 DATE,
		f4 SMALLINT,
		f5 INT,
		f6 INT,
		f7 INT,
		f8 INT,
		f9 CHAR(20),
		f10 DATETIME HOUR TO SECOND


	LET f1 = 1
	LET f2 = "functionfield"
	LET f3 ="12.12.2012"
	LET f4 = 20
	LET f5 = 5
	LET f6 = 50
	LET f7 = 50
	LET f8 = 50
	LET f9 = "textfield"
	LET f10 = "15:22:33"

	OPEN WINDOW w WITH FORM "variant_05_input_dynamic_array"  ATTRIBUTE(BORDER)

	FOR numRow=1 TO 5
		FOR numCol=1 TO 10
			CASE numCol
				WHEN 1	LET tableRec[numRow][numCol]=f1
			    WHEN 2	LET tableRec[numRow][numCol]=f2||" "||numRow
			    WHEN 3  LET tableRec[numRow][numCol]=f3
			    WHEN 4  LET tableRec[numRow][numCol]=f4
			    WHEN 5  LET tableRec[numRow][numCol]=f5
			    WHEN 6  LET tableRec[numRow][numCol]=f6
			    WHEN 7  LET tableRec[numRow][numCol]=f7
			    WHEN 8  LET tableRec[numRow][numCol]=f8
			    WHEN 9  LET tableRec[numRow][numCol]=f9
			    WHEN 10  LET tableRec[numRow][numCol]=f10
			END CASE
		END FOR
	END FOR
  
  INPUT ARRAY tableRec FROM tarr.* ATTRIBUTE (WITHOUT DEFAULTS)
  DISPLAY "INPUT ARRAY:",tableRec
END MAIN

Form:

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://namespaces.querix.com/2015/fglForms">
	<form.rootContainer>
		<Table preferredSize="1000,300.0" visible="true" fieldTable="" identifier="tarr">
			<TableColumn text="CheckBox" resizable="true" visible="true" fieldTable="" identifier="tc_f1">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<CheckBox title="CheckBox" visible="true" fieldTable="" identifier="f1">
					<CheckBox.checkedValue>
						<IntegerLiteral integerValue="1"/>
					</CheckBox.checkedValue>
					<CheckBox.uncheckedValue>
						<IntegerLiteral/>
					</CheckBox.uncheckedValue>
				</CheckBox>
			</TableColumn>
			<TableColumn text="FunctionField" resizable="true" visible="true" fieldTable="" identifier="tc_f2">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<FunctionField visible="true" fieldTable="" identifier="f2"/>
			</TableColumn>
			<TableColumn text="Calendar" resizable="true" visible="true" fieldTable="" identifier="tc_f3">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<Calendar dataType="Date,,,," visible="true" fieldTable="" identifier="f3"/>
			</TableColumn>
			<TableColumn text="ListBox" resizable="true" visible="true" fieldTable="" identifier="tc_f4">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<ListBox visible="true" fieldTable="" identifier="f4">
					<ListBoxItem text="value1" identifier="f4_1"/>
					<ListBoxItem text="value2" identifier="f4_2">
						<ListBoxItem.value>
							<IntegerLiteral integerValue="20"/>
						</ListBoxItem.value>
					</ListBoxItem>
				</ListBox>
			</TableColumn>
			<TableColumn text="RadioButtonList" resizable="true" visible="true" fieldTable="" identifier="tc_f5">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<RadioGroup orientation="Vertical" visible="true" fieldTable="" identifier="f5">
					<Radio title="value0" identifier="f5_0">
						<Radio.value>
							<IntegerLiteral integerValue="3"/>
						</Radio.value>
					</Radio>
					<Radio title="value1" identifier="f5_1">
						<Radio.value>
							<IntegerLiteral integerValue="5"/>
						</Radio.value>
					</Radio>
				</RadioGroup>
			</TableColumn>
			<TableColumn text="Slider" resizable="true" visible="true" fieldTable="" identifier="tc_f6">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<Slider maxValue="100" dataType="Integer,,,," visible="true" fieldTable="" identifier="f6"/>
			</TableColumn>
			<TableColumn text="Spinner" resizable="true" visible="true" fieldTable="" identifier="tc_f7">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<Spinner step="1" maxValue="100" visible="true" fieldTable="" identifier="f7">
					<Spinner.defaultValue>
						<IntegerLiteral/>
					</Spinner.defaultValue>
				</Spinner>
			</TableColumn>
			<TableColumn text="ScrollBar" resizable="true" visible="true" fieldTable="" identifier="tc_f8">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<ScrollBar largeStep="10" smallStep="1" maxValue="100" dataType="SmallInt,,,," visible="true" fieldTable="" identifier="f8"/>
			</TableColumn>
			<TableColumn text="TextField" resizable="true" visible="true" fieldTable="" identifier="tc_f9">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<TextField visible="true" fieldTable="" identifier="f9"/>
			</TableColumn>
			<TableColumn text="TimeEditField" resizable="true" visible="true" fieldTable="" identifier="tc_f10">
				<TableColumn.columnLength>
					<GridLength gridLengthValue=""/>
				</TableColumn.columnLength>
				<TimeEditField visible="true" fieldTable="" identifier="f10"/>
			</TableColumn>
		</Table>
	</form.rootContainer>
	<form.screenRecords>
		<ScreenRecord identifier="tarr" fields="f1,f2,f3,f4,f5,f6,f7,f8,f9,f10"/>
	</form.screenRecords>
</form>



Please find below the link to our Gitlab repository which contains 4GL applications examples.

Follow instructions in this article to add the above-mentioned repository to your Lycia IDE. Feel free to contact us in case if any additional information or assistance is needed.