Seite 1 von 1

Re: Mehrere Zellen Verketten?

Verfasst: Mo, 18.10.2010 21:12
von Karolus
Hallo
Lass dich von dem folgenden nicht abschrecken - so kompliziert ist es am Ende gar nicht.

1. Kopiere den Folgenden Code in ein neues Modul deiner Standard-bibliothek
( → Extras → Makros → Makros verwalten → OpenOffice.org_basic → Meine Makros.. → Standard →'Neu' )

Code: Alles auswählen

REM Keep a global reference to the ScriptProvider, since this stuff may be called many times:
Global g_MasterScriptProvider
REM Specify location of Python script, providing cell functions:

Const URL_Main = "vnd.sun.star.script:sheetFunction.py$"
Const URL_Args = "?language=Python&location=user"

'######____Schnittstelle zum Pythonscript___####

Function getMasterScriptProvider()
   if NOT isObject(g_MasterScriptProvider) then
      oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
      g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
   endif
   getMasterScriptProvider = g_MasterScriptProvider
End Function

'####################__Schnittstelle_ende__###### 

Function interpol( xrange, x , yrange )
   sURL = URL_Main & "interpol" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke(Array( xrange, x, yrange  ),Array(),Array())
   interpol = x
end Function

Function findall(data, regex,optional counts)
   sURL = URL_Main & "findall" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   if ismissing(counts) then
   		args() = array(data,regex)
   	else
   		args() = array(data,regex,counts)
   end if
   x = oScript.invoke( args(),Array(),Array())
   findall = x
end Function

Function multikette(data,optional vzeichen)
   sURL = URL_Main & "sjoin" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   if ismissing (vzeichen) then
   	x = oScript.invoke(Array(data),Array(),Array())
   else
   	x = oScript.invoke(Array(data, vzeichen),Array(),Array())
   end if
   multikette = x
end Function

Function quadriere(data)
   sURL = URL_Main & "quadriere" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke(Array(data),Array(),Array())
   quadriere = x
end Function

Function datatype(range)
   sURL = URL_Main & "datatype" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke(Array(range),Array(),Array())
   datatype = x
end Function

Function auswerten(range)
   sURL = URL_Main & "auswerten" & URL_Args
   oMSP = getMasterScriptProvider()
   oScript = oMSP.getScript(sURL)
   x = oScript.invoke(Array(range),Array(),Array())
   auswerten = x
end Function




2. Kopiere den folgenden Pythoncode in einen Texteditor deiner Wahl und speichere das Script in den Pfad:
( "dein OOobenutzerverzeichnis" )../3/user/Scripts/python/sheetFunction.py

Code: Alles auswählen

# -*- coding: utf-8 -*-

from __future__ import division
import sys
import uno
import re
from itertools.chain import from_iterable as flat
from bisect import bisect_left as left 
from math import *


zahlen = [ float , int ]

wrapper = uno.createUnoStruct('com.sun.star.script.ArrayWrapper')
wrapper.IsZeroIndex = False

def interpol( x_range, x , y_range ):
    """ Calcfunktion zur Rückgabe eines interpolierten y-werts aus den jeweiligen Nachbarwerten
        im y-Bereich, ermittelt aus den Verhältnissen eines x-wertes zu seinen Nachbarwerten
          siehe  http://www.ooo-portal.de/index.php?module=pnForum&func=viewtopic&topic=6055"""
    x_range = list( flat( x_range ) )
    y_range = list( flat( y_range ) )
    
    if x < min( x_range ) or x > max( x_range ):
        return "##oofRangeErr"
    
    if x in x_range:
        return y_range[ x_range.index(x) ]
    
    else:
        ri = left( x_range, x )
        li = ri-1
        ratio = ( x - x_range[li] ) / ( x_range[ri] - x_range[li] )
        return y_range[li] + ratio * ( y_range[ri] - y_range[li] )
    

def sjoin( datarange , joinstring = "" ):
    
    """ Calcfunktion zum verketten ganzer Zellbereiche,
        mit Bereichsadressangabe und mit der optionalen
        Möglichkeit eines Verbindungszeichens oder -Texts"""
    
    if isinstance (datarange, tuple): # cellranges always *nested* tuples       
        return joinstring.join("%s" % elem for elem in flat(datarange) if elem)
    else :
        return datarange    # a single cellvalue

    

def quadriere(data):
    
    """ Demo-funktion zum Quadrieren einzelner Zellen
        oder eines Zellbereiches als Arrayfunktion
        To be called through a StarBasic wrapper.
        ->Input_arg: cellrange or single cell
        --> Out: Range with same Dimension as Input."""
    
    if isinstance(data,tuple):    ## data is nestet tuple
        rows = []   ## build a resultrange with inputdimension
        for row in data:               
            rows.append(tuple( [ val**2  if type(val) in zahlen
                               else None for val in row]))
            
        ## we need the wrapper to make the 'right' datastructure
                                       ##    for poor old Basic
        wrapper.Array = tuple(rows)
        return wrapper
   
    if type(data) in zahlen:  ## here we catch the single numeric Inputs 
        return data **2 
    else:
        return None


def findall( stext , regex , imax=0):
    stext = "%s" %(stext)
    liste = re.findall( regex, stext )
    liste.extend([None]* max(0,(imax - len(liste))))                        
    wrapper.Array = tuple(liste)
    return wrapper

def auswerten( args ):
    
    """ simple demo-function
        to evaluate raw-string-expressions like 'x**2+4*y-z' in valid Pythonsyntax,
        'args' must be an cellrange of 4 with the contents :
                                                Expression, x_value, y_value, z_value.
        Values inside the expression must have a Decimal-Point not Decimal-komma ."""
    
    try:
        func, x, y, z = ( flat (args) ) # flat ? -> take a look into the 'import-lines'
        try:
            return eval( func )
        except:
            return '#args_Error'
    except :
        return '#Dim_Error'
    
3. Falls die zu verketteten Buchstaben in A2:A100 stehen rufst du die Funktion auf in der Syntax:

Code: Alles auswählen

=MULTIKETTE(INDIREKT("A2:A"&A1+1);"")
Falls die Buchstaben in Zeile2 ab A2 eingetragen sind dann:

Code: Alles auswählen

=MULTIKETTE(INDIREKT("A2:"&ADRESSE(2;A1;4));"")
Gruß Karo