Live UDF formulas in template, remove gApiEnabled guard

- GL_Accounts_Client_Template.xlsx: C6:C13 now have real formulas
  =GetAccountAmount(Setup!$B$6,...) instead of text placeholders
- GLAccountsExcelApi.bas: removed gApiEnabled flag entirely, UDFs
  call RunQuery directly; add SetManualCalculation helper macro
- Works in Excel safe mode + manual calc: F9 triggers DB queries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-29 01:25:15 +02:00
parent 242406588c
commit 7da99b3bf7
2 changed files with 33 additions and 68 deletions

View File

@@ -6,17 +6,14 @@ Option Explicit
' Setup: ' Setup:
' 1. Install PostgreSQL ODBC driver. ' 1. Install PostgreSQL ODBC driver.
' 2. Apply notes/accounting/excel_api/gl_accounts_sql_poc.sql. ' 2. Apply notes/accounting/excel_api/gl_accounts_sql_poc.sql.
' 3. In Excel: Developer > Visual Basic > File > Import File... ' 3. Open Excel in safe mode: double-clic sur Ouvrir_Excel_SafeMode.bat
' 4. Import this .bas module. ' 4. Developer > Visual Basic > File > Import File > importe ce .bas.
' 5. Edit GL_API_CONNECTION_STRING below (or use a named DSN). ' 5. Run SetManualCalculation once (sets xlCalculationManual).
' '
' Usage: ' Usage (2 modes au choix):
' - On the Setup sheet, fill in B6 (company), B7 (account), B8 (currency), B9 (date). ' Mode formule : tape =GetAccountAmount("ICT TRADING","20011","USD","2026-05-13")
' - Run RefreshGLApi to query the database and populate the Functions sheet. ' dans n'importe quelle cellule, puis F9 pour recalculer.
' - Excel stays in manual calculation mode after refresh; edit Setup freely. ' Mode macro : remplis Setup!B6:B9, lance RefreshGLApi.
'
' DSN example:
' "DSN=TradonGLApi;Uid=tradon_readonly;Pwd=change_me;"
Private Const GL_API_CONNECTION_STRING As String = _ Private Const GL_API_CONNECTION_STRING As String = _
"Driver={PostgreSQL Unicode(x64)};" & _ "Driver={PostgreSQL Unicode(x64)};" & _
@@ -28,7 +25,6 @@ Private Const GL_API_CONNECTION_STRING As String = _
Private gConnection As Object Private gConnection As Object
Private gCache As Object Private gCache As Object
Private gApiEnabled As Boolean
' ---- Connection helpers ---- ' ---- Connection helpers ----
@@ -72,11 +68,18 @@ Public Sub CloseGLApiConnection()
Set gConnection = Nothing Set gConnection = Nothing
End Sub End Sub
' ---- Main macro ---- ' ---- Setup ----
' Reads Setup!B6:B9, queries the database directly, writes plain values to Functions!C6:C13. ' A lancer une seule fois apres import du module.
' Excel stays in xlCalculationManual after this runs -- edit Setup cells freely, ' Passe Excel en calcul manuel : les formules ne se recalculent que sur F9.
' then run RefreshGLApi again when you want fresh results. Public Sub SetManualCalculation()
Application.Calculation = xlCalculationManual
MsgBox "Calcul manuel actif. F9 = recalculer toutes les formules GL.", vbInformation
End Sub
' ---- Mode macro : RefreshGLApi ----
' Lit Setup!B6:B9, interroge la DB, ecrit les valeurs dans Functions!C6:C13.
Public Sub RefreshGLApi() Public Sub RefreshGLApi()
Dim wsSetup As Worksheet Dim wsSetup As Worksheet
Dim wsFunctions As Worksheet Dim wsFunctions As Worksheet
@@ -87,11 +90,11 @@ Public Sub RefreshGLApi()
On Error GoTo 0 On Error GoTo 0
If wsSetup Is Nothing Then If wsSetup Is Nothing Then
MsgBox "Sheet 'Setup' not found.", vbExclamation MsgBox "Feuille 'Setup' introuvable.", vbExclamation
Exit Sub Exit Sub
End If End If
If wsFunctions Is Nothing Then If wsFunctions Is Nothing Then
MsgBox "Sheet 'Functions' not found.", vbExclamation MsgBox "Feuille 'Functions' introuvable.", vbExclamation
Exit Sub Exit Sub
End If End If
@@ -101,26 +104,26 @@ Public Sub RefreshGLApi()
Dim company As String Dim company As String
Dim account As String Dim account As String
Dim currency As String Dim currencyIso As String
Dim valueDate As Variant Dim valueDate As Variant
company = CStr(wsSetup.Range("B6").Value) company = CStr(wsSetup.Range("B6").Value)
account = CStr(wsSetup.Range("B7").Value) account = CStr(wsSetup.Range("B7").Value)
currency = CStr(wsSetup.Range("B8").Value) currencyIso = CStr(wsSetup.Range("B8").Value)
valueDate = wsSetup.Range("B9").Value valueDate = wsSetup.Range("B9").Value
ClearGLApiCache ClearGLApiCache
On Error GoTo RefreshError On Error GoTo RefreshError
wsFunctions.Range("C6").Value = RunQuery("get_account_base_amount", company, account, currency, valueDate) wsFunctions.Range("C6").Value = RunQuery("get_account_base_amount", company, account, currencyIso, valueDate)
wsFunctions.Range("C7").Value = RunQuery("get_account_real_base_amount", company, account, currency, valueDate) wsFunctions.Range("C7").Value = RunQuery("get_account_real_base_amount", company, account, currencyIso, valueDate)
wsFunctions.Range("C8").Value = RunQuery("get_account_amount", company, account, currency, valueDate) wsFunctions.Range("C8").Value = RunQuery("get_account_amount", company, account, currencyIso, valueDate)
wsFunctions.Range("C9").Value = RunQuery("get_account_abbr", company, account, currency, valueDate) wsFunctions.Range("C9").Value = RunQuery("get_account_abbr", company, account, currencyIso, valueDate)
wsFunctions.Range("C10").Value = RunQuery("get_account_name", company, account, currency, valueDate) wsFunctions.Range("C10").Value = RunQuery("get_account_name", company, account, currencyIso, valueDate)
wsFunctions.Range("C11").Value = RunQuery("get_account_contact", company, account, currency, valueDate) wsFunctions.Range("C11").Value = RunQuery("get_account_contact", company, account, currencyIso, valueDate)
wsFunctions.Range("C12").Value = RunQuery("get_account_contact_code", company, account, currency, valueDate) wsFunctions.Range("C12").Value = RunQuery("get_account_contact_code", company, account, currencyIso, valueDate)
wsFunctions.Range("C13").Value = RunQuery("get_account_contact_name", company, account, currency, valueDate) wsFunctions.Range("C13").Value = RunQuery("get_account_contact_name", company, account, currencyIso, valueDate)
CloseGLApiConnection CloseGLApiConnection
GoTo RefreshDone GoTo RefreshDone
@@ -131,23 +134,6 @@ RefreshError:
RefreshDone: RefreshDone:
Application.ScreenUpdating = True Application.ScreenUpdating = True
Application.EnableEvents = True Application.EnableEvents = True
' Intentionally keep xlCalculationManual -- prevents any live recalculation.
End Sub
' Resets Functions!C6:C13 to placeholder text.
Public Sub ClearGLApiResults()
Dim wsFunctions As Worksheet
On Error Resume Next
Set wsFunctions = ThisWorkbook.Worksheets("Functions")
On Error GoTo 0
If wsFunctions Is Nothing Then Exit Sub
Application.EnableEvents = False
Dim r As Long
For r = 6 To 13
wsFunctions.Cells(r, 3).Value = "-"
Next r
Application.EnableEvents = True
End Sub End Sub
' ---- Core SQL runner ---- ' ---- Core SQL runner ----
@@ -213,29 +199,15 @@ Private Function SqlText(ByVal value As Variant) As String
SqlText = Replace(CStr(value), "'", "''") SqlText = Replace(CStr(value), "'", "''")
End Function End Function
' ---- UDF functions (optional, for manual formula use) ---- ' ---- UDF formulas (mode formule) ----
' ' Utilisation : =GetAccountAmount("ICT TRADING", B7, B8, B9)
' These functions are NOT called by RefreshGLApi. ' Puis F9 pour recalculer. Le cache evite les appels DB redondants.
' They are available if you want to type a live formula directly in a cell,
' but you must first run EnableGLApi and keep Excel in manual calculation mode.
' Warning: live UDF formulas in cells can freeze Excel on recalculation.
Public Sub EnableGLApi()
gApiEnabled = True
Application.Calculation = xlCalculationManual
End Sub
Public Sub DisableGLApi()
gApiEnabled = False
CloseGLApiConnection
End Sub
Public Function GetAccountBaseAmount( _ Public Function GetAccountBaseAmount( _
ByVal companyKey As Variant, _ ByVal companyKey As Variant, _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountBaseAmount = "#GLAPI_OFF": Exit Function
GetAccountBaseAmount = RunQuery("get_account_base_amount", companyKey, accountCode, currencyIso, valueDate) GetAccountBaseAmount = RunQuery("get_account_base_amount", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -244,7 +216,6 @@ Public Function GetAccountRealBaseAmount( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountRealBaseAmount = "#GLAPI_OFF": Exit Function
GetAccountRealBaseAmount = RunQuery("get_account_real_base_amount", companyKey, accountCode, currencyIso, valueDate) GetAccountRealBaseAmount = RunQuery("get_account_real_base_amount", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -253,7 +224,6 @@ Public Function GetAccountAmount( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountAmount = "#GLAPI_OFF": Exit Function
GetAccountAmount = RunQuery("get_account_amount", companyKey, accountCode, currencyIso, valueDate) GetAccountAmount = RunQuery("get_account_amount", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -262,7 +232,6 @@ Public Function GetAccountAbbr( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountAbbr = "#GLAPI_OFF": Exit Function
GetAccountAbbr = RunQuery("get_account_abbr", companyKey, accountCode, currencyIso, valueDate) GetAccountAbbr = RunQuery("get_account_abbr", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -271,7 +240,6 @@ Public Function GetAccountName( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountName = "#GLAPI_OFF": Exit Function
GetAccountName = RunQuery("get_account_name", companyKey, accountCode, currencyIso, valueDate) GetAccountName = RunQuery("get_account_name", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -280,7 +248,6 @@ Public Function GetAccountContact( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountContact = "#GLAPI_OFF": Exit Function
GetAccountContact = RunQuery("get_account_contact", companyKey, accountCode, currencyIso, valueDate) GetAccountContact = RunQuery("get_account_contact", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -289,7 +256,6 @@ Public Function GetAccountContactCode( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountContactCode = "#GLAPI_OFF": Exit Function
GetAccountContactCode = RunQuery("get_account_contact_code", companyKey, accountCode, currencyIso, valueDate) GetAccountContactCode = RunQuery("get_account_contact_code", companyKey, accountCode, currencyIso, valueDate)
End Function End Function
@@ -298,6 +264,5 @@ Public Function GetAccountContactName( _
ByVal accountCode As Variant, _ ByVal accountCode As Variant, _
ByVal currencyIso As Variant, _ ByVal currencyIso As Variant, _
ByVal valueDate As Variant) As Variant ByVal valueDate As Variant) As Variant
If Not gApiEnabled Then GetAccountContactName = "#GLAPI_OFF": Exit Function
GetAccountContactName = RunQuery("get_account_contact_name", companyKey, accountCode, currencyIso, valueDate) GetAccountContactName = RunQuery("get_account_contact_name", companyKey, accountCode, currencyIso, valueDate)
End Function End Function