2017-06-24 6 views
1

Application.Run Wenn in Excel-VBA-Programmierung, schalte ich oft aus Berechnung und ScreenUpdating (manchmal auch Displayalerts, etc.), einige langwierige Berechnungen, und schalten Sie sie zurück zu ihren vorherigen Zuständen (nicht notwendigerweise weil diese Funktionen sich gegenseitig aufrufen können). Deshalb hätte ich gerne einen Standardweg dafür.Excel VBA: Forward ParamArray

Es gibt keine Lambda-Funktionen in VBA aber Application.Run kann eine akzeptable Lösung sein, so kam ich zu diesem Code:

Public Function FastRun(strMacroQuoted As String, ParamArray varArgs() As Variant) As Variant 
    Dim blnOldScreenUpdating As Boolean: blnOldScreenUpdating = Application.ScreenUpdating 
    Application.ScreenUpdating = False 
    Dim clcOldCalculation As XlCalculation: clcOldCalculation = Application.Calculation 
    Application.Calculation = xlCalculationManual 

    FastRun = Application.Run(strMacroQuoted, varArgs(0)) 

    Application.Calculation = clcOldCalculation 
    Application.ScreenUpdating = blnOldScreenUpdating 
End Function 

Ich konnte alle Parameter aus varargs geben einen nach dem anderen zu starten (von 0 zu 29), und so würde mein FastRun die Anzahl der Parameter über das Limit nicht beschränken, das von Run festgelegt wird.

Meine Frage ist: Gibt es eine bessere (sauberere) -Lösung als 30 Parameter hintereinander zu schreiben?

Antwort

2

Es ist nicht klar, warum Sie Application.Run sind anrufen. Ich denke, es gibt zwei Möglichkeiten: 1. dass Sie eine Prozedur von einer anderen Arbeitsmappe oder einem Add-In aufrufen, oder 2. dass Sie aus irgendeinem Grund eine Prozedur in Ihrem aktuellen Projekt mit dem Namen aufrufen müssen, der als übergeben wurde ein Faden.

Vorausgesetzt, dass Sie mit der Struktur haften möchten alle Ihre Argumente über eine ParamArray in eine Routine vorbei, die dann Application.Run nennt, Ihre ‚run‘ Verfahren müsste ein Variant als Argument haben, statt einer ParamArray. Die ParamArray ist ein Array und die Variant würde als solche interpretiert, wenn sie bestanden wird. So würde der Code wie folgt aussehen:

Public Sub Main1() 
    CallingRoutine "MyRoutine", 1, 2, 3 
End Sub 

Public Sub CallingRoutine(routineName As String, ParamArray varArgs() As Variant) 
    Application.Run routineName, varArgs 
End Sub 

Public Sub MyRoutine(arr As Variant) 
     Debug.Print "Item 0 ="; arr(0) 
     Debug.Print "Item 1 ="; arr(1) 
     Debug.Print "Item 1 ="; arr(2) 
End Sub 

ich es vermuten Möglichkeiten besser sein könnte Ihre Aufgabe zu erreichen, und wenn Sie ein wenig mehr Details liefern konnte könnten wir in der Lage sein, Ihnen mehr zu helfen. Die wichtigsten Fragen wäre, warum brauchen Sie Ihre Routine von Application.Run zu nennen, wo der Code befindet und was sind die Variablen in Ihrem varArgs Array enthalten?

+0

Der Grund ist der zweite: Ich möchte die Prozedur mit ihrem Namen aufrufen. Wie ich geschrieben habe, möchte ich einen Standard-Weg haben, Subs 'zu beschleunigen'. Ich möchte die Anzahl der Parameter, die übergeben werden können, nicht einschränken, und ich hätte gern einen sauberen Code, ohne 30 Parameter einzeln aufzählen zu müssen. – z32a7ul

+0

Ok. Der obige Code sollte also für dich funktionieren. – Ambie

+0

Nun, ich akzeptiere dieses. Es führt eine Einschränkung ein: das aufgerufene Sub muss seine Parameter als variantes Array erhalten, also muss ich beim Schreiben des Subs daran denken, dass ich es später über FastRun aufrufen möchte. Aber ich habe keine bessere Lösung gefunden, die typisch für VBA ist. – z32a7ul

0

Geben von Parametern in einen Sub-Prozedur kann ByRef oder ByVal getan werden, aber vorbei Parameter (n) in eine Funktion ist immer ByVal. Es scheint, dass ByRef eine bessere Wahl wäre.

Option Explicit 

Sub main() 
    Dim a As Long, arr As Variant 
    ReDim arr(4) 

    For a = LBound(arr) To UBound(arr) 
     arr(a) = a 
    Next a 

    upByTen arr 

    For a = LBound(arr) To UBound(arr) 
     Debug.Print arr(a) 
    Next a 

End Sub 

Sub upByTen(ByRef myArr As Variant) 
    Dim i As Long 
    For i = LBound(myArr) To UBound(myArr) 
     myArr(i) = myArr(i) + 10 
    Next i 
End Sub 

'results from Immediate window 
10 
11 
12 
13 
14 
+0

Danke, aber wie kann ich dies auf Application.Run? – z32a7ul

+0

Falsch: Funktionen nehmen Parameter standardmäßig auch als ByRef. Und überhaupt, ich sehe nicht, wie diese Antwort mit meiner Frage verbunden ist. – z32a7ul