Ergebnis in Zelle statt Fenster schreiben?

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Simeon
Beiträge: 1
Registriert: Mo, 19.01.2015 20:00

Ergebnis in Zelle statt Fenster schreiben?

Beitrag von Simeon »

Hallo Community!

Ich bin schon seit längerer Zeit auf der Suche nach einer Funktion, die es mir zuverlässig erlauben würde, den momentanen Kurswert einer Aktie (idealerweise sogar inklusive der historischen Werte) aus dem Internet abzurufen un in OpenOffice Calc zu plotten. Nach sehr langer Suche, die mir sehr viele verschiedene Makros diversester Komplexität eingebracht hat, bin ich dem Ziel leider nicht wirklich näher gekommen. Es gibt entsprechende Funktionen für Excel (das ich aber nicht besonders mag) und es gab solche Funktionen sogar mal für OpenOffice (http://stackoverflow.com/questions/9185 ... c-getquote, leider jedoch nicht mehr zugänglich), nur scheint es momentan nichts entsprechendes (zugängliches) für OpenOffice zu geben. Den besten (da einfachsten - ich bei kompletter Anfänger, wenn es um das Programmieren in OOo Basic geht) Makro poste ich mal hier (der Code ist nicht von mir, leider habe ich die Quelle verloren):

Code: Alles auswählen

    REM  *****  BASIC  *****

    Sub Main()
       ' Hole den Aktienkurs für die Software AG über die URL
       '   http://quote.yahoo.com/d/quotes.csv?s=SOW.DE&f=sl1d1t1c1ohgv&e=.csv
       Print "Software AG (WKN 330400): ", GetStockPrice( "SOW.DE" )
       ' Hole den Aktienkurs für die United Internet AG über die URL
       '   http://quote.yahoo.com/d/quotes.csv?s=UTDI.DE&f=sl1d1t1c1ohgv&e=.csv
       Print "United Internet AG (WKN 508903): ", GetStockPrice( "UTDI.DE" )
    End Sub

    '----------
    ' This function looks up the price of a stock symbol from yahoo.
    ' Pass in these parameters:
    '      cStockSymbol - a string, which is the stock symbol.
    ' Returns:
    '      A number which is the price of the stock.
    '
    Function GetStockPrice( ByVal cStockSymbol As String ) As Double
       ' Use this URL to get a stock price from Yahoo.
       ' For example, this URL...
       '   http://quote.yahoo.com/d/quotes.csv?s=SOW.DE&s=UTDI.DE&f=sl1d1t1c1ohgv&e=.csv
       ' would return a CSV file with the prices for both Software AG and United Internet AG.
       ' Similarly, we can form a URL for a single stock, based upon the parameter.
       cURL = "http://quote.yahoo.com/d/quotes.csv?s=" + cStockSymbol + "&f=sl1d1t1c1ohgv&e=.csv"
       
       ' Open up a new spreadsheet from the above URL.
       ' Specify the CSV filter with options that decode the CSV format comming back from Yahoo.
       ' Specify the Hidden property so that the spreadsheet does not appear on the screen.
       oCalcDoc = StarDesktop.loadComponentFromURL( cURL, "_blank", 0,_
          Array( MakePropertyValue( "FilterName", "Text - txt - csv (StarCalc)" ),_
                MakePropertyValue( "FilterOptions", "44,34,SYSTEM,1,1/10/2/10/3/10/4/10/5/10/6/10/7/10/8/10/9/10" ),_
                MakePropertyValue( "Hidden", True ) ) )
       
       ' Get the first sheet of the Calc document.
       oSheet = oCalcDoc.getSheets().getByIndex( 0 )
       ' Get the cell B1, which is the stock price.  (Row 0, Col 1.)
       nValue = oSheet.getCellByPosition( 1, 0 ).getValue()

       ' Be sure the close the spreadsheet, because it is hidden, and the user cannot close it.
       oCalcDoc.close( True )
       
       ' Return the value.
       GetStockPrice() = nValue
    End Function

    '----------
    '   Create and return a new com.sun.star.beans.PropertyValue.
    '
    Function MakePropertyValue( Optional cName As String, Optional uValue ) As com.sun.star.beans.PropertyValue
       Dim oPropertyValue As New com.sun.star.beans.PropertyValue
       If Not IsMissing( cName ) Then
          oPropertyValue.Name = cName
       EndIf
       If Not IsMissing( uValue ) Then
          oPropertyValue.Value = uValue
       EndIf
       MakePropertyValue() = oPropertyValue
    End Function 
Was dieser Code meines Verständnisses nach macht ist zwei momentane Aktienkurse abzurufen, die durch deren Stock Symbol (im obigen Beispiel SOW.DE und UTDI.DE) auf die jeweilige Aktie verweisen und die Ergebnisse dann in einem neuen Fenster öffnet. Nun meine Frage/Bitte an euch: Ist es möglich diesen Code dergestalt umzuschreiben/verallgemeinern, dass er statt einem fest im Makro definierten Symbol den Zelleninhalt einer bestimmten Zelle (z.b. der ersten Zelle der Spalte, in der der Befehl steht) verwendet und das Ergebnis statt in einem Fenster in die jeweilige Zelle schreibt? Ich würde gerne eine Zeitleiste mit den aktuellen Aktienwerten zum Zeitpunkt des Dokumentabrufes erstellen, damit ich die Wertentwicklung besser überwachen und plotten kann (wie ich das dann aus einem Makro das nur den aktuellen Wert herausgibt machen kann werde ich noch ausknobeln).

Ich würde mich freuen, wenn mir jemand helfen könnte.

Mit freundlichen Grüßen,
Simeon

PS: Ich kenne die Möglichkeit über "Verknüpfung zu externen Daten..." Tabellen in OpenOffice Calc zu laden, würde sie aber gerne vermeiden - leider zerschießt mir diese Funktion allerdings immer die Zellenreferenzen zur Weiterverarbeitung der Daten.
PPS: Ich habe auch noch einen zweiten Code gefunden, der genau das macht, was ich will. Nur leider in Excel. Gibt es eine Möglichkeit, dass in OOoBasic zu übertragen?

Code: Alles auswählen

    Function StockQuote(strTicker As String, Optional dtDate As Variant)
    ' Date is optional - if omitted, use today. If value is not a date, throw error.
    If IsMissing(dtDate) Then
    dtDate = Date
    Else
    If Not (IsDate(dtDate)) Then
    StockQuote = CVErr(xlErrNum)
    End If
    End If

    Dim dtPrevDate As Date
    Dim strURL As String, strCSV As String, strRows() As String, strColumns() As String
    Dim dbClose As Double

    dtPrevDate = dtDate - 7

    ' Compile the request URL with start date and end date
    strURL = "http://ichart.finance.yahoo.com/table.csv?s=" & strTicker & _
    "&a=" & Month(dtPrevDate) - 1 & _
    "&b=" & Day(dtPrevDate) & _
    "&c=" & Year(dtPrevDate) & _
    "&d=" & Month(dtDate) - 1 & _
    "&e=" & Day(dtDate) & _
    "&f=" & Year(dtDate) & _
    "&g=d&ignore=.csv"

    ' Debug.Print strURL

    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "GET", strURL, False
    http.Send
    strCSV = http.responseText

    ' Debug.Print strCSV

    ' The most recent information is in row 2, just below the table headings.
    ' The price close is the 5th entry
    strRows() = Split(strCSV, Chr(10)) ' split the CSV into rows
    strColumns = Split(strRows(1), ",") ' split the relevant row into columns. 1 means 2nd row, starting at index 0
    dbClose = strColumns(4) ' 4 means: 5th position, starting at index 0

    ' Debug.Print vbLf
    ' Debug.Print strRows(1)
    ' Debug.Print "dbClose: " & dbClose

    StockQuote = dbClose

    Set http = Nothing

    End Function
clag
********
Beiträge: 3570
Registriert: Di, 27.01.2009 15:30

Re: Ergebnis in Zelle statt Fenster schreiben?

Beitrag von clag »

hallo Simeon,

also das erste Makro tut doch prima, ist aber wohl eher nicht Massenabfrage tauglich bei 3-5 Sekunden Ladezeit
habe dir ein simples Start Makro hinzugefügt welches wie gewünscht die Daten in eine Zelle schreibt
markiere eine der Zellen Zelle A2, A3, B2, B3 und klick auf aktualisieren, logischerweise
brauchst du eine Verbindung ins I-net damit es funktioniert.
" orange " bedeutet es wird geladen.
get-stockdata-example_1.ods
(11.54 KiB) 159-mal heruntergeladen
viel Spaß
LG
clag

nutzt: WinXP SP3 / AOO 4.1.10 / Firefox
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Ergebnis in Zelle statt Fenster schreiben?

Beitrag von Karolus »

Hallo

Ich hab mal etwas "massenabfragetaugliches" aufgesetzt.
Dabei werden alle Symbole auf einen Rutsch abgefragt.

Es gibt eine Version für LibreOffice 4.x
get-stockdata.ods
Version für LO4.x mit Python3
(32.15 KiB) 148-mal heruntergeladen
Den Code sollte ichvielleicht auch posten

Code: Alles auswählen

from urllib.request import urlopen # python3 <--> LO4.x
import csv
from itertools import chain




yah_url =('http://finance.yahoo.com/d/quotes.csv?'
          's={}&f=nsl1d1t1c1ohgv&e=.csv'.format )

def get_stocks(symbols):
    url =yah_url('|'.join(symbols) )
    with urlopen(url) as response:
        content = response.read().decode('utf8')
    return csv.reader(content.splitlines())


def main(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    sheet = doc.CurrentSelection.Spreadsheet
    inhalt = sheet.queryContentCells(7).getByIndex(0).FormulaArray
    inhalt = inhalt[1:]
    backup = doc.Sheets.Backup
    filled = backup.queryContentCells(7).getByIndex(0)
    lastrow = filled.RangeAddress.EndRow
    size = (0, # erste Spalte
            lastrow+1,   # erste Zeile
            len(inhalt[0])-1, # letzte Spalte
            lastrow+len(inhalt)) #letzte zeile
    backuprange = backup.getCellRangeByPosition(*size)
    backuprange.FormulaArray = inhalt
    stocksymbols = sheet.Columns.B.queryContentCells(7).getByIndex(0).DataArray
    stocksymbols = list(chain.from_iterable(stocksymbols))[1:]
    print(stocksymbols)
    out = []

    for line in get_stocks(stocksymbols):
        dt_string = '{0} {1}'.format(line[3],line[4])
        performed = tuple(chain(line[0:2], [dt_string, line[2]], line[5:]))
        out.append(performed)
    outrange = sheet.getCellRangeByPosition(0, 1, len(out[0])-1, len(out))    
    outrange.setFormulaArray(tuple(out))
 
und eine für AOO und Libreoffice 3.x
get-stockdata_apache.ods
Version für AOO und Libreoffice3
(81.39 KiB) 113-mal heruntergeladen

Code: Alles auswählen

from urllib import urlopen # python2 <--> LO3.x, AOO
import csv
from itertools import chain




yah_url =('http://finance.yahoo.com/d/quotes.csv?'
          's={}&f=nsl1d1t1c1ohgv&e=.csv'.format )

def get_stocks(symbols):
    url =yah_url('|'.join(symbols) )
    resonse = urlopen(url)
    content = response.read().decode('utf8')
    response.close()
    return csv.reader(content.splitlines())


def main(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    sheet = doc.CurrentSelection.Spreadsheet
    inhalt = sheet.queryContentCells(7).getByIndex(0).FormulaArray
    inhalt = inhalt[1:]
    backup = doc.Sheets.Backup
    filled = backup.queryContentCells(7).getByIndex(0)
    lastrow = filled.RangeAddress.EndRow
    size = (0, # erste Spalte
            lastrow+1,   # erste Zeile
            len(inhalt[0])-1, # letzte Spalte
            lastrow+len(inhalt)) #letzte zeile
    backuprange = backup.getCellRangeByPosition(*size)
    backuprange.FormulaArray = inhalt
    stocksymbols = sheet.Columns.B.queryContentCells(7).getByIndex(0).DataArray
    stocksymbols = list(chain.from_iterable(stocksymbols))[1:]
    print(stocksymbols)
    out = []

    for line in get_stocks(stocksymbols):
        dt_string = '{0} {1}'.format(line[3],line[4])
        performed = tuple(chain(line[0:2], [dt_string, line[2]], line[5:]))
        out.append(performed)
    outrange = sheet.getCellRangeByPosition(0, 1, len(out[0])-1, len(out))    
    outrange.setFormulaArray(tuple(out))
 
Karolus
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Antworten