Sub and/or function not changing value of variable passed to function

I had a function that received 6 variables.
The one I changed in the function was an integer.
When the function returned, that integer was unchanged.
I changed the function to a sub and same result.

Function x(Var1 as Object, Var2 as Object, Var3 as Object, Var4 as string, Var5 as integer, Var6 as string) as integer
called as sf=x(Var1, Var2, Var3, Var4, Var5, Var6)
the function set Var5 to some value (9, 2, or 5)
I check the value of Var5 before I called the function and after, and Var5 is unchanged.
I even made Var5 a Global. No change.
Function is not BYVALUE and as I understand, by reference.
I also tried to make Var5 STATIC, but no change.
Any help would be appreciated.

Here is the sub:

Private sub Sheetfind(mydoc as object, sheetDoc as object, foundsheet as object, tripit as INTEGER, xSheet as string, sheetline as string, sf as integer)
' we are to find the sheet named xsheet
' we go to the setup and find where it is by the line# sheetline
' if in this workbook, then we just set sheettripit to 2 and ensure we use mydoc and use foundsheet as xsheet
'if in another workbook, then we set sheettrip to 9 and load the worksheet
	dim path as string
	dim sURL as string	
	dim Components as variant
	dim CompEnum as variant
	dim OneComp as variant

	sf=9
	dim Prop(0) as New com.sun.star.beans.PropertyValue
		' sheet5 = COA
	path=mydoc.Sheets.getByName("Setup-POS").getCellRangeByName(sheetline).String  'get location of sheet
	
	if LCase(left(path,4))="this" then 'here we check to see if the sheet exists in workbook
		If mydoc.Sheets().hasByName(xSheet) Then 
			tripit=2
			sf=1
			foundsheet=myDoc.Sheets.getByName(xSheet)
			msgbox "6sheettripit= " & tripit
			exit sub
		else
			msgbox "NO "  & xsheet &  " file! -this must be created first!"  
			sf=3
 			exit sub
    	end if
	else
       	If Not FileExists(path) Then
    			msgbox "NO " & xSheet & " file! -this must be created first!"  
 			sf=3
    		exit sub
		end if
'here we check if the file is already open and if it is, we set sheetDoc to it		
		if FileOpen2(path) then
'		msgbox "Here" & path
			sURL = convertToURL(path)
			Components = StarDesktop.getComponents()
			CompEnum = Components.createEnumeration
			While CompEnum.hasMoreElements
				OneComp = CompEnum.nextElement
				If OneComp.URL = sURL Then
			    	sheetDoc = OneComp ' set sheetdoc to the file
					foundsheet = sheetDoc.Sheets.getByName(xSheet)   'get the sheet xsheet
					foundsheet.IsVisible = True 'view the sheet
					tripit=2
					sf=2
					msgbox "opentripit= " & tripit
					exit sub
				End If
			Wend
		else
			sUrl = convertToURL(path)  ' set path from above and open the workbook which contains the customer worksheet
			if fileExists(sUrl) then
				Prop(0).Name  = "Hidden"  'the document will open hidden"
				Prop(0).Value = False
	 			sheetDoc = stardesktop.LoadComponentFromURL(sUrl, "_default", 0, Prop())  'open file
				foundSheet = sheetDoc.Sheets.getByName(xsheet)   'get the sheet named xsheet
				tripit=9
				sf=5
				msgbox "Newtripit= " & tripit
				exit sub
			else	
				msgbox "NO " & xsheet & " file! -this must be created first!"  
 				msgbox "3tripit= " & tripit
 				sf=3
    			exit sub
	   		end if

		end if	
	end if	
	msgbox "escapetripit= " & tripit
end sub

Perhaps you could edit your question to include the entire macro so we can see exactly the code you are using.

And describe what you expect to happen.

Update: are you familiar with the concept of local and global variables? See Basics of working with LO Basic

Did you try marking relevant argument(s) ByRef explicitly? I recall myself wondering if the “ByRef is the default” statement there is correct, but never found the time to check.

tdf#145279

I did not try ByRef.
According to the link you gave, ByRef is by default.
But on further reading, ByVal seems to allow changes to the variable which is what I presumed ByRef did.
To quote your link:
“ByRef: The argument is passed by reference. ByRef is the default.
ByVal: The argument is passed by value. Its value can be modified by the called routine.”

So I shall try ByVal and see if that works.

The purpose of the sub (prior was a function) is to find a worksheet, and it first checks to see if the worksheet is listed in the setup worksheet which lists the location of worksheets and workbooks.
If the worksheet is located in “This Workbook” then it uses the current object mydoc and tripit is set to 0 to indicate such.
If not in “This Workbook”, it checks to see if the file actually exists and is open, in which case oDoc is set to the workbook and tripit is set to 9.
If the file is not in “This Workbook” and not open, the file is opened and tripit is set to 9.
I use tripit to determine whether to use mydoc or oDoc for further manipulation of the data. Hence the need to modify this variable.
I have been using tripit for some time now, and it has been working well, but not now. Maybe because now its a sub being called from a sub? Prior to subing this routine/procedure I had just hard coded the procedure in each sub, but I realized I could use a sub/function in it’s place and save code space as that routing is called many many times.

Also try

Sub SheetFind(mydoc As Object, _ 
		ByRef sheetDoc As Object, ByRef foundsheet As Object, _
		ByRef tripit As Integer, ByRef xSheet As String, _
		ByRef sheetline As String, ByRef sf As Integer)

I’d like to help you simplify your code. To be honest, this was difficult to read and understand. I could not understand the purpose of the tripit and sf variables - it seems that you are returning the result of calculations in two variables at once. This is unusual. This is usually done in one variable.

oDoc? Are you talking about the document from the sheetDoc parameter?
What if we just return mydoc to sheetDoc ? Then you will simply use this object without parsing tripit further

What happens if “This Workbook” does not contain the “Setup-POS” sheet, was renamed or deleted?

mydoc contains the worksheet in which the user is. And the current sheet is usually sheet 2 or 1. If the file which contains information needed is in this workbook, then that worksheet is set to sheet3 in mydoc.
odoc is returned if the user is seeking data contained in another file and that worksheet in oDoc is set to sheet3.
There is a lot of pulling data from different worksheets in the application. A lot of dialog boxes that contain lists which are in various worksheets/workbooks.
if “Setup-Pos” is missing, the application fails because it contains needed information.
There will be other Setups in other workbooks that contain information needed for each workbook.
In total there are 6 workbooks…

As to tripit and sf, I think you are right and I should just use one variable (I will use sf) which will then trigger to use mydoc or oDoc. And that means I should then change the procedure back to a function.
Lots of rewrites!

Once I get this monster working correctly, I might consider putting the various worksheets into one workbook. That will be a major project!

What I am working on is creating a Linux :LibreOffice POS (Point of Sale) application which allows users to enter UPC codes and then look up the UPC code worksheet to bring in the description and price into a receipt. The receipt totals the amount due with tax. I am also allowing consignment sales, Merchandise (items such as pianos, guns, gems that have identification #s), giftcards and non UPC items (food, service, etc.). The POS will print to either a laser printer or a thermal printer. This workbook will interface with a Cash Journal and send deposits to the cash journal. The cash journal will keep track of checks, deposits, vendors and update inventory (sales from the POS, and purchases from checks). The cash journal will print to checks.
I also have workbooks to generate reports (Balance Sheet, Profit and Loss, etc.), to keep inventory, and a General Journal and a General Ledger.
It’s been a long time working on this project. I am about 90% done knowing that the last 10$ will be a killer.

Thanks for the detailed explanation of the concept. But it still seems to me that you are complicating the code a lot. Let’s try to make this easier. After all, your procedure (and soon to be a function) is called SheetFind, right? So let it find and return only what it is looking for - the desired sheet, wherever it is located or Null if the desired sheet could not be found. Really, what difference does it make where this leaf is located? For further use, you will only need it and the data that is on it, am I right?

1 Like

Ok, I went and changed all my references to sheetfind and made it a function.
sf=sheetfind()
That works, and returns the right value for sf. Which allows me to use mydoc or oDoc.
So I am done with my question, because I took out all references to tripit (which did not change after using sheetfind per my initial post).
so mark this closed. :smiley:
:tophat:
As to JohnSUN notation about the complexity of the code, I would say that I have simplfied the code as much as I can using the SheetFind function. To make it simpler, I would have to have different functions because the sheet needed could be in various places (in another workbook that is open, in another workbook that is not open, or in this workbook), and you would need to know where to look for it in the POS directory.
If you can think of a simpler way to do this, let me know. You can reply to this post. I can send you my email link if you wish - not sure if that’s allowed.

I think it would make sense to store the information of that miraculous sheet in exactly one place (for example your user_config_folder)

I will try very hard to be clear. Let’s discuss again, do you need to know in which particular book the required xSheet sheet was found? What does this mean for the code that will use the found sheet?

When I talked about simplifying the code, I was talking about simplifying the Sheetfind() function.
Look here. If you prefer the Microsoft style of programming, where the user is constantly informed about things that seem important to the program’s creator, but are ultimately of no interest to the user, then the function could be something like this:

Function SheetFind(xSheet As String, sheetline As String, Optional mydoc As Object) As Variant 

Const SETUP_SHEETNAME = "Setup-POS"

Dim oSheets As Variant, oSheet As Variant  
Dim path As String, sURL As String 

Dim argsOpen(0) As New com.sun.star.beans.PropertyValue
argsOpen(0).Name  = "Hidden"  : argsOpen(0).Value = False

	GlobalScope.BasicLibraries.LoadLibrary("Tools")
	
	If isMissing(mydoc) Then mydoc = ThisComponent
	If GetDocumentType(mydoc) <> "scalc" Then
		MsgBox "The procedure is designed for working with spreadsheets." & Chr(10) & _
				"The mydoc parameter is not a spreadsheet." & Chr(10) & "The macro will stop running.", _
				MB_ICONSTOP, "SheetFind: Wrong parameter"
		End
	EndIf 
	oSheets = mydoc.getSheets()
	If Not oSheets.hasByName(SETUP_SHEETNAME) Then 
		MsgBox "The specified spreadsheet does not contain a sheet named '" & _
				SETUP_SHEETNAME &"'." & Chr(10) & "The macro will stop running.", _
				MB_ICONSTOP, "SheetFind: Wrong spreadsheet"
		End
	EndIf 
	oSheet = oSheets.getByName(SETUP_SHEETNAME)
	On Error Resume Next 
		path = GetStringofCellbyName(oSheet, sheetline)
	On Error GoTo 0
	If Trim(path) = "" Then
		MsgBox "The '" & sheetline & "' cell does not contain data." & Chr(10) & "The current spreadsheet will be used.", _
				MB_ICONEXCLAMATION, "SheetFind: Wrong path value"
		path = "this"
	EndIf 
	if LCase(Left(path,4))="this" Then 
		sURL = mydoc.getURL()
	Else 
		sURL = ConvertToURL(path)
	EndIf 
	path = ConvertFromURL(sURL)
	If Not FileExists(sURL) Then
		MsgBox "The '" & path & "' file not found." & Chr(10) & _
				"Make sure that a file with the same name exists and is readable." & _
				Chr(10) & "The macro will stop running.", _
				MB_ICONSTOP, "SheetFind: File not found"
		End
	EndIf 
	mydoc = OpenDocument(sURL, argsOpen)
	If IsNull(mydoc) Then
		MsgBox "The '" & path & "' file cannot be opened." & Chr(10) & _
				"Make sure the spreadsheet is not damaged." & _
				Chr(10) & "The macro will stop running.", _
				MB_ICONSTOP, "SheetFind: File cannot be opened"
		End
	EndIf 
	oSheets = mydoc.getSheets()
	If Not oSheets.hasByName(xSheet) Then 
		If MsgBox("The '" & path & "' spreadsheet does not contain" & Chr(10) & "a sheet named '" & _
				xSheet & "'." & Chr(10) & "This must be created first!" & Chr(10) & _
				"If you want a new blank '" & xSheet & "' sheet to be created automatically " & Chr(10) & _
				"in the '" & path & "' spreadsheet, click OK" & Chr(10) & _
				"To stop the program, click Cancel", MB_OKCANCEL+MB_ICONQUESTION, "SheetFind: Sheet missing") = IDOK Then
			On Error Resume Next 
				oSheets.insertNewByName(xSheet, oSheets.getCount())
			On Error GoTo 0
			If Not oSheets.hasByName(xSheet) Then 
				MsgBox "Failed to automatically create a new empty '" & xSheet & "' sheet" & Chr(10) & _
						Chr(10) & "The macro will stop running.", _
						MB_ICONSTOP, "SheetFind: Sheet cannot be created"
				End
			EndIf 
		Else 
			End
		EndIf 
	EndIf 
	
	SheetFind = oSheets.getByName(xSheet)
End Function 

To test this function, you can use something simple like this:

Sub testFunctionSheetFind()
Dim oResult As Variant 
	oResult = SheetFind("New Sheet","C15")
	If isNull(oResult) Then
		Print "Sheet not found"
	Else 
		Print oResult.AbsoluteName
	EndIf 
End Sub

This kind of coding has a right to exist if you are paid by the number of lines of code or by the time spent.
But if a programmer wastes time on such nonsense, he will have neither time nor energy left for anything truly useful.

Fortunately, there is another style of programming, adopted, for example, in Linux - the program simply silently does what it is intended for. And in this case the code could be like this:

Function SheetFindLikeLinux(path As String, xSheet As String) As Variant 
Dim oDoc As Object
Dim argsOpen(0) As New com.sun.star.beans.PropertyValue
argsOpen(0).Name  = "Hidden"  : argsOpen(0).Value = False
	SheetFindLikeLinux = Null 
	GlobalScope.BasicLibraries.LoadLibrary("Tools")
	oDoc = OpenDocument(ConvertToURL(path), argsOpen)
	SheetFindLikeLinux = oDoc.getSheets().getByName(xSheet)
End Function 

And test it with this procedure

Sub testFunctionSheetFindLikeLinux()
Dim oResult As Variant 
	oResult = Null
	On Error Resume Next 
		oResult = SheetFindLikeLinux(ConvertFromURL(ThisComponent.getURL()),"Sheet3")
	On Error GoTo 0
	If isNull(oResult) Then
		Print "Sheet not found"
	Else 
		Print oResult.AbsoluteName
	EndIf 
End Sub

Why should the sheet search function itself search for some cells in the current or some other book, read the path of some other book from there, check the existence of that book, search for the specified sheet in it without any hope of successful searches?.. Prepare for the function there are two parameters - path and file name and the name of the desired sheet in advance and just give these two lines of function as parameters. When the function finishes working, check if it was possible to find the desired object and use what it found. By the way, in this case, it would probably be more correct to call the function giveSheetByName() or something similar.

Firstly, this should not be done because of the risk that the published email will end up in a spammers database. Yes, modern email filters do a good job of stopping spam, but why bother them with extra work?
And secondly, just click on the username and then on the Message button to start communicating face to face in Personal Messages

1 Like