access2base.py 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2012-2020 Jean-Pierre LEDURE
  3. # =====================================================================================================================
  4. # === The Access2Base library is a part of the LibreOffice project. ===
  5. # === Full documentation is available on http://www.access2base.com ===
  6. # =====================================================================================================================
  7. # Access2Base is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. # Access2Base is free software; you can redistribute it and/or modify it under the terms of either (at your option):
  11. # 1) The Mozilla Public License, v. 2.0. If a copy of the MPL was not
  12. # distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/ .
  13. # 2) The GNU Lesser General Public License as published by
  14. # the Free Software Foundation, either version 3 of the License, or
  15. # (at your option) any later version. If a copy of the LGPL was not
  16. # distributed with this file, see http://www.gnu.org/licenses/ .
  17. """
  18. The access2base.py module implements an interface between Python (user) scripts and the Access2Base Basic library.
  19. Usage:
  20. from access2base import *
  21. Additionally, if Python and LibreOffice are started in separate processes:
  22. If LibreOffice started from console ... (example for Linux)
  23. ./soffice --accept='socket,host=localhost,port=2019;urp;'
  24. then insert next statement
  25. A2BConnect(hostname = 'localhost', port = 2019)
  26. Specific documentation about Access2Base and Python:
  27. http://www.access2base.com/access2base.html#%5B%5BAccess2Base%20and%20Python%5D%5D
  28. """
  29. import uno
  30. XSCRIPTCONTEXT = uno
  31. from platform import system as _opsys
  32. import datetime, os, sys, traceback
  33. _LIBRARY = '' # Should be 'Access2Base' or 'Access2BaseDev'
  34. _VERSION = '7.4' # Actual version number
  35. _WRAPPERMODULE = 'Python' # Module name in the Access2Base library containing Python interfaces
  36. # CallByName types
  37. _vbGet, _vbLet, _vbMethod, _vbSet, _vbUNO = 2, 4, 1, 8, 16
  38. class _Singleton(type):
  39. """
  40. A Singleton design pattern
  41. Credits: « Python in a Nutshell » by Alex Martelli, O'Reilly
  42. """
  43. instances = {}
  44. def __call__(cls, *args, **kwargs):
  45. if cls not in cls.instances:
  46. cls.instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs)
  47. return cls.instances[cls]
  48. class acConstants(object, metaclass = _Singleton):
  49. """
  50. VBA constants used in the Access2Base API.
  51. Values derived from MSAccess, except when conflicts
  52. """
  53. # Python special constants (used in the protocol between Python and Basic)
  54. # -----------------------------------------------------------------
  55. Empty = '+++EMPTY+++'
  56. Null = '+++NULL+++'
  57. Missing = '+++MISSING+++'
  58. FromIsoFormat = '%Y-%m-%d %H:%M:%S' # To be used with datetime.datetime.strptime()
  59. # AcCloseSave
  60. # -----------------------------------------------------------------
  61. acSaveNo = 2
  62. acSavePrompt = 0
  63. acSaveYes = 1
  64. # AcFormView
  65. # -----------------------------------------------------------------
  66. acDesign = 1
  67. acNormal = 0
  68. acPreview = 2
  69. # AcFormOpenDataMode
  70. # -----------------------------------------------------------------
  71. acFormAdd = 0
  72. acFormEdit = 1
  73. acFormPropertySettings = -1
  74. acFormReadOnly = 2
  75. # acView
  76. # -----------------------------------------------------------------
  77. acViewDesign = 1
  78. acViewNormal = 0
  79. acViewPreview = 2
  80. # acOpenDataMode
  81. # -----------------------------------------------------------------
  82. acAdd = 0
  83. acEdit = 1
  84. acReadOnly = 2
  85. # AcObjectType
  86. # -----------------------------------------------------------------
  87. acDefault = -1
  88. acDiagram = 8
  89. acForm = 2
  90. acQuery = 1
  91. acReport = 3
  92. acTable = 0
  93. # Unexisting in MS/Access
  94. acBasicIDE = 101
  95. acDatabaseWindow = 102
  96. acDocument = 111
  97. acWelcome = 112
  98. # Subtype if acDocument
  99. docWriter = "Writer"
  100. docCalc = "Calc"
  101. docImpress = "Impress"
  102. docDraw = "Draw"
  103. docMath = "Math"
  104. # AcWindowMode
  105. # -----------------------------------------------------------------
  106. acDialog = 3
  107. acHidden = 1
  108. acIcon = 2
  109. acWindowNormal = 0
  110. # VarType constants
  111. # -----------------------------------------------------------------
  112. vbEmpty = 0
  113. vbNull = 1
  114. vbInteger = 2
  115. vbLong = 3
  116. vbSingle = 4
  117. vbDouble = 5
  118. vbCurrency = 6
  119. vbDate = 7
  120. vbString = 8
  121. vbObject = 9
  122. vbBoolean = 11
  123. vbVariant = 12
  124. vbByte = 17
  125. vbUShort = 18
  126. vbULong = 19
  127. vbBigint = 35
  128. vbDecimal = 37
  129. vbArray = 8192
  130. # MsgBox constants
  131. # -----------------------------------------------------------------
  132. vbOKOnly = 0 # OK button only (default)
  133. vbOKCancel = 1 # OK and Cancel buttons
  134. vbAbortRetryIgnore = 2 # Abort, Retry, and Ignore buttons
  135. vbYesNoCancel = 3 # Yes, No, and Cancel buttons
  136. vbYesNo = 4 # Yes and No buttons
  137. vbRetryCancel = 5 # Retry and Cancel buttons
  138. vbCritical = 16 # Critical message
  139. vbQuestion = 32 # Warning query
  140. vbExclamation = 48 # Warning message
  141. vbInformation = 64 # Information message
  142. vbDefaultButton1 = 128 # First button is default (default) (VBA: 0)
  143. vbDefaultButton2 = 256 # Second button is default
  144. vbDefaultButton3 = 512 # Third button is default
  145. vbApplicationModal = 0 # Application modal message box (default)
  146. # MsgBox Return Values
  147. # -----------------------------------------------------------------
  148. vbOK = 1 # OK button pressed
  149. vbCancel = 2 # Cancel button pressed
  150. vbAbort = 3 # Abort button pressed
  151. vbRetry = 4 # Retry button pressed
  152. vbIgnore = 5 # Ignore button pressed
  153. vbYes = 6 # Yes button pressed
  154. vbNo = 7 # No button pressed
  155. # Dialogs Return Values
  156. # ------------------------------------------------------------------
  157. dlgOK = 1 # OK button pressed
  158. dlgCancel = 0 # Cancel button pressed
  159. # Control Types
  160. # -----------------------------------------------------------------
  161. acCheckBox = 5
  162. acComboBox = 7
  163. acCommandButton = 2
  164. acToggleButton = 122
  165. acCurrencyField = 18
  166. acDateField = 15
  167. acFileControl = 12
  168. acFixedLine = 24 # FREE ENTRY (USEFUL IN DIALOGS)
  169. acFixedText = 10
  170. acLabel = 10
  171. acFormattedField = 1 # FREE ENTRY TAKEN TO NOT CONFUSE WITH acTextField
  172. acGridControl = 11
  173. acGroupBox = 8
  174. acOptionGroup = 8
  175. acHiddenControl = 13
  176. acImageButton = 4
  177. acImageControl = 14
  178. acImage = 14
  179. acListBox = 6
  180. acNavigationBar = 22
  181. acNumericField = 17
  182. acPatternField = 19
  183. acProgressBar = 23 # FREE ENTRY (USEFUL IN DIALOGS)
  184. acRadioButton = 3
  185. acOptionButton = 3
  186. acScrollBar = 20
  187. acSpinButton = 21
  188. acSubform = 112
  189. acTextField = 9
  190. acTextBox = 9
  191. acTimeField = 16
  192. # AcRecord
  193. # -----------------------------------------------------------------
  194. acFirst = 2
  195. acGoTo = 4
  196. acLast = 3
  197. acNewRec = 5
  198. acNext = 1
  199. acPrevious = 0
  200. # FindRecord
  201. # -----------------------------------------------------------------
  202. acAnywhere = 0
  203. acEntire = 1
  204. acStart = 2
  205. acDown = 1
  206. acSearchAll = 2
  207. acUp = 0
  208. acAll = 0
  209. acCurrent = -1
  210. # AcDataObjectType
  211. # -----------------------------------------------------------------
  212. acActiveDataObject = -1
  213. acDataForm = 2
  214. acDataQuery = 1
  215. acDataServerView = 7
  216. acDataStoredProcedure = 9
  217. acDataTable = 0
  218. # AcQuitOption
  219. # -----------------------------------------------------------------
  220. acQuitPrompt = 0
  221. acQuitSaveAll = 1
  222. acQuitSaveNone = 2
  223. # AcCommand
  224. # -----------------------------------------------------------------
  225. acCmdAboutMicrosoftAccess = 35
  226. acCmdAboutOpenOffice = 35
  227. acCmdAboutLibreOffice = 35
  228. acCmdVisualBasicEditor = 525
  229. acCmdBringToFront = 52
  230. acCmdClose = 58
  231. acCmdToolbarsCustomize = 165
  232. acCmdChangeToCommandButton = 501
  233. acCmdChangeToCheckBox = 231
  234. acCmdChangeToComboBox = 230
  235. acCmdChangeToTextBox = 227
  236. acCmdChangeToLabel = 228
  237. acCmdChangeToImage = 234
  238. acCmdChangeToListBox = 229
  239. acCmdChangeToOptionButton = 233
  240. acCmdCopy = 190
  241. acCmdCut = 189
  242. acCmdCreateRelationship = 150
  243. acCmdDelete = 337
  244. acCmdDatabaseProperties = 256
  245. acCmdSQLView = 184
  246. acCmdRemove = 366
  247. acCmdDesignView = 183
  248. acCmdFormView = 281
  249. acCmdNewObjectForm = 136
  250. acCmdNewObjectTable = 134
  251. acCmdNewObjectView = 350
  252. acCmdOpenDatabase = 25
  253. acCmdNewObjectQuery = 135
  254. acCmdShowAllRelationships = 149
  255. acCmdNewObjectReport = 137
  256. acCmdSelectAll = 333
  257. acCmdRemoveTable = 84
  258. acCmdOpenTable = 221
  259. acCmdRename = 143
  260. acCmdDeleteRecord = 223
  261. acCmdApplyFilterSort = 93
  262. acCmdSnapToGrid = 62
  263. acCmdViewGrid = 63
  264. acCmdInsertHyperlink = 259
  265. acCmdMaximumRecords = 508
  266. acCmdObjectBrowser = 200
  267. acCmdPaste = 191
  268. acCmdPasteSpecial = 64
  269. acCmdPrint = 340
  270. acCmdPrintPreview = 54
  271. acCmdSaveRecord = 97
  272. acCmdFind = 30
  273. acCmdUndo = 292
  274. acCmdRefresh = 18
  275. acCmdRemoveFilterSort = 144
  276. acCmdRunMacro = 31
  277. acCmdSave = 20
  278. acCmdSaveAs = 21
  279. acCmdSelectAllRecords = 109
  280. acCmdSendToBack = 53
  281. acCmdSortDescending = 164
  282. acCmdSortAscending = 163
  283. acCmdTabOrder = 41
  284. acCmdDatasheetView = 282
  285. acCmdZoomSelection = 371
  286. # AcSendObjectType
  287. # -----------------------------------------------------------------
  288. acSendForm = 2
  289. acSendNoObject = -1
  290. acSendQuery = 1
  291. acSendReport = 3
  292. acSendTable = 0
  293. # AcOutputObjectType
  294. # -----------------------------------------------------------------
  295. acOutputTable = 0
  296. acOutputQuery = 1
  297. acOutputForm = 2
  298. acOutputArray = -1
  299. # AcEncoding
  300. # -----------------------------------------------------------------
  301. acUTF8Encoding = 76
  302. # AcFormat
  303. # -----------------------------------------------------------------
  304. acFormatPDF = "writer_pdf_Export"
  305. acFormatODT = "writer8"
  306. acFormatDOC = "MS Word 97"
  307. acFormatHTML = "HTML"
  308. acFormatODS = "calc8"
  309. acFormatXLS = "MS Excel 97"
  310. acFormatXLSX = "Calc MS Excel 2007 XML"
  311. acFormatTXT = "Text - txt - csv (StarCalc)"
  312. # AcExportQuality
  313. # -----------------------------------------------------------------
  314. acExportQualityPrint = 0
  315. acExportQualityScreen = 1
  316. # AcSysCmdAction
  317. # -----------------------------------------------------------------
  318. acSysCmdAccessDir = 9
  319. acSysCmdAccessVer = 7
  320. acSysCmdClearHelpTopic = 11
  321. acSysCmdClearStatus = 5
  322. acSysCmdGetObjectState = 10
  323. acSysCmdGetWorkgroupFile = 13
  324. acSysCmdIniFile = 8
  325. acSysCmdInitMeter = 1
  326. acSysCmdProfile = 12
  327. acSysCmdRemoveMeter = 3
  328. acSysCmdRuntime = 6
  329. acSysCmdSetStatus = 4
  330. acSysCmdUpdateMeter = 2
  331. # Type property
  332. # -----------------------------------------------------------------
  333. dbBigInt = 16
  334. dbBinary = 9
  335. dbBoolean = 1
  336. dbByte = 2
  337. dbChar = 18
  338. dbCurrency = 5
  339. dbDate = 8
  340. dbDecimal = 20
  341. dbDouble = 7
  342. dbFloat = 21
  343. dbGUID = 15
  344. dbInteger = 3
  345. dbLong = 4
  346. dbLongBinary = 11 # (OLE Object)
  347. dbMemo = 12
  348. dbNumeric = 19
  349. dbSingle = 6
  350. dbText = 10
  351. dbTime = 22
  352. dbTimeStamp = 23
  353. dbVarBinary = 17
  354. dbUndefined = -1
  355. # Attributes property
  356. # -----------------------------------------------------------------
  357. dbAutoIncrField = 16
  358. dbDescending = 1
  359. dbFixedField = 1
  360. dbHyperlinkField = 32768
  361. dbSystemField = 8192
  362. dbUpdatableField = 32
  363. dbVariableField = 2
  364. # OpenRecordset
  365. # -----------------------------------------------------------------
  366. dbOpenForwardOnly = 8
  367. dbSQLPassThrough = 64
  368. dbReadOnly = 4
  369. # Query types
  370. # -----------------------------------------------------------------
  371. dbQAction = 240
  372. dbQAppend = 64
  373. dbQDDL = 4 # 96
  374. dbQDelete = 32
  375. dbQMakeTable = 128 # 80
  376. dbQSelect = 0
  377. dbQSetOperation = 8 # 128
  378. dbQSQLPassThrough = 1 # 112
  379. dbQUpdate = 16 # 48
  380. # Edit mode
  381. # -----------------------------------------------------------------
  382. dbEditNone = 0
  383. dbEditInProgress = 1
  384. dbEditAdd = 2
  385. # Toolbars
  386. # -----------------------------------------------------------------
  387. msoBarTypeNormal = 0 # Usual toolbar
  388. msoBarTypeMenuBar = 1 # Menu bar
  389. msoBarTypePopup = 2 # Shortcut menu
  390. msoBarTypeStatusBar = 11 # Status bar
  391. msoBarTypeFloater = 12 # Floating window
  392. msoControlButton = 1 # Command button
  393. msoControlPopup = 10 # Popup, submenu
  394. # New Lines
  395. # -----------------------------------------------------------------
  396. vbCr = chr(13)
  397. vbLf = chr(10)
  398. def _NewLine():
  399. if _opsys == 'Windows': return chr(13) + chr(10)
  400. return chr(10)
  401. vbNewLine = _NewLine()
  402. vbTab = chr(9)
  403. # Module types
  404. # -----------------------------------------------------------------
  405. acClassModule = 1
  406. acStandardModule = 0
  407. # (Module) procedure types
  408. # -----------------------------------------------------------------
  409. vbext_pk_Get = 1 # A Property Get procedure
  410. vbext_pk_Let = 2 # A Property Let procedure
  411. vbext_pk_Proc = 0 # A Sub or Function procedure
  412. vbext_pk_Set = 3 # A Property Set procedure
  413. COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER, THISDATABASEDOCUMENT = None, None, None, None
  414. def _ErrorHandler(type, value, tb):
  415. '''
  416. Is the function to be set as new sys.excepthook to bypass the standard error handler
  417. Derived from https://stackoverflow.com/questions/31949760/how-to-limit-python-traceback-to-specific-files
  418. Handler removes traces pointing to methods located in access2base.py when error is due to a user programming error
  419. sys.excepthook = _ErrorHandler
  420. NOT APPLIED YET
  421. '''
  422. def check_file(name):
  423. return 'access2base.py' not in name
  424. show = (fs for fs in traceback.extract_tb(tb) if check_file(fs.filename))
  425. fmt = traceback.format_list(show) + traceback.format_exception_only(type, value)
  426. print(''.join(fmt), end = '', file = sys.stderr)
  427. # Reset to standard handler
  428. sys.excepthook = sys.__excepthook__
  429. def A2BConnect(hostname = '', port = 0):
  430. """
  431. To be called explicitly by user scripts when Python process runs outside the LibreOffice process.
  432. LibreOffice started as (Linux):
  433. ./soffice --accept='socket,host=localhost,port=xxxx;urp;'
  434. Otherwise called implicitly by the current module without arguments
  435. Initializes COMPONENTCONTEXT, SCRIPTPROVIDER and DESKTOP
  436. :param hostname: probably 'localhost' or ''
  437. :param port: port number or 0
  438. :return: None
  439. """
  440. global XSCRIPTCONTEXT, COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER
  441. # Determine COMPONENTCONTEXT, via socket or inside LibreOffice
  442. if len(hostname) > 0 and port > 0: # Explicit connection request via socket
  443. # Code derived from Bridge.py by Alain H. Romedenne
  444. local_context = XSCRIPTCONTEXT.getComponentContext()
  445. resolver = local_context.ServiceManager.createInstanceWithContext(
  446. 'com.sun.star.bridge.UnoUrlResolver', local_context)
  447. try:
  448. conn = 'socket,host=%s,port=%d' % (hostname, port)
  449. connection_url = 'uno:%s;urp;StarOffice.ComponentContext' % conn
  450. established_context = resolver.resolve(connection_url)
  451. except Exception: # thrown when LibreOffice specified instance isn't started
  452. raise ConnectionError('Connection to LibreOffice failed (host = ' + hostname + ', port = ' + str(port) + ')')
  453. COMPONENTCONTEXT = established_context
  454. DESKTOP = None
  455. elif len(hostname) == 0 and port == 0: # Usual interactive mode
  456. COMPONENTCONTEXT = XSCRIPTCONTEXT.getComponentContext()
  457. DESKTOP = COMPONENTCONTEXT.ServiceManager.createInstanceWithContext( 'com.sun.star.frame.Desktop', COMPONENTCONTEXT)
  458. else:
  459. raise SystemExit('The invocation of A2BConnect() has invalid arguments')
  460. # Determine SCRIPTPROVIDER
  461. servicemanager = COMPONENTCONTEXT.ServiceManager
  462. masterscript = servicemanager.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", COMPONENTCONTEXT)
  463. SCRIPTPROVIDER = masterscript.createScriptProvider("")
  464. Script = _A2B.xScript('TraceLog', 'Trace') # Don't use invokeMethod() to force reset of error stack
  465. Script.invoke(('===>', 'Python wrapper loaded V.' + _VERSION, False), (), ())
  466. return None
  467. class _A2B(object, metaclass = _Singleton):
  468. """
  469. Collection of helper functions implementing the protocol between Python and Basic
  470. Read comments in PythonWrapper Basic function
  471. """
  472. @classmethod
  473. def BasicObject(cls, objectname):
  474. objs = {'COLLECTION': _Collection
  475. , 'COMMANDBAR': _CommandBar
  476. , 'COMMANDBARCONTROL': _CommandBarControl
  477. , 'CONTROL': _Control
  478. , 'DATABASE': _Database
  479. , 'DIALOG': _Dialog
  480. , 'EVENT': _Event
  481. , 'FIELD': _Field
  482. , 'FORM': _Form
  483. , 'MODULE': _Module
  484. , 'OPTIONGROUP': _OptionGroup
  485. , 'PROPERTY': _Property
  486. , 'QUERYDEF': _QueryDef
  487. , 'RECORDSET': _Recordset
  488. , 'SUBFORM': _SubForm
  489. , 'TABLEDEF': _TableDef
  490. , 'TEMPVAR': _TempVar
  491. }
  492. return objs[objectname]
  493. @classmethod
  494. def xScript(cls, script, module):
  495. """
  496. At first call checks the existence of the Access2Base library
  497. Initializes _LIBRARY with the found library name
  498. First and next calls execute the given script in the given module of the _LIBRARY library
  499. The script and module are presumed to exist
  500. :param script: name of script
  501. :param module: name of module
  502. :return: the script object. NB: the execution is done with the invoke() method applied on the returned object
  503. """
  504. global _LIBRARY
  505. Script = None
  506. def sScript(lib):
  507. return 'vnd.sun.star.script:' + lib + '.' + module + '.' + script + '?language=Basic&location=application'
  508. if _LIBRARY == '':
  509. # Check the availability of the Access2Base library
  510. for lib in ('Access2BaseDev', 'Access2Base'):
  511. try:
  512. if Script == None:
  513. Script = SCRIPTPROVIDER.getScript(sScript(lib))
  514. _LIBRARY = lib
  515. except Exception:
  516. pass
  517. if Script == None:
  518. raise SystemExit('Access2Base basic library not found')
  519. else:
  520. Script = SCRIPTPROVIDER.getScript(sScript(_LIBRARY))
  521. return Script
  522. @classmethod
  523. def A2BErrorCode(cls):
  524. """
  525. Return the Access2Base error stack as a tuple
  526. 0 => error code
  527. 1 => severity level
  528. 2 => short error message
  529. 3 => long error message
  530. """
  531. Script = cls.xScript('TraceErrorCode', 'Trace')
  532. return Script.invoke((), (), ())[0]
  533. @classmethod
  534. def invokeMethod(cls, script, module, *args):
  535. """
  536. Direct call to a named script/module pair with their arguments
  537. If the arguments do not match their definition at the Basic side, a TypeError is raised
  538. :param script: name of script
  539. :param module: name of module
  540. :param args: list of arguments to be passed to the script
  541. :return: the value returned by the script execution
  542. """
  543. if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation
  544. Script = cls.xScript(script, module)
  545. try:
  546. Returned = Script.invoke((args), (), ())[0]
  547. except Exception:
  548. raise TypeError("Access2Base error: method '" + script + "' in Basic module '" + module + "' call error. Check its arguments.")
  549. else:
  550. if Returned == None:
  551. if cls.VerifyNoError(): return None
  552. return Returned
  553. @classmethod
  554. def invokeWrapper(cls, action, basic, script, *args):
  555. """
  556. Call the Basic wrapper to invite it to execute the proposed action on a Basic object
  557. If the arguments do not match their definition at the Basic side, a TypeError is raised
  558. After execution, a check is done if the execution has raised an error within Basic
  559. If yes, a TypeError is raised
  560. :param action: Property Get, Property Let, Property Set, invoke Method or return UNO object
  561. :param basic: the reference of the Basic object, i.e. the index in the array caching the addresses of the objects
  562. conventionally Application = -1 and DoCmd = -2
  563. :param script: the property or method name
  564. :param args: the arguments of the method, if any
  565. :return: the value returned by the execution of the Basic routine
  566. """
  567. if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation
  568. # Intercept special call to Application.Events()
  569. if basic == Application.basicmodule and script == 'Events':
  570. Script = cls.xScript('PythonEventsWrapper', _WRAPPERMODULE)
  571. Returned = Script.invoke((args[0],), (), ())
  572. else:
  573. Script = cls.xScript('PythonWrapper', _WRAPPERMODULE)
  574. NoArgs = '+++NOARGS+++' # Conventional notation for properties/methods without arguments
  575. if len(args) == 0:
  576. args = (action,) + (basic,) + (script,) + (NoArgs,)
  577. else:
  578. args = (action,) + (basic,) + (script,) + args
  579. try:
  580. Returned = Script.invoke((args), (), ())
  581. except Exception:
  582. raise TypeError("Access2Base error: method '" + script + "' call error. Check its arguments.")
  583. if isinstance(Returned[0], tuple):
  584. # Is returned value a reference to a basic object, a scalar or a UNO object ?
  585. if len(Returned[0]) in (3, 4):
  586. if Returned[0][0] == 0: # scalar
  587. return Returned[0][1]
  588. elif Returned[0][0] == 1: # reference to objects cache
  589. basicobject = cls.BasicObject(Returned[0][2])
  590. if len(Returned[0]) == 3:
  591. return basicobject(Returned[0][1], Returned[0][2])
  592. else:
  593. return basicobject(Returned[0][1], Returned[0][2], Returned[0][3])
  594. elif Returned[0][0] == 2: # Null value
  595. return None
  596. else: # Should not happen
  597. return None
  598. else: # UNO object
  599. return Returned[0]
  600. elif Returned[0] == None:
  601. if cls.VerifyNoError(): return None
  602. else: # Should not happen
  603. return Returned[0]
  604. @classmethod
  605. def VerifyNoError(cls):
  606. # has Access2Base generated an error ?
  607. errorstack = cls.A2BErrorCode() # 0 = code, 1 = severity, 2 = short text, 3 = long text
  608. if errorstack[1] in ('ERROR', 'FATAL', 'ABORT'):
  609. raise TypeError('Access2Base error: ' + errorstack[3])
  610. return True
  611. class Application(object, metaclass = _Singleton):
  612. """ Collection of methods located in the Application (Basic) module """
  613. W = _A2B.invokeWrapper
  614. basicmodule = -1
  615. @classmethod
  616. def AllDialogs(cls, dialog = acConstants.Missing):
  617. return cls.W(_vbMethod, cls.basicmodule, 'AllDialogs', dialog)
  618. @classmethod
  619. def AllForms(cls, form = acConstants.Missing):
  620. return cls.W(_vbMethod, cls.basicmodule, 'AllForms', form)
  621. @classmethod
  622. def AllModules(cls, module = acConstants.Missing):
  623. return cls.W(_vbMethod, cls.basicmodule, 'AllModules', module)
  624. @classmethod
  625. def CloseConnection(cls):
  626. return cls.W(_vbMethod, cls.basicmodule, 'CloseConnection')
  627. @classmethod
  628. def CommandBars(cls, bar = acConstants.Missing):
  629. return cls.W(_vbMethod, cls.basicmodule, 'CommandBars', bar)
  630. @classmethod
  631. def CurrentDb(cls):
  632. return cls.W(_vbMethod, cls.basicmodule, 'CurrentDb')
  633. @classmethod
  634. def CurrentUser(cls):
  635. return cls.W(_vbMethod, cls.basicmodule, 'CurrentUser')
  636. @classmethod
  637. def DAvg(cls, expression, domain, criteria = ''):
  638. return cls.W(_vbMethod, cls.basicmodule, 'DAvg', expression, domain, criteria)
  639. @classmethod
  640. def DCount(cls, expression, domain, criteria = ''):
  641. return cls.W(_vbMethod, cls.basicmodule, 'DCount', expression, domain, criteria)
  642. @classmethod
  643. def DLookup(cls, expression, domain, criteria = '', orderclause = ''):
  644. return cls.W(_vbMethod, cls.basicmodule, 'DLookup', expression, domain, criteria, orderclause)
  645. @classmethod
  646. def DMax(cls, expression, domain, criteria = ''):
  647. return cls.W(_vbMethod, cls.basicmodule, 'DMax', expression, domain, criteria)
  648. @classmethod
  649. def DMin(cls, expression, domain, criteria = ''):
  650. return cls.W(_vbMethod, cls.basicmodule, 'DMin', expression, domain, criteria)
  651. @classmethod
  652. def DStDev(cls, expression, domain, criteria = ''):
  653. return cls.W(_vbMethod, cls.basicmodule, 'DStDev', expression, domain, criteria)
  654. @classmethod
  655. def DStDevP(cls, expression, domain, criteria = ''):
  656. return cls.W(_vbMethod, cls.basicmodule, 'DStDevP', expression, domain, criteria)
  657. @classmethod
  658. def DSum(cls, expression, domain, criteria = ''):
  659. return cls.W(_vbMethod, cls.basicmodule, 'DSum', expression, domain, criteria)
  660. @classmethod
  661. def DVar(cls, expression, domain, criteria = ''):
  662. return cls.W(_vbMethod, cls.basicmodule, 'DVar', expression, domain, criteria)
  663. @classmethod
  664. def DVarP(cls, expression, domain, criteria = ''):
  665. return cls.W(_vbMethod, cls.basicmodule, 'DVarP', expression, domain, criteria)
  666. @classmethod
  667. def Events(cls, event):
  668. return cls.W(_vbMethod, cls.basicmodule, 'Events', event)
  669. @classmethod
  670. def Forms(cls, form = acConstants.Missing):
  671. return cls.W(_vbMethod, cls.basicmodule, 'Forms', form)
  672. @classmethod
  673. def getObject(cls, shortcut):
  674. return cls.W(_vbMethod, cls.basicmodule, 'getObject', shortcut)
  675. GetObject = getObject
  676. @classmethod
  677. def getValue(cls, shortcut):
  678. return cls.W(_vbMethod, cls.basicmodule, 'getValue', shortcut)
  679. GetValue = getValue
  680. @classmethod
  681. def HtmlEncode(cls, string, length = 0):
  682. return cls.W(_vbMethod, cls.basicmodule, 'HtmlEncode', string, length)
  683. @classmethod
  684. def OpenConnection(cls, thisdatabasedocument = acConstants.Missing):
  685. global THISDATABASEDOCUMENT
  686. if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation
  687. if DESKTOP != None:
  688. THISDATABASEDOCUMENT = DESKTOP.getCurrentComponent()
  689. return _A2B.invokeMethod('OpenConnection', 'Application', THISDATABASEDOCUMENT)
  690. @classmethod
  691. def OpenDatabase(cls, connectionstring, username = '', password = '', readonly = False):
  692. return cls.W(_vbMethod, cls.basicmodule, 'OpenDatabase', connectionstring, username
  693. , password, readonly)
  694. @classmethod
  695. def ProductCode(cls):
  696. return cls.W(_vbMethod, cls.basicmodule, 'ProductCode')
  697. @classmethod
  698. def setValue(cls, shortcut, value):
  699. return cls.W(_vbMethod, cls.basicmodule, 'setValue', shortcut, value)
  700. SetValue = setValue
  701. @classmethod
  702. def SysCmd(cls, action, text = '', value = -1):
  703. return cls.W(_vbMethod, cls.basicmodule, 'SysCmd', action, text, value)
  704. @classmethod
  705. def TempVars(cls, var = acConstants.Missing):
  706. return cls.W(_vbMethod, cls.basicmodule, 'TempVars', var)
  707. @classmethod
  708. def Version(cls):
  709. return cls.W(_vbMethod, cls.basicmodule, 'Version')
  710. class DoCmd(object, metaclass = _Singleton):
  711. """ Collection of methods located in the DoCmd (Basic) module """
  712. W = _A2B.invokeWrapper
  713. basicmodule = -2
  714. @classmethod
  715. def ApplyFilter(cls, filter = '', sqlwhere = '', controlname = ''):
  716. return cls.W(_vbMethod, cls.basicmodule, 'ApplyFilter', filter, sqlwhere, controlname)
  717. @classmethod
  718. def Close(cls, objecttype, objectname, save = acConstants.acSavePrompt):
  719. return cls.W(_vbMethod, cls.basicmodule, 'Close', objecttype, objectname, save)
  720. @classmethod
  721. def CopyObject(cls, sourcedatabase, newname, sourceobjecttype, sourceobjectname): # 1st argument must be set
  722. return cls.W(_vbMethod, cls.basicmodule, 'CopyObject', sourcedatabase, newname, sourceobjecttype
  723. , sourceobjectname)
  724. @classmethod
  725. def FindNext(cls):
  726. return cls.W(_vbMethod, cls.basicmodule, 'FindNext')
  727. @classmethod
  728. def FindRecord(cls, findwhat, match = acConstants.acEntire, matchcase = False, search = acConstants.acSearchAll
  729. , searchasformatted = False, onlycurrentfield = acConstants.acCurrent, findfirst = True):
  730. return cls.W(_vbMethod, cls.basicmodule, 'FindRecord', findwhat, match, matchcase, search
  731. , searchasformatted, onlycurrentfield, findfirst)
  732. @classmethod
  733. def GetHiddenAttribute(cls, objecttype, objectname = ''):
  734. return cls.W(_vbMethod, cls.basicmodule, 'GetHiddenAttribute', objecttype, objectname)
  735. @classmethod
  736. def GoToControl(cls, controlname):
  737. return cls.W(_vbMethod, cls.basicmodule, 'GoToControl', controlname)
  738. @classmethod
  739. def GoToRecord(cls, objecttype = acConstants.acActiveDataObject, objectname = '', record = acConstants.acNext
  740. , offset = 1):
  741. return cls.W(_vbMethod, cls.basicmodule, 'GoToRecord', objecttype, objectname, record, offset)
  742. @classmethod
  743. def Maximize(cls):
  744. return cls.W(_vbMethod, cls.basicmodule, 'Maximize')
  745. @classmethod
  746. def Minimize(cls):
  747. return cls.W(_vbMethod, cls.basicmodule, 'Minimize')
  748. @classmethod
  749. def MoveSize(cls, left = -1, top = -1, width = -1, height = -1):
  750. return cls.W(_vbMethod, cls.basicmodule, 'MoveSize', left, top, width, height)
  751. @classmethod
  752. def OpenForm(cls, formname, view = acConstants.acNormal, filter = '', wherecondition = ''
  753. , datamode = acConstants.acFormEdit, windowmode = acConstants.acWindowNormal, openargs = ''):
  754. return cls.W(_vbMethod, cls.basicmodule, 'OpenForm', formname, view, filter, wherecondition
  755. , datamode, windowmode, openargs)
  756. @classmethod
  757. def OpenQuery(cls, queryname, view = acConstants.acNormal, datamode = acConstants.acEdit):
  758. return cls.W(_vbMethod, cls.basicmodule, 'OpenQuery', queryname, view, datamode)
  759. @classmethod
  760. def OpenReport(cls, queryname, view = acConstants.acNormal):
  761. return cls.W(_vbMethod, cls.basicmodule, 'OpenReport', queryname, view)
  762. @classmethod
  763. def OpenSQL(cls, sql, option = -1):
  764. return cls.W(_vbMethod, cls.basicmodule, 'OpenSQL', sql, option)
  765. @classmethod
  766. def OpenTable(cls, tablename, view = acConstants.acNormal, datamode = acConstants.acEdit):
  767. return cls.W(_vbMethod, cls.basicmodule, 'OpenTable', tablename, view, datamode)
  768. @classmethod
  769. def OutputTo(cls, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = ''
  770. , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint):
  771. if objecttype == acConstants.acOutputForm: encoding = 0
  772. return cls.W(_vbMethod, cls.basicmodule, 'OutputTo', objecttype, objectname, outputformat
  773. , outputfile, autostart, templatefile, encoding, quality)
  774. @classmethod
  775. def Quit(cls):
  776. return cls.W(_vbMethod, cls.basicmodule, 'Quit')
  777. @classmethod
  778. def RunApp(cls, commandline):
  779. return cls.W(_vbMethod, cls.basicmodule, 'RunApp', commandline)
  780. @classmethod
  781. def RunCommand(cls, command):
  782. return cls.W(_vbMethod, cls.basicmodule, 'RunCommand', command)
  783. @classmethod
  784. def RunSQL(cls, SQL, option = -1):
  785. return cls.W(_vbMethod, cls.basicmodule, 'RunSQL', SQL, option)
  786. @classmethod
  787. def SelectObject(cls, objecttype, objectname = '', indatabasewindow = False):
  788. return cls.W(_vbMethod, cls.basicmodule, 'SelectObject', objecttype, objectname, indatabasewindow)
  789. @classmethod
  790. def SendObject(cls, objecttype = acConstants.acSendNoObject, objectname = '', outputformat = '', to = '', cc = ''
  791. , bcc = '', subject = '', messagetext = '', editmessage = True, templatefile = ''):
  792. return cls.W(_vbMethod, cls.basicmodule, 'SendObject', objecttype, objectname, outputformat, to, cc
  793. , bcc, subject, messagetext, editmessage, templatefile)
  794. @classmethod
  795. def SetHiddenAttribute(cls, objecttype, objectname = '', hidden = True):
  796. return cls.W(_vbMethod, cls.basicmodule, 'SetHiddenAttribute', objecttype, objectname, hidden)
  797. @classmethod
  798. def SetOrderBy(cls, orderby = '', controlname = ''):
  799. return cls.W(_vbMethod, cls.basicmodule, 'SetOrderBy', orderby, controlname)
  800. @classmethod
  801. def ShowAllRecords(cls):
  802. return cls.W(_vbMethod, cls.basicmodule, 'ShowAllRecords')
  803. class Basic(object, metaclass = _Singleton):
  804. """ Collection of helper functions having the same behaviour as their Basic counterparts """
  805. M = _A2B.invokeMethod
  806. @classmethod
  807. def ConvertFromUrl(cls, url):
  808. return cls.M('PyConvertFromUrl', _WRAPPERMODULE, url)
  809. @classmethod
  810. def ConvertToUrl(cls, file):
  811. return cls.M('PyConvertToUrl', _WRAPPERMODULE, file)
  812. @classmethod
  813. def CreateUnoService(cls, servicename):
  814. return cls.M('PyCreateUnoService', _WRAPPERMODULE, servicename)
  815. @classmethod
  816. def DateAdd(cls, add, count, datearg):
  817. if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat()
  818. dateadd = cls.M('PyDateAdd', _WRAPPERMODULE, add, count, datearg)
  819. return datetime.datetime.strptime(dateadd, acConstants.FromIsoFormat)
  820. @classmethod
  821. def DateDiff(cls, add, date1, date2, weekstart = 1, yearstart = 1):
  822. if isinstance(date1, datetime.datetime): date1 = date1.isoformat()
  823. if isinstance(date2, datetime.datetime): date2 = date2.isoformat()
  824. return cls.M('PyDateDiff', _WRAPPERMODULE, add, date1, date2, weekstart, yearstart)
  825. @classmethod
  826. def DatePart(cls, add, datearg, weekstart = 1, yearstart = 1):
  827. if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat()
  828. return cls.M('PyDatePart', _WRAPPERMODULE, add, datearg, weekstart, yearstart)
  829. @classmethod
  830. def DateValue(cls, datestring):
  831. datevalue = cls.M('PyDateValue', _WRAPPERMODULE, datestring)
  832. return datetime.datetime.strptime(datevalue, acConstants.FromIsoFormat)
  833. @classmethod
  834. def Format(cls, value, format = None):
  835. if isinstance(value, (datetime.datetime, datetime.date, datetime.time, )):
  836. value = value.isoformat()
  837. return cls.M('PyFormat', _WRAPPERMODULE, value, format)
  838. @classmethod
  839. def GetGUIType(cls):
  840. return cls.M('PyGetGUIType', _WRAPPERMODULE)
  841. @staticmethod
  842. def GetPathSeparator():
  843. return os.sep
  844. @classmethod
  845. def GetSystemTicks(cls):
  846. return cls.M('PyGetSystemTicks', _WRAPPERMODULE)
  847. @classmethod
  848. def MsgBox(cls, text, type = None, dialogtitle = None):
  849. return cls.M('PyMsgBox', _WRAPPERMODULE, text, type, dialogtitle)
  850. class GlobalScope(object, metaclass = _Singleton):
  851. @classmethod
  852. def BasicLibraries(cls):
  853. return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Basic')
  854. @classmethod
  855. def DialogLibraries(self):
  856. return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Dialog')
  857. @classmethod
  858. def InputBox(cls, text, title = None, default = None, xpos = None, ypos = None):
  859. return cls.M('PyInputBox', _WRAPPERMODULE, text, title, default, xpos, ypos)
  860. @staticmethod
  861. def Now():
  862. return datetime.datetime.now()
  863. @staticmethod
  864. def RGB(red, green, blue):
  865. return int('%02x%02x%02x' % (red, green, blue), 16)
  866. @classmethod
  867. def Timer(cls):
  868. return cls.M('PyTimer', _WRAPPERMODULE)
  869. @staticmethod
  870. def Xray(myObject):
  871. xrayscript = 'vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application'
  872. xScript = SCRIPTPROVIDER.getScript(xrayscript)
  873. xScript.invoke((myObject,), (), ())
  874. return
  875. class _BasicObject(object):
  876. """
  877. Parent class of Basic objects
  878. Each subclass is identified by its classProperties:
  879. dictionary with keys = allowed properties, value = True if editable or False
  880. Each instance is identified by its
  881. - reference in the cache managed by Basic
  882. - type ('DATABASE', 'COLLECTION', ...)
  883. - name (form, control, ... name) - may be blank
  884. Properties are got and set following next strategy:
  885. 1. Property names are controlled strictly ('Value' and not 'value')
  886. 2. Getting a property value for the first time is always done via a Basic call
  887. 3. Next occurrences are fetched from the Python dictionary of the instance if the property is read-only, otherwise via a Basic call
  888. 4. Methods output might force the deletion of a property from the dictionary ('MoveNext' changes 'BOF' and 'EOF' properties)
  889. 5. Setting a property value is done via a Basic call, except if self.internal == True
  890. """
  891. W = _A2B.invokeWrapper
  892. internal_attributes = ('objectreference', 'objecttype', 'name', 'internal')
  893. def __init__(self, reference = -1, objtype = None, name = ''):
  894. self.objectreference = reference # reference in the cache managed by Basic
  895. self.objecttype = objtype # ('DATABASE', 'COLLECTION', ...)
  896. self.name = name # '' when no name
  897. self.internal = False # True to exceptionally allow assigning a new value to a read-only property
  898. self.localProperties = ()
  899. def __getattr__(self, name):
  900. if name in ('classProperties', 'localProperties'):
  901. pass
  902. elif name in self.classProperties:
  903. # Get Property from Basic
  904. return self.W(_vbGet, self.objectreference, name)
  905. # Usual attributes getter
  906. return super(_BasicObject, self).__getattribute__(name)
  907. def __setattr__(self, name, value):
  908. if name in ('classProperties', 'localProperties'):
  909. pass
  910. elif name in self.classProperties:
  911. if self.internal: # internal = True forces property setting even if property is read-only
  912. pass
  913. elif self.classProperties[name] == True: # True == Editable
  914. self.W(_vbLet, self.objectreference, name, value)
  915. else:
  916. raise AttributeError("type object '" + self.objecttype + "' has no editable attribute '" + name + "'")
  917. elif name[0:2] == '__' or name in self.internal_attributes or name in self.localProperties:
  918. pass
  919. else:
  920. raise AttributeError("type object '" + self.objecttype + "' has no attribute '" + name + "'")
  921. object.__setattr__(self, name, value)
  922. return
  923. def __repr__(self):
  924. repr = "Basic object (type='" + self.objecttype + "', index=" + str(self.objectreference)
  925. if len(self.name) > 0: repr += ", name='" + self.name + "'"
  926. return repr + ")"
  927. def _Reset(self, propertyname, basicreturn = None):
  928. """ force new value or erase properties from dictionary (done to optimize calls to Basic scripts) """
  929. if propertyname in ('BOF', 'EOF'):
  930. # After a Move method invocation on a Recordset object, BOF or EOF likely to be got soon
  931. if isinstance(basicreturn, int):
  932. self.internal = True
  933. # f.i. basicreturn = 0b10 means: BOF = True, EOF = False
  934. self.BOF = basicreturn in (2, 3, -2, -3)
  935. self.EOF = basicreturn in (1, 3, -1, -3)
  936. self.internal = False
  937. return ( basicreturn >= 0 )
  938. else:
  939. # Suppress possibly invalid property values: e.g. RecordCount after Delete applied on Recordset object
  940. if property in self.__dict__:
  941. del(self.propertyname)
  942. return basicreturn
  943. @property
  944. def Name(self): return self.name
  945. @property
  946. def ObjectType(self): return self.objecttype
  947. def Dispose(self):
  948. return self.W(_vbMethod, self.objectreference, 'Dispose')
  949. def getProperty(self, propertyname, index = acConstants.Missing):
  950. return self.W(_vbMethod, self.objectreference, 'getProperty', propertyname, index)
  951. GetProperty = getProperty
  952. def hasProperty(self, propertyname):
  953. return propertyname in tuple(self.classProperties.keys())
  954. HasProperty = hasProperty
  955. def Properties(self, index = acConstants.Missing):
  956. return self.W(_vbMethod, self.objectreference, 'Properties', index)
  957. def setProperty(self, propertyname, value, index = acConstants.Missing):
  958. if self.hasProperty(propertyname):
  959. if self.W(_vbMethod, self.objectreference, 'setProperty', propertyname, value, index):
  960. return self.__setattr__(propertyname, value)
  961. raise AttributeError("type object '" + self.objecttype + "' has no editable attribute '" + propertyname + "'")
  962. SetProperty = setProperty
  963. class _Collection(_BasicObject):
  964. """ Collection object built as a Python iterator """
  965. classProperties = dict(Count = False)
  966. def __init__(self, reference = -1, objtype = None):
  967. super().__init__(reference, objtype)
  968. self.localProperties = ('count', 'index')
  969. self.count = self.Count
  970. self.index = 0
  971. def __iter__(self):
  972. self.index = 0
  973. return self
  974. def __next__(self):
  975. if self.index >= self.count:
  976. raise StopIteration
  977. next = self.Item(self.index)
  978. self.index = self.index + 1
  979. return next
  980. def __len__(self):
  981. return self.count
  982. def Add(self, table, value = acConstants.Missing):
  983. if isinstance(table, _BasicObject): # Add method applied to a TABLEDEFS collection
  984. return self.W(_vbMethod, self.objectreference, 'Add', table.objectreference)
  985. else: # Add method applied to a TEMPVARS collection
  986. add = self.W(_vbMethod, self.objectreference, 'Add', table, value)
  987. self.count = self.Count
  988. return add
  989. def Delete(self, name):
  990. return self.W(_vbMethod, self.objectreference, 'Delete', name)
  991. def Item(self, index):
  992. return self.W(_vbMethod, self.objectreference, 'Item', index)
  993. def Remove(self, tempvarname):
  994. remove = self.W(_vbMethod, self.objectreference, 'Remove', tempvarname)
  995. self.count = self.Count
  996. return remove
  997. def RemoveAll(self):
  998. remove = self.W(_vbMethod, self.objectreference, 'RemoveAll')
  999. self.count = self.Count
  1000. return remove
  1001. class _CommandBar(_BasicObject):
  1002. classProperties = dict(BuiltIn = False, Parent = False, Visible = True)
  1003. def CommandBarControls(self, index = acConstants.Missing):
  1004. return self.W(_vbMethod, self.objectreference, 'CommandBarControls', index)
  1005. def Reset(self):
  1006. return self.W(_vbMethod, self.objectreference, 'Reset')
  1007. class _CommandBarControl(_BasicObject):
  1008. classProperties = dict(BeginGroup = False, BuiltIn = False, Caption = True, Index = False, OnAction = True
  1009. , Parent = False, TooltipText = True, Type = False, Visible = True)
  1010. def Execute(self):
  1011. return self.W(_vbMethod, self.objectreference, 'Execute')
  1012. class _Control(_BasicObject):
  1013. classProperties = dict(BackColor = True, BorderColor = True, BorderStyle = True, Cancel = True, Caption = True
  1014. , ControlSource = False, ControlTipText = True, ControlType = False, Default = True
  1015. , DefaultValue = True, Enabled = True, FontBold = True, FontItalic = True, FontName = True
  1016. , FontSize = True, FontUnderline = True, FontWeight = True, ForeColor = True, Form = False
  1017. , Format = True, ItemData = False, ListCount = False, ListIndex = True, Locked = True, MultiSelect = True
  1018. , OnActionPerformed = True, OnAdjustmentValueChanged = True, OnApproveAction = True
  1019. , OnApproveReset = True, OnApproveUpdate = True, OnChanged = True, OnErrorOccurred = True
  1020. , OnFocusGained = True, OnFocusLost = True, OnItemStateChanged = True, OnKeyPressed = True
  1021. , OnKeyReleased = True, OnMouseDragged = True, OnMouseEntered = True, OnMouseExited = True
  1022. , OnMouseMoved = True, OnMousePressed = True, OnMouseReleased = True, OnResetted = True, OnTextChanged = True
  1023. , OnUpdated = True, OptionValue = False, Page = False, Parent = False, Picture = True, Required = True
  1024. , RowSource = True, RowSourceType = True, Selected = True, SelLength = True, SelStart = True, SelText = True
  1025. , SubType = False, TabIndex = True, TabStop = True, Tag = True, Text = False, TextAlign = True
  1026. , TripleState = True, Value = True, Visible = True
  1027. )
  1028. @property
  1029. def BoundField(self): return self.W(_vbUNO, self.objectreference, 'BoundField')
  1030. @property
  1031. def ControlModel(self): return self.W(_vbUNO, self.objectreference, 'ControlModel')
  1032. @property
  1033. def ControlView(self): return self.W(_vbUNO, self.objectreference, 'ControlView')
  1034. @property
  1035. def LabelControl(self): return self.W(_vbUNO, self.objectreference, 'LabelControl')
  1036. def AddItem(self, value, index = -1):
  1037. basicreturn = self.W(_vbMethod, self.objectreference, 'AddItem', value, index)
  1038. self._Reset('ItemData')
  1039. self._Reset('ListCount')
  1040. return basicreturn
  1041. def Controls(self, index = acConstants.Missing):
  1042. return self.W(_vbMethod, self.objectreference, 'Controls', index)
  1043. # Overrides method in parent class: list of properties is strongly control type dependent
  1044. def hasProperty(self, propertyname):
  1045. return self.W(_vbMethod, self.objectreference, 'hasProperty', propertyname)
  1046. HasProperty = hasProperty
  1047. def RemoveItem(self, index):
  1048. basicreturn = self.W(_vbMethod, self.objectreference, 'RemoveItem', index)
  1049. self._Reset('ItemData')
  1050. self._Reset('ListCount')
  1051. return basicreturn
  1052. def Requery(self):
  1053. return self.W(_vbMethod, self.objectreference, 'Requery')
  1054. def SetSelected(self, value, index):
  1055. return self.W(_vbMethod, self.objectreference, 'SetSelected', value, index)
  1056. def SetFocus(self):
  1057. return self.W(_vbMethod, self.objectreference, 'SetFocus')
  1058. class _Database(_BasicObject):
  1059. classProperties = dict(Connect = False, OnCreate = True
  1060. , OnFocus = True, OnLoad = True, OnLoadFinished = True, OnModifyChanged = True, OnNew = True
  1061. , OnPrepareUnload = True, OnPrepareViewClosing = True, OnSave = True, OnSaveAs = True
  1062. , OnSaveAsDone = True, OnSaveAsFailed = True, OnSaveDone = True, OnSaveFailed = True
  1063. , OnSubComponentClosed = True, OnSubComponentOpened = True, OnTitleChanged = True, OnUnfocus = True
  1064. , OnUnload = True, OnViewClosed = True, OnViewCreated = True, Version = False
  1065. )
  1066. @property
  1067. def Connection(self): return self.W(_vbUNO, self.objectreference, 'Connection')
  1068. @property
  1069. def Document(self): return self.W(_vbUNO, self.objectreference, 'Document')
  1070. @property
  1071. def MetaData(self): return self.W(_vbUNO, self.objectreference, 'MetaData')
  1072. def Close(self):
  1073. return self.W(_vbMethod, self.objectreference, 'Close')
  1074. def CloseAllRecordsets(self):
  1075. return self.W(_vbMethod, self.objectreference, 'CloseAllRecordsets')
  1076. def CreateQueryDef(self, name, sqltext, option = -1):
  1077. return self.W(_vbMethod, self.objectreference, 'CreateQueryDef', name, sqltext, option)
  1078. def CreateTableDef(self, name):
  1079. return self.W(_vbMethod, self.objectreference, 'CreateTableDef', name)
  1080. def DAvg(self, expression, domain, criteria = ''):
  1081. return self.W(_vbMethod, self.objectreference, 'DAvg', expression, domain, criteria)
  1082. def DCount(self, expression, domain, criteria = ''):
  1083. return self.W(_vbMethod, self.objectreference, 'DCount', expression, domain, criteria)
  1084. def DLookup(self, expression, domain, criteria = '', orderclause = ''):
  1085. return self.W(_vbMethod, self.objectreference, 'DLookup', expression, domain, criteria, orderclause)
  1086. def DMax(self, expression, domain, criteria = ''):
  1087. return self.W(_vbMethod, self.objectreference, 'DMax', expression, domain, criteria)
  1088. def DMin(self, expression, domain, criteria = ''):
  1089. return self.W(_vbMethod, self.objectreference, 'DMin', expression, domain, criteria)
  1090. def DStDev(self, expression, domain, criteria = ''):
  1091. return self.W(_vbMethod, self.objectreference, 'DStDev', expression, domain, criteria)
  1092. def DStDevP(self, expression, domain, criteria = ''):
  1093. return self.W(_vbMethod, self.objectreference, 'DStDevP', expression, domain, criteria)
  1094. def DVar(self, expression, domain, criteria = ''):
  1095. return self.W(_vbMethod, self.objectreference, 'DVar', expression, domain, criteria)
  1096. def DVarP(self, expression, domain, criteria = ''):
  1097. return self.W(_vbMethod, self.objectreference, 'DVarP', expression, domain, criteria)
  1098. def OpenRecordset(self, source, type = -1, option = -1, lockedit = -1):
  1099. return self.W(_vbMethod, self.objectreference, 'OpenRecordset', source, type, option, lockedit)
  1100. def OpenSQL(self, SQL, option = -1):
  1101. return self.W(_vbMethod, self.objectreference, 'OpenSQL', SQL, option)
  1102. def OutputTo(self, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = ''
  1103. , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint):
  1104. if objecttype == acConstants.acOutputForm: encoding = 0
  1105. return self.W(_vbMethod, self.objectreference, 'OutputTo', objecttype, objectname, outputformat, outputfile
  1106. , autostart, templatefile, encoding, quality)
  1107. def QueryDefs(self, index = acConstants.Missing):
  1108. return self.W(_vbMethod, self.objectreference, 'QueryDefs', index)
  1109. def Recordsets(self, index = acConstants.Missing):
  1110. return self.W(_vbMethod, self.objectreference, 'Recordsets', index)
  1111. def RunSQL(self, SQL, option = -1):
  1112. return self.W(_vbMethod, self.objectreference, 'RunSQL', SQL, option)
  1113. def TableDefs(self, index = acConstants.Missing):
  1114. return self.W(_vbMethod, self.objectreference, 'TableDefs', index)
  1115. class _Dialog(_BasicObject):
  1116. classProperties = dict(Caption = True, Height = True, IsLoaded = False, OnFocusGained = True
  1117. , OnFocusLost = True, OnKeyPressed = True, OnKeyReleased = True, OnMouseDragged = True
  1118. , OnMouseEntered = True, OnMouseExited = True, OnMouseMoved = True, OnMousePressed = True
  1119. , OnMouseReleased = True, Page = True, Parent = False, Visible = True, Width = True
  1120. )
  1121. @property
  1122. def UnoDialog(self): return self.W(_vbUNO, self.objectreference, 'UnoDialog')
  1123. def EndExecute(self, returnvalue):
  1124. return self.W(_vbMethod, self.objectreference, 'EndExecute', returnvalue)
  1125. def Execute(self):
  1126. return self.W(_vbMethod, self.objectreference, 'Execute')
  1127. def Move(self, left = -1, top = -1, width = -1, height = -1):
  1128. return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height)
  1129. def OptionGroup(self, groupname):
  1130. return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname)
  1131. def Start(self):
  1132. return self.W(_vbMethod, self.objectreference, 'Start')
  1133. def Terminate(self):
  1134. return self.W(_vbMethod, self.objectreference, 'Terminate')
  1135. class _Event(_BasicObject):
  1136. classProperties = dict(ButtonLeft = False, ButtonMiddle = False, ButtonRight = False, ClickCount = False
  1137. , ContextShortcut = False, EventName = False, EventType = False, FocusChangeTemporary = False
  1138. , KeyAlt = False, KeyChar = False, KeyCode = False, KeyCtrl = False, KeyFunction = False, KeyShift = False
  1139. , Recommendation = False, RowChangeAction = False, Source = False, SubComponentName = False
  1140. , SubComponentType = False, XPos = False, YPos = False
  1141. )
  1142. class _Field(_BasicObject):
  1143. classProperties = dict(DataType = False, DataUpdatable = False, DbType = False, DefaultValue = True
  1144. , Description = True, FieldSize = False, Size = False, Source = False
  1145. , SourceField = False, SourceTable = False, TypeName = False, Value = True
  1146. )
  1147. @property
  1148. def Column(self): return self.W(_vbUNO, self.objectreference, 'Column')
  1149. def AppendChunk(self, value):
  1150. return self.W(_vbMethod, self.objectreference, 'AppendChunk', value)
  1151. def GetChunk(self, offset, numbytes):
  1152. return self.W(_vbMethod, self.objectreference, 'GetChunk', offset, numbytes)
  1153. def ReadAllBytes(self, file):
  1154. return self.W(_vbMethod, self.objectreference, 'ReadAllBytes', file)
  1155. def ReadAllText(self, file):
  1156. return self.W(_vbMethod, self.objectreference, 'ReadAllText', file)
  1157. def WriteAllBytes(self, file):
  1158. return self.W(_vbMethod, self.objectreference, 'WriteAllBytes', file)
  1159. def WriteAllText(self, file):
  1160. return self.W(_vbMethod, self.objectreference, 'WriteAllText', file)
  1161. class _Form(_BasicObject):
  1162. classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, Bookmark = True
  1163. , Caption = True, CurrentRecord = True, Filter = True, FilterOn = True, Height = True
  1164. , IsLoaded = False, OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True
  1165. , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True
  1166. , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True
  1167. , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OpenArgs = False, OrderBy = True
  1168. , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True
  1169. , Width = True
  1170. )
  1171. @property
  1172. def Component(self): return self.W(_vbUNO, self.objectreference, 'Component')
  1173. @property
  1174. def ContainerWindow(self): return self.W(_vbUNO, self.objectreference, 'ContainerWindow')
  1175. @property
  1176. def DatabaseForm(self): return self.W(_vbUNO, self.objectreference, 'DatabaseForm')
  1177. def Close(self):
  1178. return self.W(_vbMethod, self.objectreference, 'Close')
  1179. def Controls(self, index = acConstants.Missing):
  1180. return self.W(_vbMethod, self.objectreference, 'Controls', index)
  1181. def Move(self, left = -1, top = -1, width = -1, height = -1):
  1182. return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height)
  1183. def OptionGroup(self, groupname):
  1184. return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname)
  1185. def Refresh(self):
  1186. return self.W(_vbMethod, self.objectreference, 'Refresh')
  1187. def Requery(self):
  1188. return self.W(_vbMethod, self.objectreference, 'Requery')
  1189. def SetFocus(self):
  1190. return self.W(_vbMethod, self.objectreference, 'SetFocus')
  1191. class _Module(_BasicObject):
  1192. classProperties = dict(CountOfDeclarationLines = False, CountOfLines = False, Type = False)
  1193. def __init__(self, reference = -1, objtype = None, name = ''):
  1194. super().__init__(reference, objtype, name)
  1195. self.localProperties = ('startline', 'startcolumn', 'endline', 'endcolumn', 'prockind')
  1196. def Find(self, target, startline, startcolumn, endline, endcolumn, wholeword = False
  1197. , matchcase = False, patternsearch = False):
  1198. Returned = self.W(_vbMethod, self.objectreference, 'Find', target, startline, startcolumn, endline
  1199. , endcolumn, wholeword, matchcase, patternsearch)
  1200. if isinstance(Returned, tuple):
  1201. if Returned[0] == True and len(Returned) == 5:
  1202. self.startline = Returned[1]
  1203. self.startcolumn = Returned[2]
  1204. self.endline = Returned[3]
  1205. self.endcolumn = Returned[4]
  1206. return Returned[0]
  1207. return Returned
  1208. def Lines(self, line, numlines):
  1209. return self.W(_vbMethod, self.objectreference, 'Lines', line, numlines)
  1210. def ProcBodyLine(self, procname, prockind):
  1211. return self.W(_vbMethod, self.objectreference, 'ProcBodyLine', procname, prockind)
  1212. def ProcCountLines(self, procname, prockind):
  1213. return self.W(_vbMethod, self.objectreference, 'ProcCountLines', procname, prockind)
  1214. def ProcOfLine(self, line, prockind):
  1215. Returned = self.W(_vbMethod, self.objectreference, 'ProcOfLine', line, prockind)
  1216. if isinstance(Returned, tuple):
  1217. if len(Returned) == 2:
  1218. self.prockind = Returned[1]
  1219. return Returned[0]
  1220. return Returned
  1221. def ProcStartLine(self, procname, prockind):
  1222. return self.W(_vbMethod, self.objectreference, 'ProcStartLine', procname, prockind)
  1223. class _OptionGroup(_BasicObject):
  1224. classProperties = dict(Count = False, Value = True)
  1225. def Controls(self, index = acConstants.Missing):
  1226. return self.W(_vbMethod, self.objectreference, 'Controls', index)
  1227. class _Property(_BasicObject):
  1228. classProperties = dict(Value = True)
  1229. class _QueryDef(_BasicObject):
  1230. classProperties = dict(SQL = True, Type = False)
  1231. @property
  1232. def Query(self): return self.W(_vbUNO, self.objectreference, 'Query')
  1233. def Execute(self, options = acConstants.Missing):
  1234. return self.W(_vbMethod, self.objectreference, 'Execute', options)
  1235. def Fields(self, index = acConstants.Missing):
  1236. return self.W(_vbMethod, self.objectreference, 'Fields', index)
  1237. def OpenRecordset(self, type = -1, option = -1, lockedit = -1):
  1238. return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit)
  1239. class _Recordset(_BasicObject):
  1240. classProperties = dict(AbsolutePosition = True, BOF = False, Bookmark = True, Bookmarkable = False
  1241. , EditMode = False, EOF = False, Filter = True, RecordCount = False
  1242. )
  1243. @property
  1244. def RowSet(self): return self.W(_vbUNO, self.objectreference, 'RowSet')
  1245. def AddNew(self):
  1246. return self.W(_vbMethod, self.objectreference, 'AddNew')
  1247. def CancelUpdate(self):
  1248. return self.W(_vbMethod, self.objectreference, 'CancelUpdate')
  1249. def Clone(self):
  1250. return self.W(_vbMethod, self.objectreference, 'Clone')
  1251. def Close(self):
  1252. return self.W(_vbMethod, self.objectreference, 'Close')
  1253. def Delete(self):
  1254. return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Delete'))
  1255. def Edit(self):
  1256. return self.W(_vbMethod, self.objectreference, 'Edit')
  1257. def Fields(self, index = acConstants.Missing):
  1258. return self.W(_vbMethod, self.objectreference, 'Fields', index)
  1259. def GetRows(self, numrows):
  1260. return self.W(_vbMethod, self.objectreference, 'GetRows', numrows)
  1261. def Move(self, rows, startbookmark = acConstants.Missing):
  1262. return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'Move', rows, startbookmark))
  1263. def MoveFirst(self):
  1264. return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveFirst'))
  1265. def MoveLast(self):
  1266. return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveLast'))
  1267. def MoveNext(self):
  1268. return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveNext'))
  1269. def MovePrevious(self):
  1270. return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MovePrevious'))
  1271. def OpenRecordset(self, type = -1, option = -1, lockedit = -1):
  1272. return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit)
  1273. def Update(self):
  1274. return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Update'))
  1275. class _SubForm(_Form):
  1276. classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, CurrentRecord = True
  1277. , Filter = True, FilterOn = True, LinkChildFields = False, LinkMasterFields = False
  1278. , OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True
  1279. , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True
  1280. , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True
  1281. , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OrderBy = True
  1282. , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True
  1283. )
  1284. def SetFocus(self):
  1285. raise AttributeError("type object 'SubForm' has no method 'SetFocus'")
  1286. class _TableDef(_BasicObject):
  1287. classProperties = dict()
  1288. @property
  1289. def Table(self): return self.W(_vbUNO, self.objectreference, 'Table')
  1290. def CreateField(self, name, type, size = 0, attributes = 0):
  1291. return self.W(_vbMethod, self.objectreference, 'CreateField', name, type, size, attributes)
  1292. def Fields(self, index = acConstants.Missing):
  1293. return self.W(_vbMethod, self.objectreference, 'Fields', index)
  1294. def OpenRecordset(self, type = -1, option = -1, lockedit = -1):
  1295. return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit)
  1296. class _TempVar(_BasicObject):
  1297. classProperties = dict(Value = True)
  1298. """
  1299. Set of directly callable error handling methods
  1300. """
  1301. def DebugPrint(*args):
  1302. dargs = ()
  1303. for arg in args:
  1304. if isinstance(arg, _BasicObject):
  1305. arg = ('[' + arg.objecttype + '] ' + arg.name).rstrip()
  1306. dargs = dargs + (arg,)
  1307. return _A2B.invokeMethod('DebugPrint', _WRAPPERMODULE, *dargs)
  1308. def TraceConsole(): return _A2B.invokeMethod('TraceConsole', 'Trace')
  1309. def TraceError(tracelevel, errorcode, errorprocedure, errorline):
  1310. return _A2B.invokeMethod('TraceError', 'Trace', tracelevel, errorcode, errorprocedure, errorline)
  1311. def TraceLevel(newtracelevel = 'ERROR'): return _A2B.invokeMethod('TraceLevel', 'Trace', newtracelevel)
  1312. def TraceLog(tracelevel, text, messagebox = True):
  1313. return _A2B.invokeMethod('TraceLog', 'Trace', tracelevel, text, messagebox)