Bug 144924 - Split Basic function return Array Type String, not Variant/String like the oldest version
Summary: Split Basic function return Array Type String, not Variant/String like the ol...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
7.1.3.2 release
Hardware: All All
: medium normal
Assignee: Andreas Heinisch
URL:
Whiteboard: target:7.3.0 target:7.2.3
Keywords:
Depends on:
Blocks:
 
Reported: 2021-10-04 20:31 UTC by edil
Modified: 2021-10-12 20:09 UTC (History)
4 users (show)

See Also:
Crash report or crash signature:


Attachments
Array of Arrays (49.57 KB, image/png)
2021-10-05 12:58 UTC, Andreas Heinisch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description edil 2021-10-04 20:31:55 UTC
Sub Main ' LibreOffice 6.3
	Dim a
	a = Split("5+3", "+") ' a Type Variant(0 to 1);  a(0) Type Variant/String
	a(0) = cInt(a(0)) ' --> 5  a(0) Type Variant/Integer
End Sub

Sub Main ' LibreOffice 7.1.3
	Dim a
	a = Split("5+3", "+") ' a Type String(0 to 1);  a(0) Type String
	a(0) = cInt(a(0)) ' --> "5"  a(0) Type String    REMAIN STRING
End Sub

It seems logical to have Array(String) from one String, but ....
Whit new behavior it is impossible to change the Type of items, and worst it is impossible to make Split(Item) to obtain an Array of Arrays.
Obviously I can create a New Array(Variant) and put there the new values, but my old macros now give errors, and it is more slow.
Comment 1 Andreas Heinisch 2021-10-05 06:43:13 UTC
Change was introduced with https://gerrit.libreoffice.org/c/core/+/104039
Comment 2 Andreas Heinisch 2021-10-05 06:50:12 UTC
I will do some experiments with a potential fix. Imho we could set a single item to Variant/String instead of String.
Comment 3 Andreas Heinisch 2021-10-05 07:06:15 UTC
Excel behaves the same as LO for split. Should we change the behaviour as asked in this bug report? We can even use the VBASupport flag in order to prevent the type conversion. Mike what do you think?
Comment 4 Mike Kaganski 2021-10-05 07:47:05 UTC
(In reply to Andreas Heinisch from comment #3)

If we change this, we will re-introduce the same problem that we have fixed in bug 123025. I believe that we should not implement this request.

Regarding performance, we should focus on making it faster.

My take: NOTABUG/WONTFIX.
Comment 5 edil 2021-10-05 08:14:29 UTC
From Pitonyak OpenOffice.org Macros Explained  §5.4. Array to String and back again pag. 118 

"The Split function returns a Variant array of strings, created by breaking a string into multiple strings based on a delimiter."

And this for many many years ....
Need to think a lot before changing a behavior of 20 years...

Fix Redim with a new array() As String and then copy values with CStr()...
Comment 6 Andreas Heinisch 2021-10-05 08:16:32 UTC
(In reply to edil from comment #0)
> It seems logical to have Array(String) from one String, but ....
> Whit new behavior it is impossible to change the Type of items, and worst it
> is impossible to make Split(Item) to obtain an Array of Arrays.
> Obviously I can create a New Array(Variant) and put there the new values,
> but my old macros now give errors, and it is more slow.

Could you give an example where you need more performance or a code snippet where it is slow now?
Comment 7 edil 2021-10-05 11:45:01 UTC
(In reply to Andreas Heinisch from comment 6)
Hi Andreas
it is not only a problem of speed, ma also to design macro:
I have a range of string numbers rgDesMisu, where the rows are the 3 rooms dimension Long Width Height, one row for each room. I transform each row for calculate the ceiling in one row and if H the lateral surface in another row.

To avoid a lot of Redim, and don't know in advance the number of result rows,  

Dim aaDesMisus : aaDesMisus = rgDesMisu.DataArray
		Dim sPareti$, sSoffitto$
	For r = 0 To UBound(aaDesMisus)
		aDesMisus = aaDesMisus(r)
		sDes = Trim(CStr(aDesMisus(0))) : sN = Trim(CStr(aDesMisus(1)))
		sL = Trim(CStr(aDesMisus(2))) : sB = Trim(CStr(aDesMisus(3))) : sHA = Trim(CStr(aDesMisus(4)))
		' Se 2 Dimensioni, resta invariato
		If sL = "" Or sB = "" Or sHA$ = "" Then
			sCells = sCells & "§§" & Join(Array(sDes, sN, sL, sB, sHA), "::")
			Goto NexR
		End If
		' 3 Dimensioni
		sPareti = Join(Array(sDes & " >Pareti", IIF(sN="", "2", sN & " * 2") , sL & " + " & sB, "", sHA), "::")
		sCells = sCells & "§§" & sPareti
		sCells = sCells & "§§" & Join(Array(sDes & " >Soffitto", sN, sL , sB, ""), "::")
NexR:			
	Next
	sCells = Mid(sCells, 3)
	Dim aaDesMisusOut : aaDesMisusOut = Split(sCells, "§§") ' aaDesMisusOut
	For r = 0 To UBound(aaDesMisusOut)
		aaDesMisusOut(r) = Split(aaDesMisusOut(r), "::")
	Next
Comment 8 edil 2021-10-05 11:59:41 UTC
For me is easy transform every cells of a row and join them with "::" and join the rows together with "§§" . At the end Split the entire string with "§§" to have an array of rows, and split every row in place (now is not possible) to obtain the array row.
So i have an array of arrays and with DataArray copy to new range.
Now I must create a new variant Array, and copy the single splitted rows in it.
It isn't a big problem, but i think at the last 20 years of coding that make now errors. :C
Comment 9 Andreas Heinisch 2021-10-05 12:16:15 UTC
May you include an example document where I can test your macro?
Comment 10 Andreas Heinisch 2021-10-05 12:58:56 UTC
Created attachment 175541 [details]
Array of Arrays

I think you mean something like this is not possible in the new version. The macro run in:
Version: 7.0.0.3 (x86)
Build ID: 8061b3e9204bef6b321a21033174034a5e2ea88e
CPU-Threads: 6; BS: Windows 10.0 Build 18362; UI-Render: Skia/Vulkan; VCL: win
Locale: de-DE (de_DE); UI: de-DE
Calc: threaded

Sub Main
	Dim sCells
	sCells = "A::B§§B::C§§C::D"
	Dim aaDesMisusOut
	aaDesMisusOut = Split(sCells, "§§") ' aaDesMisusOut
	Dim r
	For r = 0 To UBound(aaDesMisusOut)
		aaDesMisusOut(r) = Split(aaDesMisusOut(r), "::")
	Next
	
	MsgBox aaDesMisusOut(0)(0)
End Sub
Comment 11 Andreas Heinisch 2021-10-05 13:18:56 UTC
I see your problem now. You may change it to:

Dim aaVariant(UBound(aaDesMisusOut)) As Variant
For r = 0 To UBound(aaVariant)
    aaVariant(r) = Split(aaDesMisusOut(r), "::")
Next

Sure this code does not run anymore like it run for 20 years, but there are other bugs which arise from this behaviour of the split function which we addressed with this change. Unfortunately, there are still a lot of inconveniences in LOs macros and we tried to fix some of them in the last two years with the new macro team, and some of them break existing macros due to loose restrictions of the functions. I hope this workaround is fine.

However, I will try some workarounds using the split function itself and report back.
Comment 12 edil 2021-10-05 15:30:04 UTC
Andreas, thank you very much.
Your workaround is the same of mine, and it is fine.
Thank you for your heavy work to improve basic and LibreOffice.
But be very careful, it is very important for developer don't break with the past.
For example, for fix problem with Split e Redim, I would prefer change Redim and internally change Array(Variant/String) in Array(String) then make Redim  and finally return in Array(Variant/String).
Another thought: for me the stability of basic is more important than the speed : if I need speed in big array, I delivery the Array to Python and then came back to LO.
Good work !!!
Comment 13 Commit Notification 2021-10-07 06:22:41 UTC
Andreas Heinisch committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/e090afc29bdff4303f1235080fb169011220be4a

tdf#144924 - Change return type of array elements of the split function

It will be available in 7.3.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 14 Andreas Heinisch 2021-10-07 06:25:47 UTC
We addressed this issue with the VBASupport flag. In this mode split returns an array of substrings, whereas without the flag it returns elements of type variant/string.

We still have to update the documentation.
Comment 15 edil 2021-10-07 08:10:32 UTC
Andreas Thank you very much.
The stability and reliability of basic is very very important for the future of LO.
Nicola Giardinelli
Comment 16 Commit Notification 2021-10-11 14:22:10 UTC
Andreas Heinisch committed a patch related to this issue.
It has been pushed to "libreoffice-7-2":

https://git.libreoffice.org/core/commit/74aef3f0af59008aa9390bad0b24f8fce0632c87

tdf#144924 - Change return type of array elements of the split function

It will be available in 7.2.3.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 17 Commit Notification 2021-10-12 20:09:48 UTC
Andreas Heinisch committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/help/commit/c0b8265b7148b1860bd47c77e072c3c605b208da

tdf#144924 - Change return type of array elements of the split function