Bug 87974 - Base does not appear to execute Sub Main or allocate GLOBAL variables.
Summary: Base does not appear to execute Sub Main or allocate GLOBAL variables.
Status: RESOLVED INVALID
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Base (show other bugs)
Version:
(earliest affected)
4.1.6.2 release
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-01-02 16:55 UTC by Bill Gradwohl
Modified: 2015-09-04 03:00 UTC (History)
4 users (show)

See Also:
Crash report or crash signature:


Attachments
Entire test database that can demonstrate the issue (26.46 KB, application/vnd.oasis.opendocument.base)
2015-01-02 16:55 UTC, Bill Gradwohl
Details
Main Sub starts when opening the document -works as it should work (27.66 KB, application/vnd.oasis.opendocument.database)
2015-01-04 09:21 UTC, Robert Großkopf
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bill Gradwohl 2015-01-02 16:55:02 UTC
Created attachment 111660 [details]
Entire test database that can demonstrate the issue

Base reports Version: 4.1.6.2, Build ID 4.1.6.2-7.fc19

While attempting to solve a problem, I installed Xray. 
After altering Sub Main as follows:
   Sub Main
   Xray ThisComponent
   End Sub
I noticed it wasn't available, so I manually loaded it and continued on to solve my original problem. Xray works as long as I manually load it, but that indicates that Sub Main isn't functioning as expected.

I further modified my code as follows:
Option Explicit

Global defaultDate           as string
Global defaultVendor         as string

Sub Main
Xray ThisComponent

defaultDate = Date
defaultVendor = "Eldons"
End Sub




Sub PriorToReset(event)
dim Form
dim DateField
MsgBox ("defaultVendor = " + defaultVendor)
if defaultDate = "" then
   defaultDate = Date
   defaultVendor = ""
end if
MsgBox ("defaultDate = " + defaultDate)
Form=event.source
DateField = Form.getByName("Date")

Xray DateField

if DateField.getPropertyValue("Text") = "" then
   DateField.setPropertyValue("Text", "01/03/2015")
   'DateField.Text = Date
   MsgBox (DateField.getPropertyValue("Text"))
   Xray DateField
else
   defaultDate = DateField.Text
end if
End Sub

This consistently shows that the Globals don't exist and/or that Main is not executing because my defaultVendor is always a null string on inspection. Even removing all references to Xray shows that the globals are never initialized via Sub Main.

Attached is the entire database.

If your testing environment has Xray available, then the code can run as is. If not, please comment out all references to Xray.

To demonstrate the bug, start Base using the attached database, go to Forms and execute the Inventory form. Immediately go to the last record via >| and then attempt to go beyond it to next record via > to cause the PriorToReset sub to execute. The first MsgBox always displays a null string as the defaultVendor value when that global is supposedly explicitly set to a value via the Sub Main. Ignore all the rest of the code and results as it's testing code for a different issue.
The first MsgBox not displaying the contents of the Global shows that either there is no global or it exists but Sub Main is not being executed to initialize the global.
Comment 1 Julien Nabet 2015-01-02 17:38:17 UTC
4.1.6 is a bit old, 4.2 branch is EOL (end of life).
Could you give a try to a more recent LO version? (last stable one is 4.3.5)
Comment 2 Bill Gradwohl 2015-01-02 18:35:53 UTC
In a few hours I'll have access to a Fedora 20 and I'll see if that has a better Base version. If that also fails I'll upgrade a box to Fedora 21, but that will take a few days till I can find the time.

Please keep this incident alive for about a week. I should have updated info by then.

Thanks.
Comment 3 Bill Gradwohl 2015-01-02 20:52:30 UTC
Just tested on Fedora 20 with version 4.2.8.2 of Base.

Exactly the same results. Since this is still an old release, I'll spin up a Fedora 21 and see what it offers for a Base version.
Comment 4 Julien Nabet 2015-01-02 22:36:27 UTC
Here's the only error message when I copied your macro in your database file and gave a try:
A Scripting Framework error occurred while running the Basic script vnd.sun.star.script:Standard.Module1.PriorToReset?language=Basic&location=application.

Message: The following Basic script could not be found:
library: 'Standard'
module: 'Module1'
method: 'PriorToReset'
location: 'application'

(I tested on pc Debian x86-64 with master sources updated today).
Comment 5 Bill Gradwohl 2015-01-02 22:59:53 UTC
Sorry about that. I thought the database file had that buried inside it. Apparently not.

The listing I posted above contains that subroutine. That listing needs to be copied, in its entirety into Standard/Module1 replacing the stub Sub Main in there now. That will provide my PriorToReset subroutine.

I'm in the process of installing Fedora 21 that contains a Base version 4.3.2.2, I believe. As soon as I have the install finished I'll resume testing.
Comment 6 Bill Gradwohl 2015-01-03 04:20:36 UTC
Just installed Fedora 21 and patched it. The Base version is 4.3.4.1

The exact same problem happens in this release as well.

The mere fact that Xray isn't available unless I manually load it has to mean that the Main sub is not executing.
Comment 7 Julien Nabet 2015-01-03 10:15:00 UTC
I put all the macro in odb file/standard/module1, I don't reproduce the problem but have the same message as I quoted in a previous comment.

Robert: would you have some time to give it a try?
Comment 8 Bill Gradwohl 2015-01-03 14:42:54 UTC
I've simplified the testing code to focus specifically on the problem.

Place the following code at Standard/Module1 and follow the instructions I previously supplied for my test database to clearly show that Sub Main is not being executed or that the Globals are not being created. I don't know which is the case. I'm using an event trigger to execute the PriorToReset subroutine and that sub should have access to the Globals that should have been initialized via the Sub Main.

Option Explicit

Global defaultDate           as string
Global defaultVendor         as string

Sub Main
defaultDate = Date
defaultVendor = "Eldons"
End Sub

Sub PriorToReset(event)
MsgBox ("defaultDate = " + defaultDate)
MsgBox ("defaultVendor = " + defaultVendor)
End Sub
Comment 9 Alex Thurgood 2015-01-03 17:40:47 UTC Comment hidden (no-value)
Comment 10 Robert Großkopf 2015-01-03 18:55:27 UTC
Hi Bill,

Had first problems to link the macro the right way. Was linked to (application,Basic), must be linked to (document,Basic) in the form.

No let's have a look at the code:
--------------
Option Explicit

Global defaultDate           as string
Global defaultVendor         as string

Sub Main
defaultDate = Date
defaultVendor = "Eldons"
End Sub

Sub PriorToReset(event)
MsgBox ("defaultDate = " + defaultDate)
MsgBox ("defaultVendor = " + defaultVendor)
End Sub
-------------
Sub PriorToRest(oEvent AS OBJECT)
If there is set Option Explicit you have to declare all variables.

Where should the content of Sub Main be loaded. I haven't found any link. If you will change the code it will work as expected:

Sub PriorToReset
Main
MsgBox ("defaultDate = " + defaultDate)
MsgBox ("defaultVendor = " + defaultVendor)
End Sub

If I understand right you think 'Main' is a keyword and will be executed by default. I have just read the help of LibreOffice in German Language, when I searched for "main" in LibreOffice Basic:
«Der "Sub Main"-Abschnitt wird bei der Programmausführung nicht bevorzugt behandelt.»
Must be translated to something like this:
«"Sub Main"-procedure wouldn't be executed in preference.»
You have to start the procedure by an event or with another procedure, as shown above.

Regards

Robert
Comment 11 Robert Großkopf 2015-01-03 19:07:14 UTC
One hint:
You could also start the Sub Main during opening the Base-document. You have declared the variables as Global, so the variables would be there for the whole session of Base.
Start Tools → Customize → Events → Open Document
Add the Sub Main at his point.

Now it will be loaded when the Base-document is loaded. Main mustn't be included in any other procedure like PriorToReset.
Comment 12 Bill Gradwohl 2015-01-03 19:18:56 UTC
Robert: Thanks for the hint, but I had figured that out. Main must only run once per document. That's the whole point of having a Main entry point so that you can initialize things properly so the rest of the subs and functions can take advantage of it.
Comment 13 Robert Großkopf 2015-01-04 09:21:04 UTC
Created attachment 111713 [details]
Main Sub starts when opening the document -works as it should work

(In reply to Bill Gradwohl from comment #12)
> Robert: Thanks for the hint, but I had figured that out. Main must only run
> once per document. That's the whole point of having a Main entry point so
> that you can initialize things properly so the rest of the subs and
> functions can take advantage of it.

Could be I don't understand right - English is a little bit complicated for me. 
"Main must only run once per document". You want a procedure running once. Mustn't be named 'Main'. 'Main' is only a name without a special function, as it is described in the help of LO. I have attached your attachment, added teh macrocode - works like it should work. The sub Main starts when the document is loaded. The variables are there for all other doing. They will appear also in the form ...

Where do you get the information from 'Main' is a special keyword for LO-Basic?

I'm not a specialist in writing macros. The component for this report would be wrong. It must be BASIC. There would be persons who know more about naming of 'SUB Main' and why it is called so.
Comment 14 Bill Gradwohl 2015-01-04 13:45:58 UTC
Robert: I've been a Professional Software developer for over 30 years. I've written code in 22 languages. "Main" has a special meaning in many computer languages. It is the "Main" entry point to start the execution. Main is NOT special in Basic. However, using "Main" in LibreOffice's pseudo language does give the impression that LibreOffice supports the concept of "Main" as it's commonly understood. 

Main has that meaning in LibreOffice Calc, for example. In a Calc sheet, Main is executed without having to specify it in any event list. Main works in Calc as expected 100% of the time. I wrote a Point Of Sale system in Calc's Basic that is 6000 lines of macro code. Main never fails to execute when expected in Calc.

I don't want Main to execute when the document opens. I want main to execute when the Form is started, and it should be re-executed every time the form is started from within the same document.

After specifying Main in the event list of Base as you suggested, things do work as expected sometimes. If any modification is made to the Basic code while the document is up, Main is NOT executed when you restart a form execution. The Globals are NOT initialized as would be expected. You must close the document, effectively closing Base, and then starting from scratch to reacquire the facility of the Main entry point. That is time consuming and frustrating in a testing environment, and is unlike Calc where that does not happen.

BTW - My first language was German. I was born in Graz, Austria, but spent most of my life in the US, so appreciate your efforts in using English. My German isn't anywhere near as good as your English.
Comment 15 Julien Nabet 2015-01-04 13:52:58 UTC
Andrew: thought you might be interested in this one.
Any idea?
Comment 16 Robert Großkopf 2015-01-04 14:21:28 UTC
Hi Bill,

(In reply to Bill Gradwohl from comment #14)
> 
> Main has that meaning in LibreOffice Calc, for example. In a Calc sheet,
> Main is executed without having to specify it in any event list. Main works
> in Calc as expected 100% of the time. I wrote a Point Of Sale system in
> Calc's Basic that is 6000 lines of macro code. Main never fails to execute
> when expected in Calc.

I have tested with together with the code of comment8. Opened a Calc-document, insereted the macro-code, created a button on a sheet and saved the Calc-document.
Then closed, reopened: The same behavior here with Calc as with Base. Main isn't executed, the msgbox doesent show the date or "Eldons".
> 
> I don't want Main to execute when the document opens. I want main to execute
> when the Form is started, and it should be re-executed every time the form
> is started from within the same document.

So you could boun it to the form. Open "Inventory" for editing. 
Start Tools → Customize → Events → Open Document
... and be shure to save 'Sub Main' in 
"AirportInventoryOriginal.odb : Inventory"

> 
> After specifying Main in the event list of Base as you suggested, things do
> work as expected sometimes. If any modification is made to the Basic code
> while the document is up, Main is NOT executed when you restart a form
> execution. 

That would work in the way I described above ...

Regards

Robert
Comment 17 Bill Gradwohl 2015-01-04 14:26:30 UTC
I've never done a form in Calc. I was speaking of using Basic Macros to control the sheet's actions and capabilities natively.
Comment 18 Bill Gradwohl 2015-01-04 16:10:07 UTC
I believe every form should have its own Sub Main, and that Main should be automatically executed at every form start up. As forms are not really self standing units, they are part of Calc, Base, etc apps that need their own Sub Main to control them.
Comment 19 Andrew Pitonyak 2015-01-04 23:42:23 UTC
I see many comments floating around, so it is difficult for me to understand exactly where things stand; especially since I see some posts claiming that things run as expected.

I will add, however, that I never expect a routine of any name to be automatically run unless it is specifically tied to an event. 

If need one time initialization of something, I usually set a global sentinel variable and the initialization checks for a specific value. If that value is not present, then initialization has not completed. If initialization was completed, it immediately exits. I then call this initialization routine and it can initialize or return as required. 

I have Fedora 21 installed and I can test something specific if that is needed.
Comment 20 Bill Gradwohl 2015-01-05 14:54:36 UTC
Testing was done on Fedora 21 & LibreOffice 4.3.5.2

I've discovered that forcing Main to execute at document start up, and then starting a forms execution somewhat later, causes Global items created via 
Global dateStruct as new "com.sun.star.util.Date"
and then subsequently initialized in Main to lose their value by time the form execution causes a sub to fire.

Option Explicit

Global defaultVendor         as string
Global dateStruct            as new "com.sun.star.util.Date"

Sub Main   ' started via event "Open Document" at the document level
dim dateString               as string

BasicLibraries.LoadLibrary("XrayTool")

defaultVendor = "Eldons"
dateString = date()
dateStruct.Month = left(dateString,2)
dateStruct.Day   = mid(dateString,4,2)
dateStruct.Year  = right(dateString,4)
msgbox ("Today is " + dateStruct.Month + "/" + dateStruct.Day + "/" + dateStruct.Year)
xray dateStruct   ' this clearly shows that dateStruct is properly initialized.
End Sub




Sub PriorToReset(event)       'started via Form Properties event "Prior to reset" attached to the "Date" field.
xray dateStruct   ' this shows the structure exists, but with 0 values.
msgbox (defaultVendor) ' This shows "Eldons"
End Sub

If the document level event to execute Main is deleted, and the form level event "Open Document" is set to execute Main, the same thing happens. The Global values are reset to 0 for the dateStruct, but the default Vendor has its value of Eldons. In addition, this change to run Main at forms start causes any attempt at editing the form to run Main. Main executes when an attempt is made to just edit the form, not execute it.
Comment 21 QA Administrators 2015-07-18 17:35:10 UTC
Dear Bug Submitter,

This bug has been in NEEDINFO status with no change for at least 6 months. Please provide the requested information as soon as possible and mark the bug as UNCONFIRMED. Due to regular bug tracker maintenance, if the bug is still in NEEDINFO status with no change in 30 days the QA team will close the bug as INVALID due to lack of needed information.

For more information about our NEEDINFO policy please read the wiki located here: 
https://wiki.documentfoundation.org/QA/FDO/NEEDINFO

If you have already provided the requested information, please mark the bug as UNCONFIRMED so that the QA team knows that the bug is ready to be confirmed.


Thank you for helping us make LibreOffice even better for everyone!


Warm Regards,
QA Team

This NEEDINFO message was generated on: 2015-07-18
Comment 22 QA Administrators 2015-09-04 03:00:28 UTC
Dear Bug Submitter,

Please read this message in its entirety before proceeding.

Your bug report is being closed as INVALID due to inactivity and a lack of information which is needed in order to accurately reproduce and confirm the problem. We encourage you to retest your bug against the latest release. If the issue is still present in the latest stable release, we need the following information (please ignore any that you've already provided):

a) Provide details of your system including your operating system and the latest version of LibreOffice that you have confirmed the bug to be present

b) Provide easy to reproduce steps – the simpler the better

c) Provide any test case(s) which will help us confirm the problem

d) Provide screenshots of the problem if you think it might help

e) Read all comments and provide any requested information

Once all of this is done, please set the bug back to UNCONFIRMED and we will attempt to reproduce the issue. 
Please do not:
a) respond via email 
b) update the version field in the bug or any of the other details on the top section of FDO
Message generated on: 2015-09-03