Fix ChatGPT error

This commit is contained in:
Rufus King 2026-07-27 20:35:27 -04:00
parent bf0f376cdb
commit f68993cc14

View file

@ -1,37 +1,12 @@
' ========================================================================= ' =========================================================================
' StockFunctions.bas ' StockFunctions.bas
' Collabora / LibreOffice Basic port of the ONLYOFFICE custom functions. ' Collabora / LibreOffice Basic
' '
' UPDATED 2026-07-27: FUNDTIME now returns Yahoo's last market update ' FUNDTIME now returns Yahoo's latest market update date/time:
' date and time as a combined Calc date/time value.
' '
' FUNDPRICE returns the current price from stockproxy. ' 2026-07-27 19:58:00
' FUNDPRICE_HIST returns a historical price from stockproxy.
' FUNDTIME returns Yahoo's regularMarketTime as a date/time value.
' '
' Example FUNDTIME result: ' The date and time are obtained from the stockproxy /current endpoint.
' 2026-07-27 19:58:00
'
' The returned value is a real Calc date/time value, not text, so it can
' be sorted, compared, formatted, or used in date/time calculations.
'
' HOW TO INSTALL IN COLLABORA:
' 1. Open the sheet in Collabora (collabora.kingdezigns.com).
' 2. Tools > Macros > Edit Macros (opens the Basic IDE).
' 3. In the tree, find "<Your Document Name>" (NOT "My Macros" -
' you want this stored IN the document so it travels with the file).
' 4. Right-click "Standard" under your document > Insert > Module.
' 5. Paste this entire file's contents into the new module.
' (Or, if StockFunctions already exists, replace its contents.)
' 6. Fill in PROXY_SECRET() below with the real value if not already set.
' 7. Save the document (Ctrl+S). Macro security must allow this
' document's macros to run - if prompted, allow them.
'
' USAGE IN CELLS:
' =FUNDPRICE(D4)
' =FUNDPRICE_HIST(D4, TEXT($B$3,"yyyy-mm-dd"))
' =FUNDPRICE(A5) <- replaces old =STOCKPRICE(A5)
' =FUNDTIME(A5) <- returns Yahoo date/time of latest market update
' ========================================================================= ' =========================================================================
Option Explicit Option Explicit
@ -39,303 +14,277 @@ Option Explicit
' ---- Config ------------------------------------------------------------- ' ---- Config -------------------------------------------------------------
Function PROXY_BASE() As String Function PROXY_BASE() As String
PROXY_BASE = "https://stocks.kingdezigns.com" PROXY_BASE = "https://stocks.kingdezigns.com"
End Function End Function
Function PROXY_SECRET() As String Function PROXY_SECRET() As String
PROXY_SECRET = "90c2528e9b5221c110f7c2c9cd6c65dc" ' <-- from Vaultwarden PROXY_SECRET = "90c2528e9b5221c110f7c2c9cd6c65dc"
End Function End Function
' ---- Public spreadsheet functions --------------------------------------- ' ---- Public spreadsheet functions ---------------------------------------
Function FUNDPRICE(ticker As String) As Variant Function FUNDPRICE(ticker As String) As Variant
Dim sUrl As String, sJson As String, vPrice As Variant Dim sUrl As String
Dim sJson As String
Dim vPrice As Variant
``` sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _
sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _ "&key=" & PROXY_SECRET()
"&key=" & PROXY_SECRET()
sJson = HttpGetText(sUrl) sJson = HttpGetText(sUrl)
If sJson = "" Then If sJson = "" Then
FUNDPRICE = "#ERROR" FUNDPRICE = "#ERROR"
Exit Function Exit Function
End If End If
vPrice = JsonNumber(sJson, "price") vPrice = JsonNumber(sJson, "price")
If IsNull(vPrice) Then
FUNDPRICE = "#N/A"
Else
FUNDPRICE = vPrice
End If
```
If IsNull(vPrice) Then
FUNDPRICE = "#N/A"
Else
FUNDPRICE = vPrice
End If
End Function End Function
Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant
Dim sUrl As String, sJson As String, vPrice As Variant Dim sUrl As String
Dim sJson As String
Dim vPrice As Variant
``` sUrl = PROXY_BASE() & "/historical?ticker=" & EncodeUrl(ticker) & _
sUrl = PROXY_BASE() & "/historical?ticker=" & EncodeUrl(ticker) & _ "&date=" & EncodeUrl(dateStr) & _
"&date=" & EncodeUrl(dateStr) & "&key=" & PROXY_SECRET() "&key=" & PROXY_SECRET()
sJson = HttpGetText(sUrl) sJson = HttpGetText(sUrl)
If sJson = "" Then If sJson = "" Then
FUNDPRICE_HIST = "#ERROR" FUNDPRICE_HIST = "#ERROR"
Exit Function Exit Function
End If End If
vPrice = JsonNumber(sJson, "price") vPrice = JsonNumber(sJson, "price")
If IsNull(vPrice) Then
FUNDPRICE_HIST = "#N/A"
Else
FUNDPRICE_HIST = vPrice
End If
```
If IsNull(vPrice) Then
FUNDPRICE_HIST = "#N/A"
Else
FUNDPRICE_HIST = vPrice
End If
End Function End Function
' Returns Yahoo's latest market update date and time as a real Calc
' date/time value. ' ---- Yahoo market update date/time --------------------------------------
' '
' Example: ' Returns:
' Yahoo JSON:
' "date":"2026-07-27","time":"19:58:00"
' '
' FUNDTIME returns: ' 2026-07-27 19:58:00
' 2026-07-27 19:58:00
' '
Function FUNDTIME(ticker As String) As Variant ' This combines the "date" and "time" fields returned by stockproxy.
Dim sUrl As String '
Dim sJson As String Function FUNDTIME(ticker As String) As String
Dim vDate As Variant Dim sUrl As String
Dim vTime As Variant Dim sJson As String
Dim sDateTime As String Dim sDate As String
Dim oDateTime As Date Dim sTime As String
``` sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _
sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _ "&key=" & PROXY_SECRET()
"&key=" & PROXY_SECRET()
sJson = HttpGetText(sUrl) sJson = HttpGetText(sUrl)
If sJson = "" Then If sJson = "" Then
FUNDTIME = "#ERROR" FUNDTIME = "#ERROR"
Exit Function Exit Function
End If End If
' Get the separate date and time values from stockproxy. sDate = JsonString(sJson, "date")
vDate = JsonString(sJson, "date") sTime = JsonString(sJson, "time")
vTime = JsonString(sJson, "time")
If IsNull(vDate) Or IsNull(vTime) Then If sDate = "" Or sTime = "" Then
FUNDTIME = "#N/A" FUNDTIME = "#N/A"
Exit Function Exit Function
End If End If
' Combine into a single date/time string. FUNDTIME = sDate & " " & sTime
sDateTime = CStr(vDate) & " " & CStr(vTime)
' Convert to a real Calc date/time value.
On Error GoTo DateError
oDateTime = CDate(sDateTime)
FUNDTIME = oDateTime
Exit Function
```
DateError:
FUNDTIME = "#N/A"
End Function End Function
' ---- Internal helpers ---------------------------------------------------- ' ---- Internal helpers ----------------------------------------------------
' Synchronous HTTP GET, returns response body as text, "" on failure. ' Synchronous HTTP GET, returns response body as text, "" on failure.
Function HttpGetText(sUrl As String) As String Function HttpGetText(sUrl As String) As String
Dim oSFA As Object, oStream As Object, oTextStream As Object Dim oSFA As Object
Dim sResult As String Dim oStream As Object
Dim oTextStream As Object
Dim sResult As String
``` On Error GoTo ErrHandler
On Error GoTo ErrHandler
oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess") oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
oStream = oSFA.openFileRead(sUrl) oStream = oSFA.openFileRead(sUrl)
oTextStream = createUnoService("com.sun.star.io.TextInputStream") oTextStream = createUnoService("com.sun.star.io.TextInputStream")
oTextStream.setInputStream(oStream) oTextStream.setInputStream(oStream)
oTextStream.setEncoding("UTF-8") oTextStream.setEncoding("UTF-8")
sResult = "" sResult = ""
Do While Not oTextStream.isEOF() Do While Not oTextStream.isEOF()
sResult = sResult & oTextStream.readLine() & Chr(10) sResult = sResult & oTextStream.readLine() & Chr(10)
Loop Loop
oTextStream.closeInput() oTextStream.closeInput()
HttpGetText = sResult HttpGetText = sResult
Exit Function Exit Function
```
ErrHandler: ErrHandler:
HttpGetText = "" HttpGetText = ""
End Function End Function
' Pulls a numeric value out of a flat JSON string for a given key. ' Pulls a numeric value out of a flat JSON string for a given key.
' e.g. JsonNumber("{""price"":18.37}", "price") -> 18.37
' Returns Null if the key isn't found or has no numeric value.
Function JsonNumber(sJson As String, sKey As String) As Variant Function JsonNumber(sJson As String, sKey As String) As Variant
Dim iPos As Integer, iStart As Integer, iEnd As Integer Dim iPos As Integer
Dim sNum As String, cChar As String Dim iStart As Integer
Dim iEnd As Integer
Dim sNum As String
Dim cChar As String
``` iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
If iPos = 0 Then If iPos = 0 Then
JsonNumber = Null JsonNumber = Null
Exit Function Exit Function
End If
iPos = InStr(iPos, sJson, ":")
If iPos = 0 Then
JsonNumber = Null
Exit Function
End If
iStart = iPos + 1
Do While iStart <= Len(sJson) And Mid(sJson, iStart, 1) = " "
iStart = iStart + 1
Loop
iEnd = iStart
Do While iEnd <= Len(sJson)
cChar = Mid(sJson, iEnd, 1)
If (cChar >= "0" And cChar <= "9") Or _
cChar = "." Or cChar = "-" Then
iEnd = iEnd + 1
Else
Exit Do
End If End If
Loop
sNum = Mid(sJson, iStart, iEnd - iStart) iPos = InStr(iPos, sJson, ":")
If Len(sNum) = 0 Then If iPos = 0 Then
JsonNumber = Null JsonNumber = Null
Else Exit Function
JsonNumber = CDbl(sNum) End If
End If
```
iStart = iPos + 1
Do While iStart <= Len(sJson) And Mid(sJson, iStart, 1) = " "
iStart = iStart + 1
Loop
iEnd = iStart
Do While iEnd <= Len(sJson)
cChar = Mid(sJson, iEnd, 1)
If (cChar >= "0" And cChar <= "9") Or _
cChar = "." Or cChar = "-" Then
iEnd = iEnd + 1
Else
Exit Do
End If
Loop
sNum = Mid(sJson, iStart, iEnd - iStart)
If Len(sNum) = 0 Then
JsonNumber = Null
Else
JsonNumber = CDbl(sNum)
End If
End Function End Function
' Pulls a quoted STRING value out of a flat JSON string for a given key.
' e.g. JsonString("{""resolved_date"":""2026-07-23""}", "resolved_date")
' -> "2026-07-23"
'
' Returns Null if the key isn't found or has no quoted value.
Function JsonString(sJson As String, sKey As String) As Variant
Dim iPos As Integer
Dim iColon As Integer
Dim iQuoteStart As Integer
Dim iQuoteEnd As Integer
``` ' Pulls a quoted string value out of a flat JSON string.
iPos = InStr(sJson, Chr(34) & sKey & Chr(34)) Function JsonString(sJson As String, sKey As String) As String
Dim iPos As Integer
Dim iColon As Integer
Dim iQuoteStart As Integer
Dim iQuoteEnd As Integer
If iPos = 0 Then iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
JsonString = Null
Exit Function
End If
iColon = InStr(iPos, sJson, ":") If iPos = 0 Then
JsonString = ""
Exit Function
End If
If iColon = 0 Then iColon = InStr(iPos, sJson, ":")
JsonString = Null
Exit Function
End If
iQuoteStart = InStr(iColon, sJson, Chr(34)) If iColon = 0 Then
JsonString = ""
Exit Function
End If
If iQuoteStart = 0 Then iQuoteStart = InStr(iColon, sJson, Chr(34))
JsonString = Null
Exit Function
End If
iQuoteEnd = InStr(iQuoteStart + 1, sJson, Chr(34)) If iQuoteStart = 0 Then
JsonString = ""
Exit Function
End If
If iQuoteEnd = 0 Then iQuoteEnd = InStr(iQuoteStart + 1, sJson, Chr(34))
JsonString = Null
Exit Function
End If
JsonString = Mid(sJson, iQuoteStart + 1, _ If iQuoteEnd = 0 Then
iQuoteEnd - iQuoteStart - 1) JsonString = ""
``` Exit Function
End If
JsonString = Mid(sJson, iQuoteStart + 1, _
iQuoteEnd - iQuoteStart - 1)
End Function End Function
' Minimal percent-encoder - sufficient for tickers and yyyy-mm-dd strings.
' Minimal percent-encoder.
Function EncodeUrl(s As String) As String Function EncodeUrl(s As String) As String
Dim i As Integer, c As String, sOut As String Dim i As Integer
Dim c As String
Dim sOut As String
``` sOut = ""
sOut = ""
For i = 1 To Len(s) For i = 1 To Len(s)
c = Mid(s, i, 1) c = Mid(s, i, 1)
If (c >= "A" And c <= "Z") Or _ If (c >= "A" And c <= "Z") Or _
(c >= "a" And c <= "z") Or _ (c >= "a" And c <= "z") Or _
(c >= "0" And c <= "9") Or _ (c >= "0" And c <= "9") Or _
c = "-" Or c = "_" Or c = "." Or c = "~" Then c = "-" Or c = "_" Or c = "." Or c = "~" Then
sOut = sOut & c sOut = sOut & c
Else Else
sOut = sOut & "%" & Right("0" & Hex(Asc(c)), 2) sOut = sOut & "%" & Right("0" & Hex(Asc(c)), 2)
End If End If
Next i Next i
EncodeUrl = sOut
```
EncodeUrl = sOut
End Function End Function
' ---- Snapshot ------------------------------------------------------------
Sub RefreshPriceSnapshot Sub RefreshPriceSnapshot
Dim oDoc As Object, oSheet As Object Dim oDoc As Object
Dim oSrcRange As Object, oDestRange As Object Dim oSheet As Object
Dim oCell As Object Dim i As Integer
Dim i As Integer
``` oDoc = ThisComponent
oDoc = ThisComponent oSheet = oDoc.Sheets.getByIndex(0)
oSheet = oDoc.Sheets.getByIndex(0) ' adjust index/name if needed
' Copy P3:Q53 -> R3:S53 as values only ' Copy P3:Q53 -> R3:S53 as values only
For i = 2 To 4 ' rows 3 to 53 (0-indexed: row 3 = index 2) For i = 2 To 4
oSheet.getCellByPosition(17, i).setValue( _ oSheet.getCellByPosition(17, i).setValue( _
oSheet.getCellByPosition(15, i).getValue()) _ oSheet.getCellByPosition(15, i).getValue())
' P->R (col P=15, R=17)
oSheet.getCellByPosition(18, i).setValue( _ oSheet.getCellByPosition(18, i).setValue( _
oSheet.getCellByPosition(16, i).getValue()) _ oSheet.getCellByPosition(16, i).getValue())
' Q->S (col Q=16, S=18)
Next i Next i
MsgBox "Price snapshot refreshed."
```
MsgBox "Price snapshot refreshed."
End Sub End Sub