Hello LibreOffice development community,

I am developing a Python-based automation pipeline to programmatically create a full LibreOffice Base (.odb) database with a Firebird embedded engine. While the SQL-based creation of tables, views, and triggers via the UNO API is working reliably, I have encountered significant and seemingly undocumented issues specifically when trying to*programmatically create new, empty Form documents*and insert them into the.odbcontainer.

My goal is to achieve a "zero-intervention" setup script, but this specific step is proving to be a major roadblock. I am hoping to get definitive guidance on the correct, stable API sequence to achieve this.

*Environment:*

 *

   *Operating System:*Windows 11 Pro 64-bit

 *

   *LibreOffice Version:*25.8.1.1 (X86_64) Build ID:
   54047653041915e595ad4e45cccea684809c77b5

 *

   *Database Engine:*Firebird embedded

 *

   *Python:*The interpreter bundled with the LibreOffice installation
   (program/python.exe)

 *

   *Connection Method:*Connecting to a headless LibreOffice instance
   listening on a socket (--accept="socket,host=localhost,port=2002;urp;").

*The Core Problem:*
All attempted methods to create a new valid Form object and insert it into theFormDocumentscontainer of a loaded.odbdocument have failed. The process of*opening and modifying an existing, manually-created Form works perfectly*, but creating one from scratch via the API seems to be broken or requires a non-obvious procedure.

*Summary of Failed Methods and Errors:*
I have systematically tested several approaches, all of which failed in a clean environment (ensuring no lingeringsofficeprocesses were running).

1.

   *Method 1: Creating aFormDefinitionobject*

     *

       *Logic:*Get theFormContainer,
       useform_container.createInstance("com.sun.star.sdb.FormDefinition"),
       set its name, and then try to eitherinsertByNameor use it
       inloadComponentFromURL.

     *

       *Errors Encountered:*

         o

           com.sun.star.lang.IllegalArgumentException: incorrect number
           of parameters(whencreateInstanceis called without parameters).

         o

           com.sun.star.script.CannotConvertException: value is not of
           same or derived type!(when passing the
           createdFormDefinitionobject toloadComponentFromURL).

2.

   *Method 2: Loading aprivate:factory/sformdocument*

     *

       *Logic:*Create an independent, in-memory form document
       usingdesktop.loadComponentFromURL("private:factory/sform",
       ...)and then insert this valid object into the
       database'sFormContainer.

     *

       *Error Encountered:*com.sun.star.lang.IllegalArgumentException:
       Unsupported URL <private:factory/sform>: "type detection
       failed". This error suggests a context conflict when a database
       document is already loaded.

3.

   *Method 3: Copying an internal template Form (ElementExistException)*

     *

       *Logic:*If a template form exists within the.odb, get it by name
       and try toinsertByNamewith a new name.

     *

       *Error
       Encountered:*com.sun.star.container.ElementExistException: The
       object is already, with a different name, part of the
       container.This indicates that the object reference cannot be
       simply re-inserted; a deep clone would be needed, for which
       there is no straightforward API method.

4.

   *Obsolete Methods (leading toAttributeError)*

     *

       Attempts usingdb_doc.getContext()orform_docs.createNew()resulted
       inAttributeError, confirming these methods are deprecated or
       invalid for this object type.

*The Key Question for the Community:*

What is the officially supported, reliable sequence of API calls in Python to programmatically achieve the equivalent of the manual user action: "Go to the Forms section -> Click 'Create Form in Design View...' -> Save the new empty form within the.odbfile"?

*Minimal Reproducible Example (Demonstrating Failure of Method 2):*

Here is a self-contained script that reliably reproduces thetype detection failederror. It successfully connects, creates an in-memory form, opens the database, but fails on the final insertion step.

codePython

|# # Minimal script to reproduce the form creation issue. # PREREQUISITE: An empty, initialized Firebird .odb file named "TestDB.odb" must exist. # import uno import os import sys import subprocess import time from com.sun.star.beans import PropertyValue def main(): print("--- Starting Form Creation Test ---") # Define paths soffice_path = "C:\\Program Files\\LibreOffice\\program\\soffice.exe" db_path = os.path.abspath("TestDB.odb") port = 2002 # Launch LibreOffice in listening mode headless_cmd = [soffice_path, "--headless", f"--accept=socket,host=localhost,port={port};urp;", "--norestore"] loffice_process = subprocess.Popen(headless_cmd) time.sleep(10) form_doc = None db_doc = None try: # Connect to LibreOffice local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local_context) context = resolver.resolve(f"uno:socket,host=localhost,port={port};urp;StarOffice.ComponentContext") desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context) # 1. Create a valid, in-memory sform document (This part works) print("1. Creating a blank sform document in memory...") form_doc = desktop.loadComponentFromURL("private:factory/sform", "_blank", 0, ()) if not form_doc: raise Exception("Failed to create a blank sform document.") print(" -> OK: In-memory form document created.") # 2. Open the target database document (This part works) print("2. Opening the target .odb database document...") db_url = uno.systemPathToFileUrl(db_path) db_doc = desktop.loadComponentFromURL(db_url, "_blank", 0, ()) if not db_doc: raise Exception("Failed to open the database document.") print(" -> OK: Database document opened.") # 3. Attempt to insert the form into the database container (This is where it fails) print("3. Attempting to insert the sform document into the database's FormContainer...") form_container = db_doc.getFormDocuments() form_name = "My_Auto_Generated_Form" if form_container.hasByName(form_name): form_container.dropByName(form_name) form_container.insertByName(form_name, form_doc) # This line throws the exception print(" -> SUCCESS: Form inserted!") # 4. Save the database db_doc.store() print("Database saved successfully.") except Exception as e: print(f"\n--- TEST FAILED ---") print(f"ERROR: {e}") import traceback traceback.print_exc() finally: # Cleanup if form_doc: form_doc.close(True) if db_doc: db_doc.close(True) loffice_process.terminate() print("LibreOffice process terminated.") if __name__ == "__main__": main()|

Any guidance, pointers to correct documentation, or working code snippets would be immensely appreciated. We believe solving this is key to unlocking powerful automation capabilities in LibreOffice Base for the entire community.

Thank you for your time and your work on this fantastic open-source suite.

Best regards,

Alfredo

Reply via email to