Microsoft Excel

Herbers Excel/VBA-Archiv

Informationen und Beispiele zum Thema MsgBox
BildScreenshot zu MsgBox MsgBox-Seite mit Beispielarbeitsmappe aufrufen

Function durch Übergabeparameter aufrufen

Betrifft: Function durch Übergabeparameter aufrufen von: Malte
Geschrieben am: 02.10.2014 22:42:27

Hallo!

ich würde gerne folgende Idee umsetzen.

Ich würde gerne den Namen der Funktion übergeben, die ich aufrufen möchte.
Im moment habe ich das ganze so gelöst, dass ich für Funktion A eine 0 übergebe und für Funktion B eine 1. Dann frage ich per If-Else-Abfrage ab, welchen Wert der Übergabeparameter hat. Je nachdem wird dann Funktion A bzw. B ausgeführt.

Sub Beispiel(Variante As Integer)
dim test1 as integer, Wert as integer
    

            If Variante = 0 Then
                test1 = Funktion_A(Wert)
            ElseIf Variante = 1 Then
                test1 = Funktion_B(Wert)
            End If
        
            If Variante = 0 Then
                Cells(16, 10) = test1
                Cells(16, 12) = Wert
            ElseIf Variante = 1 Then
                Cells(16, 15) = test1
                Cells(16, 17) = Wert
            End If
End Sub
Dieses Beispiel würde ich gerne eleganter lösen (siehe unten), wobei mir für die Ausgabe noch nichts eingefallen ist:
Sub test(Funktionsname as String)
dim test1 as integer, wert as integer


test1 = Funktionsname(Wert)

End Sub
Wie könnte man das lösen, bzw. geht das überhaupt?

Vielen Dank!

Gruß
Malte

  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Ewald
Geschrieben am: 03.10.2014 01:35:42

Hallo Malte,

eine funktion wird immer über ihren Namen und ihre Parameter aufgerufen.

in der Sub die Funktionen aufruft, übergibst du dann richtig

If x = 7 Then a = MWST7(Wert)
If x = 19 Then a = MWST19(Wert)

hier eine Variable für den Funktionsnamen zu verwenden ist doch Unsinn.

Gruß Ewald


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Malte
Geschrieben am: 03.10.2014 11:38:10

Hallo,

ich wollte halt den Code etwas verkürzen, das sah so unelegant aus mit den selben Befehlen und der If-Abfrage ;)

Danke!


  

Betrifft: Naja, weiß ja nicht wofür DU das benötigst, ... von: Luc:-?
Geschrieben am: 03.10.2014 09:05:09

…Malte,
ich hatte für Ähnliches schon sinnvollen Bedarf, aber es geht im Prinzip, nur nicht so, denn hierbei würde es sich um eine (erst zur Laufzeit wirksame) sog CallByName-Referenzierung handeln, die in VBA per gleichnamiger vbFkt bewerkstelligt wdn kann. Allerdings ist es dazu erforderlich, ein Objekt anzugeben, dem die Fkt (als Methode) zugeordnet wdn kann. Folglich müssen solche Fktt in einem KlassenModul notiert wdn (ein DokumentK-Modul der Mappe reicht schon).
Allerdings halte ich deine Test-SubProzedur für ungeeignet, denn die müsste ja durch eine weitere Prozedur aufgerufen wdn, denn direkt (auch nicht per Button!) kann man in Xl-VBA keine Prozedur mit ParameterÜbergabe aufrufen, was dann wieder auf (Select Case mit den) FktsNamen in vordefinierten Konstanten hinauslaufen würde. Man kann aber auch eine benannte Konstante in der Mappe definieren, der der jeweilige FktsName zuvor als Text übergeben wdn muss und in der SubProzedur auf diesen zugreifen.
Morrn, Luc :-?


  

Betrifft: AW: Naja, weiß ja nicht wofür DU das benötigst, ... von: Malte
Geschrieben am: 03.10.2014 11:37:02

Hallo,

ich glaube das ist ein Level zu hoch für mich ;)

Dennoch danke! :D


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Luschi
Geschrieben am: 03.10.2014 10:51:26

Hallo Malte,

das funktioniert so:

Sub machmal()
    Dim v As Variant
    v = Application.Run("Func_A", 1)
    MsgBox v
    v = Application.Run("Func_B", 2)
    MsgBox v
End Sub

Function Func_A(i As Integer)
    Func_A = 10 * i
End Function

Function Func_B(i As Integer)
    Func_B = 12 * i
End Function
Gruß von Luschi
aus klein-Paris

PS: Sowas ist das nötig, wenn sich erst zur Laufzeit des Makros feststeht / berechnen läßt etc., welche Funktion jetzt angewendet werden soll. Das funktioniert auch über geöffnete Arbeitsmappen/AddIns hinweg.
In Vb.Net bzw. C# nennt man sowas 'Delegate'.


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Malte
Geschrieben am: 03.10.2014 11:36:30

Hallo,

vielen Dank für all Eure Antworten!


Das mit dem Application.Run erfüllt meine Zwecke voll und Ganz!

Vielen Dank!

Gruß

Malte


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Malte
Geschrieben am: 03.10.2014 11:42:27

Ups!

da war ich etwas voreilig.

Ich dachte ich kann nun wie folgt vorgehen:

Sub tu_etwas()
 call machmal("Func_A")
End Sub
Sub machmal(dim Funktionsname as String)
    Dim v As Variant
    v = Application.Run(Funktionsname, 1)
    msgbox v
End Sub

Function Func_A(i As Integer)
    Func_A = 10 * i
End Function

Function Func_B(i As Integer)
    Func_B = 12 * i
End Function
Aber das geht leider nicht :-(

Gruß
Malte


  

Betrifft: Ich bin ein Idiot. Wird Zeit zum Mittag! von: Malte
Geschrieben am: 03.10.2014 11:44:31

Geht, Danke!


  

Betrifft: Das ist auch die einzige Alternative zu CbN, ... von: Luc:-?
Geschrieben am: 03.10.2014 16:35:25

…Malte,
weil hier der FktsName als Text eingetragen wdn kann, was letzlich ebenfalls der ByName-Referenzierung entspricht, aber mit Application als Parent-Objekt. Das findet man übrigens auch im ForumsArchiv!
Trotzdem solltest du dich irgendwann mal damit befassen… ;-]
Luc :-?


  

Betrifft: ...Allerdings würde das mit CbyN nicht fktion, ... von: Luc:-?
Geschrieben am: 03.10.2014 17:07:17

…Malte,
wenn die Fkt nicht in einem Klassenmodul steht. Hier leistet Run also noch etwas mehr interne Arbeit. Aber trotzdem hier mal zum Vgl ein kurzes Bsp mit beiden Varianten:
In normalem Modul:

Option Explicit

Function TNum1(Bezug)
    TNum1 = IsNumeric(Bezug)
End Function

Sub Test1()
    Const fn$ = "tnum1"
    MsgBox Run(fn, Cells(1))
End Sub

Sub Test2()
    Const fn$ = "tnum2"
    MsgBox CallByName(DieseArbeitsmappe, fn, VbMethod, Cells(1))
End Sub
Im Klassenmodul der Mappe DieseArbeitsmappe dann die Fkt TNum2:
Option Explicit

Function TNum2(Bezug)
    TNum2 = Array("nein", "ja")(Abs(IsNumeric(Bezug) And Not IsEmpty(Bezug)))
End Function
Jetzt nur noch in A1 des aktiven Blattes etwas eintragen (oder auch nicht, auch mal #NV) und mal die eine, mal die andere Test-Prozedur aufrufen (der Unterschied in der AW beider liegt allerdings nur an der FktsPgmierung!)…
Luc :-?


  

Betrifft: Ergänzg: Statt des InternNamens der Mappe ... von: Luc:-?
Geschrieben am: 03.10.2014 17:17:40

…(dt Standard DieseArbeitsmappe bzw eine eigene Umbenennung) kann in Test2 selbstverständlich auch ein üblicher Verweis auf das Parent-Objekt der Fkt TNum2 wie Workbooks("xyz"), hier auch ThisWorkbook und ActiveWorkbook, erfolgen.
Luc :-?


  

Betrifft: AW: Ergänzg: Statt des InternNamens der Mappe ... von: Malte
Geschrieben am: 04.10.2014 11:01:08

Hallo,

vielen Dank für die Erläuterungen.

Ich setz mich mal ran ;)

Gruß
Malte!


  

Betrifft: AW: Warum eigentlich? von: Luschi
Geschrieben am: 03.10.2014 19:00:50

Hallo Luc,

bisher habe ich diese Möglichkeit eigentlich nur selten benutzt. Selbst die neuesten deutschsprachigen Excel 2013-Vba-Bücher machen einen großen Bogen darum. Im M$-Press-Verlag erschnienenen Buch von Mourad Louha/Monika Weber gibt es die Funktion CallByName() überhaupt nicht und im Buch vom Hanser-Verlag von Michael Kofler/Ralf Nebelo nur ein paar Zeilen, ohne daß man erahnen könnte, hier eine 'wichtige' Funktionionalität zu verpassen.
Die Online Hilfe zu dieser Funktion:
http://msdn.microsoft.com/de-de/library/office/gg278760%28v=office.15%29.aspx
gibt wenig her, denn nicht mal die vbCallType-Konstanten sind aufgeführt und muß man sich wie so oft erst ergOOgeln. Die Beispiele, die ich im I-Net gefunden habe sind auch nicht berauschend und für mein Beispiel muß ich extra ein Klassenmodul erstellen, darin die Funktionen hinterlegen, dann ein Objekt der Klasse erzeugen und so aufrufen:
Dim myClass As New myClass
v = CallByName(myClass, "Func_A", vbMethod, 1)
Selbst der von Hajo in Beispielen gern benutzte Aufruf:

If CallByName(Target, IIf(Val( _
            Application.Version) > 11, "CountLarge", "Count"), VbGet) = 1 Then
braucht man nicht, da Target.Count ausreicht, ob mehr als eine Zelle im Spiel ist - aber schön gewaltig sieht der Aufruf ja aus.
Geschwindigkeitsmäßig liegen aber 'Application.Run' & 'CallByName' gleichauf, obwohl der Overhead bei letzterer Funktion größer ist.

Gruß von Luschi
aus klein-Paris



  

Betrifft: Das hängt ganz davon ab, ob und wie tief man ... von: Luc:-?
Geschrieben am: 03.10.2014 20:29:57

…in VBA eindringen bzw bestimmte Möglichkeiten nutzen will bzw muss, Luschi;
was Hajo betrifft, halte ich das auch für überflüssig (ggf will er nur zeigen, dass er es kennt). Ich habe so aber mal eine Fkt (als AGGREGAT-Alternative) geschrieben, die neben einer gewissen Menge vorgesehener auch jede andere WorksheetFunction verwenden kann, sofern ihre Argumentierung zu den Rahmen­Bedingungen der „MutterFkt“ passt. Man kann so (zumindest zT) auf Select Case-Konstrukte verzichten. Außerdem befindet sich im Archiv ein PgmBsp von mir zur Kryptisierung bestimmter PgmVorgänge, in dem ich die ReferenzierungsFkt/-Methode CbyN im Zusammenspiel mit einer Krypt-Fkt eingesetzt hatte (Verschlei­erung aufge­rufe­ner/ver­wen­deter Fktt/Variablen).
Das viele VBA-Literaten das weglassen, mag daran liegen, dass sie meist für Einsteiger schreiben bzw ggf selbst wenig Erfahrung damit haben. Letztlich handelt es sich hierbei aber um eine Referen­zierungs­art (Wikipedia gibt dazu mehr her), die seit langem eingeführt ist, obwohl viele Sprachen darauf verzichten, weil so etwas nicht vorkompiliert wdn kann.
Gruß, Luc :-?


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Ewald
Geschrieben am: 03.10.2014 14:28:23

Hallo,

das ist ja kein Aufruf des Funktionsnamen,sondern der Funktion selbst.

denn

v = Application.Run("Func_A", 1)
ist nichts anderes wie
v = Func_A(1)
Selbst bei unterschiedlichen Funktionen ist die Stringübergabe des Funktionsnamen unnötig
Sub machmal2()
    Dim v As Variant
    Dim x As String
    Dim y As Double
    Dim Wert As Integer
    y = 2
    Wert = 6
    If y = 1 Then x = "Func_A"
    If y = 2 Then x = "Func_B"
    
    v = Application.Run(x, Wert)
    MsgBox v
    If y = 1 Then v = Func_A(Wert)
    If y = 2 Then v = Func_B(Wert)
    MsgBox v
End Sub
Gruß Ewald


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Luschi
Geschrieben am: 03.10.2014 16:05:32

Hallo Ewald,

meine kleine Demo-Variante ist sicher sehr einfach gestrickt und deshalb kann man es so vereinfachen. In der Praxis aber wird der Sub-/Funktionsname als Textkette in einer Unterprozedur anhand von Kriterien zusammengebaut, aber nicht dort auch als Sub/Function aufgerufen. Das passiert in einer ganz anderen Routine oder wird an ein AddIn durchgereicht.

Gruß von Luschi
aus klein-Paris


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Ewald
Geschrieben am: 03.10.2014 18:57:07

Hallo Luschi,

mir ist schon klar was du meinst, nur ist das in den meisten Fällen nicht notwendig.

Im obigen Fall ist es überhaupt nicht notwendig mit zwei Funktionen zu arbeiten.

Gibst du der Funktion noch einen weiteren Parameter mit, kommst du mit einer Funktion aus.

Dieser Parameter bestimmt dann was als Funktionswert ausgegeben wird.

Die Berechnung passiert dann genau da wo sie hingehört, in der Funktion.

Bei Fehlern brauch dann nur die Funktion überprüft werden und nicht noch zusätzliche Subs die vorrangige Berechnungen anstellen.

Gruß Ewald


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Malte
Geschrieben am: 04.10.2014 11:12:50

Hallo,

ich kann deiner Darstellung nicht so richtig folgen.
Ich rufe ja aus einer Sub, je nachdem was ich berechnen möchte, eine Funktion A oder eine Funktion B auf.
Beide berechnen unterschiedliche Sachen, sodass ich auch mit einem Parameter mehr nicht auskomme.

Mir ging es nur darum, dass ich für mich fand, dass die If-Abfrage "unelegant" ist und ich das ganze gerne in einer Zeile gelöst haben wollte, da sich ja eigl. nur der Funktionsname im Aufruf ändert.

Die Gesamtstruktur des VBA Codes sieht nun wie folgt aus:

Sub start()
dim a as double, b as double

a=cells(1,1)
b=cells(2,1)

call vergleich(a,b,"Variante_1")
call vergleich(a,b,"Variante_2")

End Sub
Sub vergleich(a as double, b as double, Variante as string)
dim ergebnis as double

'Hier läuft noch eine Iteration ab, bei der ich den Inhalt von "ergebnis" benötige.

ergebnis=Application.Run(Variante,a,b)

case select Variante
  case "Variante_1"
      ergebnis=cells(4,1)
  case "Variante_2"
      ergebnis=cells(4,2)
end select

End Sub

Function Variante_1(a as double, b as double)
 Variante_1=a*b
End Function

Function Variante_2(a as double, b as double)
 Variante_2=a+b
End Function

Vielen Dank für Eure Hilfe!

Gruß

Malte!


  

Betrifft: AW: Function durch Übergabeparameter aufrufen von: Ewald
Geschrieben am: 04.10.2014 11:44:05

Hallo Malte,

hier ein einfaches Beispiel mit einer Function aber mehreren Ergebnissen(aktuell 2)

Sub Tuwas()
Dim v As Integer
Dim y As Integer
Dim i As Integer
y = 2
i = 3
v = Func_AB(i, y)
MsgBox v
y = 1
i = 5
v = Func_AB(i, y)
MsgBox v
End Sub

Function Func_AB(i As Integer, BM As Integer) As Integer
    Select Case BM
    Case 1
    Func_AB = 10 * i
    Case 2
     Func_AB = 12 * i
     End Select
End Function
durch den Parameter BM kannst du mehrere verschiedene Ergebnisse mit einer Function ausgeben

Gruß Ewald


 

Beiträge aus den Excel-Beispielen zum Thema "Function durch Übergabeparameter aufrufen"