# -*- coding: utf-8 -*- # Copyright 2012-2020 Jean-Pierre LEDURE # ===================================================================================================================== # === The Access2Base library is a part of the LibreOffice project. === # === Full documentation is available on http://www.access2base.com === # ===================================================================================================================== # Access2Base is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # Access2Base is free software; you can redistribute it and/or modify it under the terms of either (at your option): # 1) The Mozilla Public License, v. 2.0. If a copy of the MPL was not # distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/ . # 2) The GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. If a copy of the LGPL was not # distributed with this file, see http://www.gnu.org/licenses/ . """ The access2base.py module implements an interface between Python (user) scripts and the Access2Base Basic library. Usage: from access2base import * Additionally, if Python and LibreOffice are started in separate processes: If LibreOffice started from console ... (example for Linux) ./soffice --accept='socket,host=localhost,port=2019;urp;' then insert next statement A2BConnect(hostname = 'localhost', port = 2019) Specific documentation about Access2Base and Python: http://www.access2base.com/access2base.html#%5B%5BAccess2Base%20and%20Python%5D%5D """ import uno XSCRIPTCONTEXT = uno from platform import system as _opsys import datetime import os import sys import traceback _LIBRARY = '' # Should be 'Access2Base' or 'Access2BaseDev' _VERSION = '7.4' # Actual version number _WRAPPERMODULE = 'Python' # Module name in the Access2Base library containing Python interfaces # CallByName types _vbGet, _vbLet, _vbMethod, _vbSet, _vbUNO = 2, 4, 1, 8, 16 class _Singleton(type): """ A Singleton design pattern Credits: « Python in a Nutshell » by Alex Martelli, O'Reilly """ instances = {} def __call__(cls, *args, **kwargs): if cls not in cls.instances: cls.instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs) return cls.instances[cls] class acConstants(object, metaclass = _Singleton): """ VBA constants used in the Access2Base API. Values derived from MSAccess, except when conflicts """ # Python special constants (used in the protocol between Python and Basic) # ----------------------------------------------------------------- Empty = '+++EMPTY+++' Null = '+++NULL+++' Missing = '+++MISSING+++' FromIsoFormat = '%Y-%m-%d %H:%M:%S' # To be used with datetime.datetime.strptime() # AcCloseSave # ----------------------------------------------------------------- acSaveNo = 2 acSavePrompt = 0 acSaveYes = 1 # AcFormView # ----------------------------------------------------------------- acDesign = 1 acNormal = 0 acPreview = 2 # AcFormOpenDataMode # ----------------------------------------------------------------- acFormAdd = 0 acFormEdit = 1 acFormPropertySettings = -1 acFormReadOnly = 2 # acView # ----------------------------------------------------------------- acViewDesign = 1 acViewNormal = 0 acViewPreview = 2 # acOpenDataMode # ----------------------------------------------------------------- acAdd = 0 acEdit = 1 acReadOnly = 2 # AcObjectType # ----------------------------------------------------------------- acDefault = -1 acDiagram = 8 acForm = 2 acQuery = 1 acReport = 3 acTable = 0 # Unexisting in MS/Access acBasicIDE = 101 acDatabaseWindow = 102 acDocument = 111 acWelcome = 112 # Subtype if acDocument docWriter = "Writer" docCalc = "Calc" docImpress = "Impress" docDraw = "Draw" docMath = "Math" # AcWindowMode # ----------------------------------------------------------------- acDialog = 3 acHidden = 1 acIcon = 2 acWindowNormal = 0 # VarType constants # ----------------------------------------------------------------- vbEmpty = 0 vbNull = 1 vbInteger = 2 vbLong = 3 vbSingle = 4 vbDouble = 5 vbCurrency = 6 vbDate = 7 vbString = 8 vbObject = 9 vbBoolean = 11 vbVariant = 12 vbByte = 17 vbUShort = 18 vbULong = 19 vbBigint = 35 vbDecimal = 37 vbArray = 8192 # MsgBox constants # ----------------------------------------------------------------- vbOKOnly = 0 # OK button only (default) vbOKCancel = 1 # OK and Cancel buttons vbAbortRetryIgnore = 2 # Abort, Retry, and Ignore buttons vbYesNoCancel = 3 # Yes, No, and Cancel buttons vbYesNo = 4 # Yes and No buttons vbRetryCancel = 5 # Retry and Cancel buttons vbCritical = 16 # Critical message vbQuestion = 32 # Warning query vbExclamation = 48 # Warning message vbInformation = 64 # Information message vbDefaultButton1 = 128 # First button is default (default) (VBA: 0) vbDefaultButton2 = 256 # Second button is default vbDefaultButton3 = 512 # Third button is default vbApplicationModal = 0 # Application modal message box (default) # MsgBox Return Values # ----------------------------------------------------------------- vbOK = 1 # OK button pressed vbCancel = 2 # Cancel button pressed vbAbort = 3 # Abort button pressed vbRetry = 4 # Retry button pressed vbIgnore = 5 # Ignore button pressed vbYes = 6 # Yes button pressed vbNo = 7 # No button pressed # Dialogs Return Values # ------------------------------------------------------------------ dlgOK = 1 # OK button pressed dlgCancel = 0 # Cancel button pressed # Control Types # ----------------------------------------------------------------- acCheckBox = 5 acComboBox = 7 acCommandButton = 2 acToggleButton = 122 acCurrencyField = 18 acDateField = 15 acFileControl = 12 acFixedLine = 24 # FREE ENTRY (USEFUL IN DIALOGS) acFixedText = 10 acLabel = 10 acFormattedField = 1 # FREE ENTRY TAKEN TO NOT CONFUSE WITH acTextField acGridControl = 11 acGroupBox = 8 acOptionGroup = 8 acHiddenControl = 13 acImageButton = 4 acImageControl = 14 acImage = 14 acListBox = 6 acNavigationBar = 22 acNumericField = 17 acPatternField = 19 acProgressBar = 23 # FREE ENTRY (USEFUL IN DIALOGS) acRadioButton = 3 acOptionButton = 3 acScrollBar = 20 acSpinButton = 21 acSubform = 112 acTextField = 9 acTextBox = 9 acTimeField = 16 # AcRecord # ----------------------------------------------------------------- acFirst = 2 acGoTo = 4 acLast = 3 acNewRec = 5 acNext = 1 acPrevious = 0 # FindRecord # ----------------------------------------------------------------- acAnywhere = 0 acEntire = 1 acStart = 2 acDown = 1 acSearchAll = 2 acUp = 0 acAll = 0 acCurrent = -1 # AcDataObjectType # ----------------------------------------------------------------- acActiveDataObject = -1 acDataForm = 2 acDataQuery = 1 acDataServerView = 7 acDataStoredProcedure = 9 acDataTable = 0 # AcQuitOption # ----------------------------------------------------------------- acQuitPrompt = 0 acQuitSaveAll = 1 acQuitSaveNone = 2 # AcCommand # ----------------------------------------------------------------- acCmdAboutMicrosoftAccess = 35 acCmdAboutOpenOffice = 35 acCmdAboutLibreOffice = 35 acCmdVisualBasicEditor = 525 acCmdBringToFront = 52 acCmdClose = 58 acCmdToolbarsCustomize = 165 acCmdChangeToCommandButton = 501 acCmdChangeToCheckBox = 231 acCmdChangeToComboBox = 230 acCmdChangeToTextBox = 227 acCmdChangeToLabel = 228 acCmdChangeToImage = 234 acCmdChangeToListBox = 229 acCmdChangeToOptionButton = 233 acCmdCopy = 190 acCmdCut = 189 acCmdCreateRelationship = 150 acCmdDelete = 337 acCmdDatabaseProperties = 256 acCmdSQLView = 184 acCmdRemove = 366 acCmdDesignView = 183 acCmdFormView = 281 acCmdNewObjectForm = 136 acCmdNewObjectTable = 134 acCmdNewObjectView = 350 acCmdOpenDatabase = 25 acCmdNewObjectQuery = 135 acCmdShowAllRelationships = 149 acCmdNewObjectReport = 137 acCmdSelectAll = 333 acCmdRemoveTable = 84 acCmdOpenTable = 221 acCmdRename = 143 acCmdDeleteRecord = 223 acCmdApplyFilterSort = 93 acCmdSnapToGrid = 62 acCmdViewGrid = 63 acCmdInsertHyperlink = 259 acCmdMaximumRecords = 508 acCmdObjectBrowser = 200 acCmdPaste = 191 acCmdPasteSpecial = 64 acCmdPrint = 340 acCmdPrintPreview = 54 acCmdSaveRecord = 97 acCmdFind = 30 acCmdUndo = 292 acCmdRefresh = 18 acCmdRemoveFilterSort = 144 acCmdRunMacro = 31 acCmdSave = 20 acCmdSaveAs = 21 acCmdSelectAllRecords = 109 acCmdSendToBack = 53 acCmdSortDescending = 164 acCmdSortAscending = 163 acCmdTabOrder = 41 acCmdDatasheetView = 282 acCmdZoomSelection = 371 # AcSendObjectType # ----------------------------------------------------------------- acSendForm = 2 acSendNoObject = -1 acSendQuery = 1 acSendReport = 3 acSendTable = 0 # AcOutputObjectType # ----------------------------------------------------------------- acOutputTable = 0 acOutputQuery = 1 acOutputForm = 2 acOutputArray = -1 # AcEncoding # ----------------------------------------------------------------- acUTF8Encoding = 76 # AcFormat # ----------------------------------------------------------------- acFormatPDF = "writer_pdf_Export" acFormatODT = "writer8" acFormatDOC = "MS Word 97" acFormatHTML = "HTML" acFormatODS = "calc8" acFormatXLS = "MS Excel 97" acFormatXLSX = "Calc MS Excel 2007 XML" acFormatTXT = "Text - txt - csv (StarCalc)" # AcExportQuality # ----------------------------------------------------------------- acExportQualityPrint = 0 acExportQualityScreen = 1 # AcSysCmdAction # ----------------------------------------------------------------- acSysCmdAccessDir = 9 acSysCmdAccessVer = 7 acSysCmdClearHelpTopic = 11 acSysCmdClearStatus = 5 acSysCmdGetObjectState = 10 acSysCmdGetWorkgroupFile = 13 acSysCmdIniFile = 8 acSysCmdInitMeter = 1 acSysCmdProfile = 12 acSysCmdRemoveMeter = 3 acSysCmdRuntime = 6 acSysCmdSetStatus = 4 acSysCmdUpdateMeter = 2 # Type property # ----------------------------------------------------------------- dbBigInt = 16 dbBinary = 9 dbBoolean = 1 dbByte = 2 dbChar = 18 dbCurrency = 5 dbDate = 8 dbDecimal = 20 dbDouble = 7 dbFloat = 21 dbGUID = 15 dbInteger = 3 dbLong = 4 dbLongBinary = 11 # (OLE Object) dbMemo = 12 dbNumeric = 19 dbSingle = 6 dbText = 10 dbTime = 22 dbTimeStamp = 23 dbVarBinary = 17 dbUndefined = -1 # Attributes property # ----------------------------------------------------------------- dbAutoIncrField = 16 dbDescending = 1 dbFixedField = 1 dbHyperlinkField = 32768 dbSystemField = 8192 dbUpdatableField = 32 dbVariableField = 2 # OpenRecordset # ----------------------------------------------------------------- dbOpenForwardOnly = 8 dbSQLPassThrough = 64 dbReadOnly = 4 # Query types # ----------------------------------------------------------------- dbQAction = 240 dbQAppend = 64 dbQDDL = 4 # 96 dbQDelete = 32 dbQMakeTable = 128 # 80 dbQSelect = 0 dbQSetOperation = 8 # 128 dbQSQLPassThrough = 1 # 112 dbQUpdate = 16 # 48 # Edit mode # ----------------------------------------------------------------- dbEditNone = 0 dbEditInProgress = 1 dbEditAdd = 2 # Toolbars # ----------------------------------------------------------------- msoBarTypeNormal = 0 # Usual toolbar msoBarTypeMenuBar = 1 # Menu bar msoBarTypePopup = 2 # Shortcut menu msoBarTypeStatusBar = 11 # Status bar msoBarTypeFloater = 12 # Floating window msoControlButton = 1 # Command button msoControlPopup = 10 # Popup, submenu # New Lines # ----------------------------------------------------------------- vbCr = chr(13) vbLf = chr(10) def _NewLine(): if _opsys == 'Windows': return chr(13) + chr(10) return chr(10) vbNewLine = _NewLine() vbTab = chr(9) # Module types # ----------------------------------------------------------------- acClassModule = 1 acStandardModule = 0 # (Module) procedure types # ----------------------------------------------------------------- vbext_pk_Get = 1 # A Property Get procedure vbext_pk_Let = 2 # A Property Let procedure vbext_pk_Proc = 0 # A Sub or Function procedure vbext_pk_Set = 3 # A Property Set procedure COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER, THISDATABASEDOCUMENT = None, None, None, None def _ErrorHandler(type, value, tb): ''' Is the function to be set as new sys.excepthook to bypass the standard error handler Derived from https://stackoverflow.com/questions/31949760/how-to-limit-python-traceback-to-specific-files Handler removes traces pointing to methods located in access2base.py when error is due to a user programming error sys.excepthook = _ErrorHandler NOT APPLIED YET ''' def check_file(name): return 'access2base.py' not in name show = (fs for fs in traceback.extract_tb(tb) if check_file(fs.filename)) fmt = traceback.format_list(show) + traceback.format_exception_only(type, value) print(''.join(fmt), end = '', file = sys.stderr) # Reset to standard handler sys.excepthook = sys.__excepthook__ def A2BConnect(hostname = '', port = 0): """ To be called explicitly by user scripts when Python process runs outside the LibreOffice process. LibreOffice started as (Linux): ./soffice --accept='socket,host=localhost,port=xxxx;urp;' Otherwise called implicitly by the current module without arguments Initializes COMPONENTCONTEXT, SCRIPTPROVIDER and DESKTOP :param hostname: probably 'localhost' or '' :param port: port number or 0 :return: None """ global XSCRIPTCONTEXT, COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER # Determine COMPONENTCONTEXT, via socket or inside LibreOffice if len(hostname) > 0 and port > 0: # Explicit connection request via socket # Code derived from Bridge.py by Alain H. Romedenne local_context = XSCRIPTCONTEXT.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext( 'com.sun.star.bridge.UnoUrlResolver', local_context) try: conn = 'socket,host=%s,port=%d' % (hostname, port) connection_url = 'uno:%s;urp;StarOffice.ComponentContext' % conn established_context = resolver.resolve(connection_url) except Exception: # thrown when LibreOffice specified instance isn't started raise ConnectionError('Connection to LibreOffice failed (host = ' + hostname + ', port = ' + str(port) + ')') COMPONENTCONTEXT = established_context DESKTOP = None elif len(hostname) == 0 and port == 0: # Usual interactive mode COMPONENTCONTEXT = XSCRIPTCONTEXT.getComponentContext() DESKTOP = COMPONENTCONTEXT.ServiceManager.createInstanceWithContext( 'com.sun.star.frame.Desktop', COMPONENTCONTEXT) else: raise SystemExit('The invocation of A2BConnect() has invalid arguments') # Determine SCRIPTPROVIDER servicemanager = COMPONENTCONTEXT.ServiceManager masterscript = servicemanager.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", COMPONENTCONTEXT) SCRIPTPROVIDER = masterscript.createScriptProvider("") Script = _A2B.xScript('TraceLog', 'Trace') # Don't use invokeMethod() to force reset of error stack Script.invoke(('===>', 'Python wrapper loaded V.' + _VERSION, False), (), ()) return None class _A2B(object, metaclass = _Singleton): """ Collection of helper functions implementing the protocol between Python and Basic Read comments in PythonWrapper Basic function """ @classmethod def BasicObject(cls, objectname): objs = {'COLLECTION': _Collection , 'COMMANDBAR': _CommandBar , 'COMMANDBARCONTROL': _CommandBarControl , 'CONTROL': _Control , 'DATABASE': _Database , 'DIALOG': _Dialog , 'EVENT': _Event , 'FIELD': _Field , 'FORM': _Form , 'MODULE': _Module , 'OPTIONGROUP': _OptionGroup , 'PROPERTY': _Property , 'QUERYDEF': _QueryDef , 'RECORDSET': _Recordset , 'SUBFORM': _SubForm , 'TABLEDEF': _TableDef , 'TEMPVAR': _TempVar } return objs[objectname] @classmethod def xScript(cls, script, module): """ At first call checks the existence of the Access2Base library Initializes _LIBRARY with the found library name First and next calls execute the given script in the given module of the _LIBRARY library The script and module are presumed to exist :param script: name of script :param module: name of module :return: the script object. NB: the execution is done with the invoke() method applied on the returned object """ global _LIBRARY Script = None def sScript(lib): return 'vnd.sun.star.script:' + lib + '.' + module + '.' + script + '?language=Basic&location=application' if _LIBRARY == '': # Check the availability of the Access2Base library for lib in ('Access2BaseDev', 'Access2Base'): try: if Script is None: Script = SCRIPTPROVIDER.getScript(sScript(lib)) _LIBRARY = lib except Exception: pass if Script is None: raise SystemExit('Access2Base basic library not found') else: Script = SCRIPTPROVIDER.getScript(sScript(_LIBRARY)) return Script @classmethod def A2BErrorCode(cls): """ Return the Access2Base error stack as a tuple 0 => error code 1 => severity level 2 => short error message 3 => long error message """ Script = cls.xScript('TraceErrorCode', 'Trace') return Script.invoke((), (), ())[0] @classmethod def invokeMethod(cls, script, module, *args): """ Direct call to a named script/module pair with their arguments If the arguments do not match their definition at the Basic side, a TypeError is raised :param script: name of script :param module: name of module :param args: list of arguments to be passed to the script :return: the value returned by the script execution """ if COMPONENTCONTEXT is None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation Script = cls.xScript(script, module) try: Returned = Script.invoke((args), (), ())[0] except Exception: raise TypeError("Access2Base error: method '" + script + "' in Basic module '" + module + "' call error. Check its arguments.") else: if Returned is None: if cls.VerifyNoError(): return None return Returned @classmethod def invokeWrapper(cls, action, basic, script, *args): """ Call the Basic wrapper to invite it to execute the proposed action on a Basic object If the arguments do not match their definition at the Basic side, a TypeError is raised After execution, a check is done if the execution has raised an error within Basic If yes, a TypeError is raised :param action: Property Get, Property Let, Property Set, invoke Method or return UNO object :param basic: the reference of the Basic object, i.e. the index in the array caching the addresses of the objects conventionally Application = -1 and DoCmd = -2 :param script: the property or method name :param args: the arguments of the method, if any :return: the value returned by the execution of the Basic routine """ if COMPONENTCONTEXT is None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation # Intercept special call to Application.Events() if basic == Application.basicmodule and script == 'Events': Script = cls.xScript('PythonEventsWrapper', _WRAPPERMODULE) Returned = Script.invoke((args[0],), (), ()) else: Script = cls.xScript('PythonWrapper', _WRAPPERMODULE) NoArgs = '+++NOARGS+++' # Conventional notation for properties/methods without arguments if len(args) == 0: args = (action,) + (basic,) + (script,) + (NoArgs,) else: args = (action,) + (basic,) + (script,) + args try: Returned = Script.invoke((args), (), ()) except Exception: raise TypeError("Access2Base error: method '" + script + "' call error. Check its arguments.") if isinstance(Returned[0], tuple): # Is returned value a reference to a basic object, a scalar or a UNO object ? if len(Returned[0]) in (3, 4): if Returned[0][0] == 0: # scalar return Returned[0][1] elif Returned[0][0] == 1: # reference to objects cache basicobject = cls.BasicObject(Returned[0][2]) if len(Returned[0]) == 3: return basicobject(Returned[0][1], Returned[0][2]) else: return basicobject(Returned[0][1], Returned[0][2], Returned[0][3]) elif Returned[0][0] == 2: # Null value return None else: # Should not happen return None else: # UNO object return Returned[0] elif Returned[0] is None: if cls.VerifyNoError(): return None else: # Should not happen return Returned[0] @classmethod def VerifyNoError(cls): # has Access2Base generated an error ? errorstack = cls.A2BErrorCode() # 0 = code, 1 = severity, 2 = short text, 3 = long text if errorstack[1] in ('ERROR', 'FATAL', 'ABORT'): raise TypeError('Access2Base error: ' + errorstack[3]) return True class Application(object, metaclass = _Singleton): """ Collection of methods located in the Application (Basic) module """ W = _A2B.invokeWrapper basicmodule = -1 @classmethod def AllDialogs(cls, dialog = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'AllDialogs', dialog) @classmethod def AllForms(cls, form = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'AllForms', form) @classmethod def AllModules(cls, module = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'AllModules', module) @classmethod def CloseConnection(cls): return cls.W(_vbMethod, cls.basicmodule, 'CloseConnection') @classmethod def CommandBars(cls, bar = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'CommandBars', bar) @classmethod def CurrentDb(cls): return cls.W(_vbMethod, cls.basicmodule, 'CurrentDb') @classmethod def CurrentUser(cls): return cls.W(_vbMethod, cls.basicmodule, 'CurrentUser') @classmethod def DAvg(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DAvg', expression, domain, criteria) @classmethod def DCount(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DCount', expression, domain, criteria) @classmethod def DLookup(cls, expression, domain, criteria = '', orderclause = ''): return cls.W(_vbMethod, cls.basicmodule, 'DLookup', expression, domain, criteria, orderclause) @classmethod def DMax(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DMax', expression, domain, criteria) @classmethod def DMin(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DMin', expression, domain, criteria) @classmethod def DStDev(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DStDev', expression, domain, criteria) @classmethod def DStDevP(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DStDevP', expression, domain, criteria) @classmethod def DSum(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DSum', expression, domain, criteria) @classmethod def DVar(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DVar', expression, domain, criteria) @classmethod def DVarP(cls, expression, domain, criteria = ''): return cls.W(_vbMethod, cls.basicmodule, 'DVarP', expression, domain, criteria) @classmethod def Events(cls, event): return cls.W(_vbMethod, cls.basicmodule, 'Events', event) @classmethod def Forms(cls, form = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'Forms', form) @classmethod def getObject(cls, shortcut): return cls.W(_vbMethod, cls.basicmodule, 'getObject', shortcut) GetObject = getObject @classmethod def getValue(cls, shortcut): return cls.W(_vbMethod, cls.basicmodule, 'getValue', shortcut) GetValue = getValue @classmethod def HtmlEncode(cls, string, length = 0): return cls.W(_vbMethod, cls.basicmodule, 'HtmlEncode', string, length) @classmethod def OpenConnection(cls, thisdatabasedocument = acConstants.Missing): global THISDATABASEDOCUMENT if COMPONENTCONTEXT is None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation if DESKTOP is not None: THISDATABASEDOCUMENT = DESKTOP.getCurrentComponent() return _A2B.invokeMethod('OpenConnection', 'Application', THISDATABASEDOCUMENT) @classmethod def OpenDatabase(cls, connectionstring, username = '', password = '', readonly = False): return cls.W(_vbMethod, cls.basicmodule, 'OpenDatabase', connectionstring, username , password, readonly) @classmethod def ProductCode(cls): return cls.W(_vbMethod, cls.basicmodule, 'ProductCode') @classmethod def setValue(cls, shortcut, value): return cls.W(_vbMethod, cls.basicmodule, 'setValue', shortcut, value) SetValue = setValue @classmethod def SysCmd(cls, action, text = '', value = -1): return cls.W(_vbMethod, cls.basicmodule, 'SysCmd', action, text, value) @classmethod def TempVars(cls, var = acConstants.Missing): return cls.W(_vbMethod, cls.basicmodule, 'TempVars', var) @classmethod def Version(cls): return cls.W(_vbMethod, cls.basicmodule, 'Version') class DoCmd(object, metaclass = _Singleton): """ Collection of methods located in the DoCmd (Basic) module """ W = _A2B.invokeWrapper basicmodule = -2 @classmethod def ApplyFilter(cls, filter = '', sqlwhere = '', controlname = ''): return cls.W(_vbMethod, cls.basicmodule, 'ApplyFilter', filter, sqlwhere, controlname) @classmethod def Close(cls, objecttype, objectname, save = acConstants.acSavePrompt): return cls.W(_vbMethod, cls.basicmodule, 'Close', objecttype, objectname, save) @classmethod def CopyObject(cls, sourcedatabase, newname, sourceobjecttype, sourceobjectname): # 1st argument must be set return cls.W(_vbMethod, cls.basicmodule, 'CopyObject', sourcedatabase, newname, sourceobjecttype , sourceobjectname) @classmethod def FindNext(cls): return cls.W(_vbMethod, cls.basicmodule, 'FindNext') @classmethod def FindRecord(cls, findwhat, match = acConstants.acEntire, matchcase = False, search = acConstants.acSearchAll , searchasformatted = False, onlycurrentfield = acConstants.acCurrent, findfirst = True): return cls.W(_vbMethod, cls.basicmodule, 'FindRecord', findwhat, match, matchcase, search , searchasformatted, onlycurrentfield, findfirst) @classmethod def GetHiddenAttribute(cls, objecttype, objectname = ''): return cls.W(_vbMethod, cls.basicmodule, 'GetHiddenAttribute', objecttype, objectname) @classmethod def GoToControl(cls, controlname): return cls.W(_vbMethod, cls.basicmodule, 'GoToControl', controlname) @classmethod def GoToRecord(cls, objecttype = acConstants.acActiveDataObject, objectname = '', record = acConstants.acNext , offset = 1): return cls.W(_vbMethod, cls.basicmodule, 'GoToRecord', objecttype, objectname, record, offset) @classmethod def Maximize(cls): return cls.W(_vbMethod, cls.basicmodule, 'Maximize') @classmethod def Minimize(cls): return cls.W(_vbMethod, cls.basicmodule, 'Minimize') @classmethod def MoveSize(cls, left = -1, top = -1, width = -1, height = -1): return cls.W(_vbMethod, cls.basicmodule, 'MoveSize', left, top, width, height) @classmethod def OpenForm(cls, formname, view = acConstants.acNormal, filter = '', wherecondition = '' , datamode = acConstants.acFormEdit, windowmode = acConstants.acWindowNormal, openargs = ''): return cls.W(_vbMethod, cls.basicmodule, 'OpenForm', formname, view, filter, wherecondition , datamode, windowmode, openargs) @classmethod def OpenQuery(cls, queryname, view = acConstants.acNormal, datamode = acConstants.acEdit): return cls.W(_vbMethod, cls.basicmodule, 'OpenQuery', queryname, view, datamode) @classmethod def OpenReport(cls, queryname, view = acConstants.acNormal): return cls.W(_vbMethod, cls.basicmodule, 'OpenReport', queryname, view) @classmethod def OpenSQL(cls, sql, option = -1): return cls.W(_vbMethod, cls.basicmodule, 'OpenSQL', sql, option) @classmethod def OpenTable(cls, tablename, view = acConstants.acNormal, datamode = acConstants.acEdit): return cls.W(_vbMethod, cls.basicmodule, 'OpenTable', tablename, view, datamode) @classmethod def OutputTo(cls, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = '' , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint): if objecttype == acConstants.acOutputForm: encoding = 0 return cls.W(_vbMethod, cls.basicmodule, 'OutputTo', objecttype, objectname, outputformat , outputfile, autostart, templatefile, encoding, quality) @classmethod def Quit(cls): return cls.W(_vbMethod, cls.basicmodule, 'Quit') @classmethod def RunApp(cls, commandline): return cls.W(_vbMethod, cls.basicmodule, 'RunApp', commandline) @classmethod def RunCommand(cls, command): return cls.W(_vbMethod, cls.basicmodule, 'RunCommand', command) @classmethod def RunSQL(cls, SQL, option = -1): return cls.W(_vbMethod, cls.basicmodule, 'RunSQL', SQL, option) @classmethod def SelectObject(cls, objecttype, objectname = '', indatabasewindow = False): return cls.W(_vbMethod, cls.basicmodule, 'SelectObject', objecttype, objectname, indatabasewindow) @classmethod def SendObject(cls, objecttype = acConstants.acSendNoObject, objectname = '', outputformat = '', to = '', cc = '' , bcc = '', subject = '', messagetext = '', editmessage = True, templatefile = ''): return cls.W(_vbMethod, cls.basicmodule, 'SendObject', objecttype, objectname, outputformat, to, cc , bcc, subject, messagetext, editmessage, templatefile) @classmethod def SetHiddenAttribute(cls, objecttype, objectname = '', hidden = True): return cls.W(_vbMethod, cls.basicmodule, 'SetHiddenAttribute', objecttype, objectname, hidden) @classmethod def SetOrderBy(cls, orderby = '', controlname = ''): return cls.W(_vbMethod, cls.basicmodule, 'SetOrderBy', orderby, controlname) @classmethod def ShowAllRecords(cls): return cls.W(_vbMethod, cls.basicmodule, 'ShowAllRecords') class Basic(object, metaclass = _Singleton): """ Collection of helper functions having the same behaviour as their Basic counterparts """ M = _A2B.invokeMethod @classmethod def ConvertFromUrl(cls, url): return cls.M('PyConvertFromUrl', _WRAPPERMODULE, url) @classmethod def ConvertToUrl(cls, file): return cls.M('PyConvertToUrl', _WRAPPERMODULE, file) @classmethod def CreateUnoService(cls, servicename): return cls.M('PyCreateUnoService', _WRAPPERMODULE, servicename) @classmethod def DateAdd(cls, add, count, datearg): if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat() dateadd = cls.M('PyDateAdd', _WRAPPERMODULE, add, count, datearg) return datetime.datetime.strptime(dateadd, acConstants.FromIsoFormat) @classmethod def DateDiff(cls, add, date1, date2, weekstart = 1, yearstart = 1): if isinstance(date1, datetime.datetime): date1 = date1.isoformat() if isinstance(date2, datetime.datetime): date2 = date2.isoformat() return cls.M('PyDateDiff', _WRAPPERMODULE, add, date1, date2, weekstart, yearstart) @classmethod def DatePart(cls, add, datearg, weekstart = 1, yearstart = 1): if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat() return cls.M('PyDatePart', _WRAPPERMODULE, add, datearg, weekstart, yearstart) @classmethod def DateValue(cls, datestring): datevalue = cls.M('PyDateValue', _WRAPPERMODULE, datestring) return datetime.datetime.strptime(datevalue, acConstants.FromIsoFormat) @classmethod def Format(cls, value, format = None): if isinstance(value, (datetime.datetime, datetime.date, datetime.time, )): value = value.isoformat() return cls.M('PyFormat', _WRAPPERMODULE, value, format) @classmethod def GetGUIType(cls): return cls.M('PyGetGUIType', _WRAPPERMODULE) @staticmethod def GetPathSeparator(): return os.sep @classmethod def GetSystemTicks(cls): return cls.M('PyGetSystemTicks', _WRAPPERMODULE) @classmethod def MsgBox(cls, text, type = None, dialogtitle = None): return cls.M('PyMsgBox', _WRAPPERMODULE, text, type, dialogtitle) class GlobalScope(object, metaclass = _Singleton): @classmethod def BasicLibraries(cls): return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Basic') @classmethod def DialogLibraries(self): return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Dialog') @classmethod def InputBox(cls, text, title = None, default = None, xpos = None, ypos = None): return cls.M('PyInputBox', _WRAPPERMODULE, text, title, default, xpos, ypos) @staticmethod def Now(): return datetime.datetime.now() @staticmethod def RGB(red, green, blue): return int('%02x%02x%02x' % (red, green, blue), 16) @classmethod def Timer(cls): return cls.M('PyTimer', _WRAPPERMODULE) @staticmethod def Xray(myObject): xrayscript = 'vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application' xScript = SCRIPTPROVIDER.getScript(xrayscript) xScript.invoke((myObject,), (), ()) return class _BasicObject(object): """ Parent class of Basic objects Each subclass is identified by its classProperties: dictionary with keys = allowed properties, value = True if editable or False Each instance is identified by its - reference in the cache managed by Basic - type ('DATABASE', 'COLLECTION', ...) - name (form, control, ... name) - may be blank Properties are got and set following next strategy: 1. Property names are controlled strictly ('Value' and not 'value') 2. Getting a property value for the first time is always done via a Basic call 3. Next occurrences are fetched from the Python dictionary of the instance if the property is read-only, otherwise via a Basic call 4. Methods output might force the deletion of a property from the dictionary ('MoveNext' changes 'BOF' and 'EOF' properties) 5. Setting a property value is done via a Basic call, except if self.internal == True """ W = _A2B.invokeWrapper internal_attributes = ('objectreference', 'objecttype', 'name', 'internal') def __init__(self, reference = -1, objtype = None, name = ''): self.objectreference = reference # reference in the cache managed by Basic self.objecttype = objtype # ('DATABASE', 'COLLECTION', ...) self.name = name # '' when no name self.internal = False # True to exceptionally allow assigning a new value to a read-only property self.localProperties = () def __getattr__(self, name): if name in ('classProperties', 'localProperties'): pass elif name in self.classProperties: # Get Property from Basic return self.W(_vbGet, self.objectreference, name) # Usual attributes getter return super(_BasicObject, self).__getattribute__(name) def __setattr__(self, name, value): if name in ('classProperties', 'localProperties'): pass elif name in self.classProperties: if self.internal: # internal = True forces property setting even if property is read-only pass elif self.classProperties[name]: # True == Editable self.W(_vbLet, self.objectreference, name, value) else: raise AttributeError("type object '" + self.objecttype + "' has no editable attribute '" + name + "'") elif name[0:2] == '__' or name in self.internal_attributes or name in self.localProperties: pass else: raise AttributeError("type object '" + self.objecttype + "' has no attribute '" + name + "'") object.__setattr__(self, name, value) return def __repr__(self): repr = "Basic object (type='" + self.objecttype + "', index=" + str(self.objectreference) if len(self.name) > 0: repr += ", name='" + self.name + "'" return repr + ")" def _Reset(self, propertyname, basicreturn = None): """ force new value or erase properties from dictionary (done to optimize calls to Basic scripts) """ if propertyname in ('BOF', 'EOF'): # After a Move method invocation on a Recordset object, BOF or EOF likely to be got soon if isinstance(basicreturn, int): self.internal = True # f.i. basicreturn = 0b10 means: BOF = True, EOF = False self.BOF = basicreturn in (2, 3, -2, -3) self.EOF = basicreturn in (1, 3, -1, -3) self.internal = False return ( basicreturn >= 0 ) else: # Suppress possibly invalid property values: e.g. RecordCount after Delete applied on Recordset object if property in self.__dict__: del(self.propertyname) return basicreturn @property def Name(self): return self.name @property def ObjectType(self): return self.objecttype def Dispose(self): return self.W(_vbMethod, self.objectreference, 'Dispose') def getProperty(self, propertyname, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'getProperty', propertyname, index) GetProperty = getProperty def hasProperty(self, propertyname): return propertyname in tuple(self.classProperties.keys()) HasProperty = hasProperty def Properties(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Properties', index) def setProperty(self, propertyname, value, index = acConstants.Missing): if self.hasProperty(propertyname): if self.W(_vbMethod, self.objectreference, 'setProperty', propertyname, value, index): return self.__setattr__(propertyname, value) raise AttributeError("type object '" + self.objecttype + "' has no editable attribute '" + propertyname + "'") SetProperty = setProperty class _Collection(_BasicObject): """ Collection object built as a Python iterator """ classProperties = dict(Count = False) def __init__(self, reference = -1, objtype = None): super().__init__(reference, objtype) self.localProperties = ('count', 'index') self.count = self.Count self.index = 0 def __iter__(self): self.index = 0 return self def __next__(self): if self.index >= self.count: raise StopIteration next = self.Item(self.index) self.index = self.index + 1 return next def __len__(self): return self.count def Add(self, table, value = acConstants.Missing): if isinstance(table, _BasicObject): # Add method applied to a TABLEDEFS collection return self.W(_vbMethod, self.objectreference, 'Add', table.objectreference) else: # Add method applied to a TEMPVARS collection add = self.W(_vbMethod, self.objectreference, 'Add', table, value) self.count = self.Count return add def Delete(self, name): return self.W(_vbMethod, self.objectreference, 'Delete', name) def Item(self, index): return self.W(_vbMethod, self.objectreference, 'Item', index) def Remove(self, tempvarname): remove = self.W(_vbMethod, self.objectreference, 'Remove', tempvarname) self.count = self.Count return remove def RemoveAll(self): remove = self.W(_vbMethod, self.objectreference, 'RemoveAll') self.count = self.Count return remove class _CommandBar(_BasicObject): classProperties = dict(BuiltIn = False, Parent = False, Visible = True) def CommandBarControls(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'CommandBarControls', index) def Reset(self): return self.W(_vbMethod, self.objectreference, 'Reset') class _CommandBarControl(_BasicObject): classProperties = dict(BeginGroup = False, BuiltIn = False, Caption = True, Index = False, OnAction = True , Parent = False, TooltipText = True, Type = False, Visible = True) def Execute(self): return self.W(_vbMethod, self.objectreference, 'Execute') class _Control(_BasicObject): classProperties = dict(BackColor = True, BorderColor = True, BorderStyle = True, Cancel = True, Caption = True , ControlSource = False, ControlTipText = True, ControlType = False, Default = True , DefaultValue = True, Enabled = True, FontBold = True, FontItalic = True, FontName = True , FontSize = True, FontUnderline = True, FontWeight = True, ForeColor = True, Form = False , Format = True, ItemData = False, ListCount = False, ListIndex = True, Locked = True, MultiSelect = True , OnActionPerformed = True, OnAdjustmentValueChanged = True, OnApproveAction = True , OnApproveReset = True, OnApproveUpdate = True, OnChanged = True, OnErrorOccurred = True , OnFocusGained = True, OnFocusLost = True, OnItemStateChanged = True, OnKeyPressed = True , OnKeyReleased = True, OnMouseDragged = True, OnMouseEntered = True, OnMouseExited = True , OnMouseMoved = True, OnMousePressed = True, OnMouseReleased = True, OnResetted = True, OnTextChanged = True , OnUpdated = True, OptionValue = False, Page = False, Parent = False, Picture = True, Required = True , RowSource = True, RowSourceType = True, Selected = True, SelLength = True, SelStart = True, SelText = True , SubType = False, TabIndex = True, TabStop = True, Tag = True, Text = False, TextAlign = True , TripleState = True, Value = True, Visible = True ) @property def BoundField(self): return self.W(_vbUNO, self.objectreference, 'BoundField') @property def ControlModel(self): return self.W(_vbUNO, self.objectreference, 'ControlModel') @property def ControlView(self): return self.W(_vbUNO, self.objectreference, 'ControlView') @property def LabelControl(self): return self.W(_vbUNO, self.objectreference, 'LabelControl') def AddItem(self, value, index = -1): basicreturn = self.W(_vbMethod, self.objectreference, 'AddItem', value, index) self._Reset('ItemData') self._Reset('ListCount') return basicreturn def Controls(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Controls', index) # Overrides method in parent class: list of properties is strongly control type dependent def hasProperty(self, propertyname): return self.W(_vbMethod, self.objectreference, 'hasProperty', propertyname) HasProperty = hasProperty def RemoveItem(self, index): basicreturn = self.W(_vbMethod, self.objectreference, 'RemoveItem', index) self._Reset('ItemData') self._Reset('ListCount') return basicreturn def Requery(self): return self.W(_vbMethod, self.objectreference, 'Requery') def SetSelected(self, value, index): return self.W(_vbMethod, self.objectreference, 'SetSelected', value, index) def SetFocus(self): return self.W(_vbMethod, self.objectreference, 'SetFocus') class _Database(_BasicObject): classProperties = dict(Connect = False, OnCreate = True , OnFocus = True, OnLoad = True, OnLoadFinished = True, OnModifyChanged = True, OnNew = True , OnPrepareUnload = True, OnPrepareViewClosing = True, OnSave = True, OnSaveAs = True , OnSaveAsDone = True, OnSaveAsFailed = True, OnSaveDone = True, OnSaveFailed = True , OnSubComponentClosed = True, OnSubComponentOpened = True, OnTitleChanged = True, OnUnfocus = True , OnUnload = True, OnViewClosed = True, OnViewCreated = True, Version = False ) @property def Connection(self): return self.W(_vbUNO, self.objectreference, 'Connection') @property def Document(self): return self.W(_vbUNO, self.objectreference, 'Document') @property def MetaData(self): return self.W(_vbUNO, self.objectreference, 'MetaData') def Close(self): return self.W(_vbMethod, self.objectreference, 'Close') def CloseAllRecordsets(self): return self.W(_vbMethod, self.objectreference, 'CloseAllRecordsets') def CreateQueryDef(self, name, sqltext, option = -1): return self.W(_vbMethod, self.objectreference, 'CreateQueryDef', name, sqltext, option) def CreateTableDef(self, name): return self.W(_vbMethod, self.objectreference, 'CreateTableDef', name) def DAvg(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DAvg', expression, domain, criteria) def DCount(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DCount', expression, domain, criteria) def DLookup(self, expression, domain, criteria = '', orderclause = ''): return self.W(_vbMethod, self.objectreference, 'DLookup', expression, domain, criteria, orderclause) def DMax(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DMax', expression, domain, criteria) def DMin(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DMin', expression, domain, criteria) def DStDev(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DStDev', expression, domain, criteria) def DStDevP(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DStDevP', expression, domain, criteria) def DVar(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DVar', expression, domain, criteria) def DVarP(self, expression, domain, criteria = ''): return self.W(_vbMethod, self.objectreference, 'DVarP', expression, domain, criteria) def OpenRecordset(self, source, type = -1, option = -1, lockedit = -1): return self.W(_vbMethod, self.objectreference, 'OpenRecordset', source, type, option, lockedit) def OpenSQL(self, SQL, option = -1): return self.W(_vbMethod, self.objectreference, 'OpenSQL', SQL, option) def OutputTo(self, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = '' , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint): if objecttype == acConstants.acOutputForm: encoding = 0 return self.W(_vbMethod, self.objectreference, 'OutputTo', objecttype, objectname, outputformat, outputfile , autostart, templatefile, encoding, quality) def QueryDefs(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'QueryDefs', index) def Recordsets(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Recordsets', index) def RunSQL(self, SQL, option = -1): return self.W(_vbMethod, self.objectreference, 'RunSQL', SQL, option) def TableDefs(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'TableDefs', index) class _Dialog(_BasicObject): classProperties = dict(Caption = True, Height = True, IsLoaded = False, OnFocusGained = True , OnFocusLost = True, OnKeyPressed = True, OnKeyReleased = True, OnMouseDragged = True , OnMouseEntered = True, OnMouseExited = True, OnMouseMoved = True, OnMousePressed = True , OnMouseReleased = True, Page = True, Parent = False, Visible = True, Width = True ) @property def UnoDialog(self): return self.W(_vbUNO, self.objectreference, 'UnoDialog') def EndExecute(self, returnvalue): return self.W(_vbMethod, self.objectreference, 'EndExecute', returnvalue) def Execute(self): return self.W(_vbMethod, self.objectreference, 'Execute') def Move(self, left = -1, top = -1, width = -1, height = -1): return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height) def OptionGroup(self, groupname): return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname) def Start(self): return self.W(_vbMethod, self.objectreference, 'Start') def Terminate(self): return self.W(_vbMethod, self.objectreference, 'Terminate') class _Event(_BasicObject): classProperties = dict(ButtonLeft = False, ButtonMiddle = False, ButtonRight = False, ClickCount = False , ContextShortcut = False, EventName = False, EventType = False, FocusChangeTemporary = False , KeyAlt = False, KeyChar = False, KeyCode = False, KeyCtrl = False, KeyFunction = False, KeyShift = False , Recommendation = False, RowChangeAction = False, Source = False, SubComponentName = False , SubComponentType = False, XPos = False, YPos = False ) class _Field(_BasicObject): classProperties = dict(DataType = False, DataUpdatable = False, DbType = False, DefaultValue = True , Description = True, FieldSize = False, Size = False, Source = False , SourceField = False, SourceTable = False, TypeName = False, Value = True ) @property def Column(self): return self.W(_vbUNO, self.objectreference, 'Column') def AppendChunk(self, value): return self.W(_vbMethod, self.objectreference, 'AppendChunk', value) def GetChunk(self, offset, numbytes): return self.W(_vbMethod, self.objectreference, 'GetChunk', offset, numbytes) def ReadAllBytes(self, file): return self.W(_vbMethod, self.objectreference, 'ReadAllBytes', file) def ReadAllText(self, file): return self.W(_vbMethod, self.objectreference, 'ReadAllText', file) def WriteAllBytes(self, file): return self.W(_vbMethod, self.objectreference, 'WriteAllBytes', file) def WriteAllText(self, file): return self.W(_vbMethod, self.objectreference, 'WriteAllText', file) class _Form(_BasicObject): classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, Bookmark = True , Caption = True, CurrentRecord = True, Filter = True, FilterOn = True, Height = True , IsLoaded = False, OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OpenArgs = False, OrderBy = True , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True , Width = True ) @property def Component(self): return self.W(_vbUNO, self.objectreference, 'Component') @property def ContainerWindow(self): return self.W(_vbUNO, self.objectreference, 'ContainerWindow') @property def DatabaseForm(self): return self.W(_vbUNO, self.objectreference, 'DatabaseForm') def Close(self): return self.W(_vbMethod, self.objectreference, 'Close') def Controls(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Controls', index) def Move(self, left = -1, top = -1, width = -1, height = -1): return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height) def OptionGroup(self, groupname): return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname) def Refresh(self): return self.W(_vbMethod, self.objectreference, 'Refresh') def Requery(self): return self.W(_vbMethod, self.objectreference, 'Requery') def SetFocus(self): return self.W(_vbMethod, self.objectreference, 'SetFocus') class _Module(_BasicObject): classProperties = dict(CountOfDeclarationLines = False, CountOfLines = False, Type = False) def __init__(self, reference = -1, objtype = None, name = ''): super().__init__(reference, objtype, name) self.localProperties = ('startline', 'startcolumn', 'endline', 'endcolumn', 'prockind') def Find(self, target, startline, startcolumn, endline, endcolumn, wholeword = False , matchcase = False, patternsearch = False): Returned = self.W(_vbMethod, self.objectreference, 'Find', target, startline, startcolumn, endline , endcolumn, wholeword, matchcase, patternsearch) if isinstance(Returned, tuple): if Returned[0] and len(Returned) == 5: self.startline = Returned[1] self.startcolumn = Returned[2] self.endline = Returned[3] self.endcolumn = Returned[4] return Returned[0] return Returned def Lines(self, line, numlines): return self.W(_vbMethod, self.objectreference, 'Lines', line, numlines) def ProcBodyLine(self, procname, prockind): return self.W(_vbMethod, self.objectreference, 'ProcBodyLine', procname, prockind) def ProcCountLines(self, procname, prockind): return self.W(_vbMethod, self.objectreference, 'ProcCountLines', procname, prockind) def ProcOfLine(self, line, prockind): Returned = self.W(_vbMethod, self.objectreference, 'ProcOfLine', line, prockind) if isinstance(Returned, tuple): if len(Returned) == 2: self.prockind = Returned[1] return Returned[0] return Returned def ProcStartLine(self, procname, prockind): return self.W(_vbMethod, self.objectreference, 'ProcStartLine', procname, prockind) class _OptionGroup(_BasicObject): classProperties = dict(Count = False, Value = True) def Controls(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Controls', index) class _Property(_BasicObject): classProperties = dict(Value = True) class _QueryDef(_BasicObject): classProperties = dict(SQL = True, Type = False) @property def Query(self): return self.W(_vbUNO, self.objectreference, 'Query') def Execute(self, options = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Execute', options) def Fields(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Fields', index) def OpenRecordset(self, type = -1, option = -1, lockedit = -1): return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) class _Recordset(_BasicObject): classProperties = dict(AbsolutePosition = True, BOF = False, Bookmark = True, Bookmarkable = False , EditMode = False, EOF = False, Filter = True, RecordCount = False ) @property def RowSet(self): return self.W(_vbUNO, self.objectreference, 'RowSet') def AddNew(self): return self.W(_vbMethod, self.objectreference, 'AddNew') def CancelUpdate(self): return self.W(_vbMethod, self.objectreference, 'CancelUpdate') def Clone(self): return self.W(_vbMethod, self.objectreference, 'Clone') def Close(self): return self.W(_vbMethod, self.objectreference, 'Close') def Delete(self): return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Delete')) def Edit(self): return self.W(_vbMethod, self.objectreference, 'Edit') def Fields(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Fields', index) def GetRows(self, numrows): return self.W(_vbMethod, self.objectreference, 'GetRows', numrows) def Move(self, rows, startbookmark = acConstants.Missing): return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'Move', rows, startbookmark)) def MoveFirst(self): return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveFirst')) def MoveLast(self): return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveLast')) def MoveNext(self): return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveNext')) def MovePrevious(self): return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MovePrevious')) def OpenRecordset(self, type = -1, option = -1, lockedit = -1): return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) def Update(self): return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Update')) class _SubForm(_Form): classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, CurrentRecord = True , Filter = True, FilterOn = True, LinkChildFields = False, LinkMasterFields = False , OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OrderBy = True , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True ) def SetFocus(self): raise AttributeError("type object 'SubForm' has no method 'SetFocus'") class _TableDef(_BasicObject): classProperties = dict() @property def Table(self): return self.W(_vbUNO, self.objectreference, 'Table') def CreateField(self, name, type, size = 0, attributes = 0): return self.W(_vbMethod, self.objectreference, 'CreateField', name, type, size, attributes) def Fields(self, index = acConstants.Missing): return self.W(_vbMethod, self.objectreference, 'Fields', index) def OpenRecordset(self, type = -1, option = -1, lockedit = -1): return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) class _TempVar(_BasicObject): classProperties = dict(Value = True) """ Set of directly callable error handling methods """ def DebugPrint(*args): dargs = () for arg in args: if isinstance(arg, _BasicObject): arg = ('[' + arg.objecttype + '] ' + arg.name).rstrip() dargs = dargs + (arg,) return _A2B.invokeMethod('DebugPrint', _WRAPPERMODULE, *dargs) def TraceConsole(): return _A2B.invokeMethod('TraceConsole', 'Trace') def TraceError(tracelevel, errorcode, errorprocedure, errorline): return _A2B.invokeMethod('TraceError', 'Trace', tracelevel, errorcode, errorprocedure, errorline) def TraceLevel(newtracelevel = 'ERROR'): return _A2B.invokeMethod('TraceLevel', 'Trace', newtracelevel) def TraceLog(tracelevel, text, messagebox = True): return _A2B.invokeMethod('TraceLog', 'Trace', tracelevel, text, messagebox)