Export listbox based on entity selection

Product :4D - 4D Server
4D : v17R6

Just an example of a way to export data from a listbox based on entity selection.
Create the method and use it in a button in the same form as your listbox is placed.

//Project Method: LSTBX_Rows_to_Collection
//Descripton: Converts data in a listbox to a collection of values per row. (Listbox-CurrentData to Collection of Collections)
//Listbox based on entity selection.
//$1: Object name of a listbox in current form
//$2: Entity selection shown in listbox

//4D-version: v17 R6
//In this method, this is the key-commands in 4D:
//LISTBOX GET ARRAYS(;
//OBJECT Get title(
;
//LISTBOX Get column formula(*;
//Formula from string

//In a listbox based on entity selection all formulas contains “This.” to get the current value.
//If the formula works in the listbox then it should work here as well. (This.myRelationNameToOne.fieldName)

//Example:
//Could be used in a button next to a listbox.
//$Result_o:=LSTBX_Rows_to_Collection(“Object_Name_My_Listbox”;Form.My_Listbox_es)
//$Result_o.dataCollection=[“HeaderTitle1”,“HeaderTitle2”,“HeaderTitle3”,“HeaderTitle4”],[“ValueR1C1”,“ValueR1C2”,ValueR1C3,“ValueR1C4”],[“ValueR2C1”,“ValueR2C2”,ValueR2C3,“ValueR2C4”],[“ValueR3C1”,“ValueR3C2”,ValueR3C3,“ValueR3C4”]
//This collection could be used directly with:
//VP SET VALUES (VP Cell (“MyViewProArea”;0;0);$Result_o.dataCollection)
//or convert it to any format you like. (See demo-example in code)

C_TEXT($1;$ListboxName)
C_OBJECT($2;$Listbox_es)
C_OBJECT($0;$Result_o)

$ListboxName:=$1
$Listbox_es:=$2

$Result_o:=New object
$Result_o.dataCollection:=New collection //Only to remember to always return a collection

If (OBJECT Get type(*;$ListboxName)=Object type listbox)
ARRAY TEXT($colNames_at;0)
ARRAY TEXT($headerNames_at;0)
ARRAY POINTER($colVars_ap;0)
ARRAY POINTER($headerVars_ap;0)
ARRAY BOOLEAN($colsVisible_ab;0)
ARRAY POINTER($styles_ap;0)
ARRAY TEXT($colHeaderTitle_at;0)
ARRAY TEXT($colFormula_at;0)
C_LONGINT($i)

LISTBOX GET ARRAYS(*;$ListboxName;$colNames_at;$headerNames_at;$colVars_ap;$headerVars_ap;$colsVisible_ab;$styles_ap)
ARRAY TEXT($colHeaderTitle_at;Size of array($colNames_at))
ARRAY TEXT($colFormula_at;Size of array($colNames_at))
For ($i;1;Size of array($colNames_at))
	$colHeaderTitle_at{$i}:=OBJECT Get title(*;$headerNames_at{$i})
	$colFormula_at{$i}:=LISTBOX Get column formula(*;$colNames_at{$i})
End for 

C_TEXT($Column_Value_t)
C_COLLECTION($Column_Values_c)
C_OBJECT($Column_Formula_o)
C_COLLECTION($Column_Formula_c)
C_COLLECTION($ListBox_Values_c)

$Column_Value_t:=""
$Column_Values_c:=New collection
$Column_Formula_o:=New object
$Column_Formula_c:=New collection
$ListBox_Values_c:=New collection

  //Select columns and add column titles
For ($i;1;Size of array($colFormula_at))
	If ($colsVisible_ab{$i})
		$Column_Formula_o:=Formula from string($colFormula_at{$i})
		$Column_Formula_c.push($Column_Formula_o)
		$Column_Values_c.push($colHeaderTitle_at{$i})
	End if 
End for 
$ListBox_Values_c.push($Column_Values_c)  //First collection is column title

  //Main loop to get values into a collection of collections
C_OBJECT($Listbox_o)
For each ($Listbox_o;$Listbox_es)
	$Column_Values_c:=New collection
	For each ($Column_Formula_o;$Column_Formula_c)
		$Column_Values_c.push($Column_Formula_o.call($Listbox_o))
	End for each 
	$ListBox_Values_c.push($Column_Values_c)
End for each 

$Result_o.dataCollection:=$ListBox_Values_c

  //Demo-example:
If (True)  //Only for demo. Change to False after you have tested the code.
	If (Shift down)
		C_TEXT($JSON_t)
		$JSON_t:=JSON Stringify($ListBox_Values_c)
		SET TEXT TO PASTEBOARD($JSON_t)
		INVOKE ACTION(ak show clipboard)
	Else   //Convert to tab-separated text
		C_COLLECTION($ListBoxRow_c)
		C_TEXT($Row_t)
		C_TEXT($ListBox_Export_t)
		$ListBox_Export_t:=""
		For each ($ListBoxRow_c;$ListBox_Values_c)
			$Row_t:=""
			For ($i;0;($ListBoxRow_c.length-1))
				If (Value type($ListBoxRow_c[$i])=Is text)
					$Row_t:=$Row_t+$ListBoxRow_c[$i]
				Else 
					$Row_t:=$Row_t+String($ListBoxRow_c[$i])
				End if 
				If ($i<($ListBoxRow_c.length-1))
					$Row_t:=$Row_t+"\t"
				End if 
			End for 
			$ListBox_Export_t:=$ListBox_Export_t+$Row_t+"\r"
		End for each 
		SET TEXT TO PASTEBOARD($ListBox_Export_t)
		INVOKE ACTION(ak show clipboard)
	End if 
End if 

End if

$0:=$Result_o

The human version :wink:
<code 4D>
//Project Method: LSTBX_Rows_to_Collection
//Descripton: Converts data in a listbox to a collection of values per row. (Listbox-CurrentData to Collection of Collections)
//Listbox based on entity selection.
//$1: Object name of a listbox in current form
//$2: Entity selection shown in listbox

//4D-version: v17 R6
//In this method, this is the key-commands in 4D:
//LISTBOX GET ARRAYS(;
//OBJECT Get title(
;
//LISTBOX Get column formula(*;
//Formula from string

//In a listbox based on entity selection all formulas contains “This.” to get the current value.
//If the formula works in the listbox then it should work here as well. (This.myRelationNameToOne.fieldName)

//Example:
//Could be used in a button next to a listbox.
//$Result_o:=LSTBX_Rows_to_Collection(“Object_Name_My_Listbox”;Form.My_Listbox_es)
//$Result_o.dataCollection=[“HeaderTitle1”,“HeaderTitle2”,“HeaderTitle3”,“HeaderTitle4”],[“ValueR1C1”,“ValueR1C2”,ValueR1C3,“ValueR1C4”],[“ValueR2C1”,“ValueR2C2”,ValueR2C3,“ValueR2C4”],[“ValueR3C1”,“ValueR3C2”,ValueR3C3,“ValueR3C4”]
//This collection could be used directly with:
//VP SET VALUES (VP Cell (“MyViewProArea”;0;0);$Result_o.dataCollection)
//or convert it to any format you like. (See demo-example in code)

C_TEXT($1;$ListboxName)
C_OBJECT($2;$Listbox_es)
C_OBJECT($0;$Result_o)

$ListboxName:=$1
$Listbox_es:=$2

$Result_o:=New object
$Result_o.dataCollection:=New collection //Only to remember to always return a collection

If (OBJECT Get type(*;$ListboxName)=Object type listbox)
ARRAY TEXT($colNames_at;0)
ARRAY TEXT($headerNames_at;0)
ARRAY POINTER($colVars_ap;0)
ARRAY POINTER($headerVars_ap;0)
ARRAY BOOLEAN($colsVisible_ab;0)
ARRAY POINTER($styles_ap;0)
ARRAY TEXT($colHeaderTitle_at;0)
ARRAY TEXT($colFormula_at;0)
C_LONGINT($i)

LISTBOX GET ARRAYS(;$ListboxName;$colNames_at;$headerNames_at;$colVars_ap;$headerVars_ap;$colsVisible_ab;$styles_ap)
ARRAY TEXT($colHeaderTitle_at;Size of array($colNames_at))
ARRAY TEXT($colFormula_at;Size of array($colNames_at))
For ($i;1;Size of array($colNames_at))
$colHeaderTitle_at{$i}:=OBJECT Get title(
;$headerNames_at{$i})
$colFormula_at{$i}:=LISTBOX Get column formula(*;$colNames_at{$i})
End for

C_TEXT($Column_Value_t)
C_COLLECTION($Column_Values_c)
C_OBJECT($Column_Formula_o)
C_COLLECTION($Column_Formula_c)
C_COLLECTION($ListBox_Values_c)

$Column_Value_t:=""
$Column_Values_c:=New collection
$Column_Formula_o:=New object
$Column_Formula_c:=New collection
$ListBox_Values_c:=New collection

//Select columns and add column titles
For ($i;1;Size of array($colFormula_at))
If ($colsVisible_ab{$i})
$Column_Formula_o:=Formula from string($colFormula_at{$i})
$Column_Formula_c.push($Column_Formula_o)
$Column_Values_c.push($colHeaderTitle_at{$i})
End if
End for
$ListBox_Values_c.push($Column_Values_c) //First collection is column title

//Main loop to get values into a collection of collections
C_OBJECT($Listbox_o)
For each ($Listbox_o;$Listbox_es)
$Column_Values_c:=New collection
For each ($Column_Formula_o;$Column_Formula_c)
$Column_Values_c.push($Column_Formula_o.call($Listbox_o))
End for each
$ListBox_Values_c.push($Column_Values_c)
End for each

$Result_o.dataCollection:=$ListBox_Values_c

//Demo-example:
If (True) //Only for demo. Change to False after you have tested the code.
If (Shift down)
C_TEXT($JSON_t)
$JSON_t:=JSON Stringify($ListBox_Values_c)
SET TEXT TO PASTEBOARD($JSON_t)
INVOKE ACTION(ak show clipboard)
Else //Convert to tab-separated text
C_COLLECTION($ListBoxRow_c)
C_TEXT($Row_t)
C_TEXT($ListBox_Export_t)
$ListBox_Export_t:=""
For each ($ListBoxRow_c;$ListBox_Values_c)
$Row_t:=""
For ($i;0;($ListBoxRow_c.length-1))
If (Value type($ListBoxRow_c[$i])=Is text)
$Row_t:=$Row_t+$ListBoxRow_c[$i]
Else
$Row_t:=$Row_t+String($ListBoxRow_c[$i])
End if
If ($i<($ListBoxRow_c.length-1))
$Row_t:=$Row_t+"\t"
End if
End for
$ListBox_Export_t:=$ListBox_Export_t+$Row_t+"\r"
End for each
SET TEXT TO PASTEBOARD($ListBox_Export_t)
INVOKE ACTION(ak show clipboard)
End if
End if

End if

$0:=$Result_o

Traduire
</code 4D>

So much new to learn nowadays :-?

Hi Goran,
thank you for sharing! :smiley:

I hope you won’t bother if I suggest some alternate code for the last part, “convert to text”:
<code 4D>
$ListBox_Export_c:=New collection
For each ($ListBoxRow_c;$ListBox_Values_c)
For ($i;0;($ListBoxRow_c.length-1))
$ListBox_Export_c.push($ListBoxRow_c[$i])
If ($i<($ListBoxRow_c.length-1))
$ListBox_Export_c.push("\t")
End if
End for
End for each
SET TEXT TO PASTEBOARD($ListBox_Export_c.join("\r"))
</code 4D>
I noticed that, compared to successive concatenations, using .push is very fast. And .join eliminates the need to convert each data cell before (I far as I could see.)

Thanks for your suggestion, I see that everything can be arranged with objects if you just want to think in new ways. My suggestion was a little bit old school I think.:oops: :slight_smile:

: Goran EKWALL

My suggestion was a little bit old school I think.:oops: :slight_smile:
That’s not what I think at all. I’m happy to read shared code, even more when in containment! :slight_smile: