Je me demandais donc comment puis-je renvoyer plusieurs valeurs d'une fonction, d'un sous-type ou d'un type dans VBA? semble. Alors, comment puis-je renvoyer plusieurs à un sous?
Vous voudrez peut-être repenser la structure de votre application si vous voulez vraiment, vraiment, qu'une méthode renvoie plusieurs valeurs.
Soit vous séparez les éléments, de sorte que des méthodes distinctes renvoient des valeurs distinctes, soit vous établissez un regroupement logique et construisez un objet contenant les données qui peuvent à leur tour être renvoyées.
' this is the VB6/VBA equivalent of a struct
' data, no methods
Private Type settings
root As String
path As String
name_first As String
name_last As String
overwrite_Prompt As Boolean
End Type
Public Sub Main()
Dim mySettings As settings
mySettings = getSettings()
End Sub
' if you want this to be public, you're better off with a class instead of a User-Defined-Type (UDT)
Private Function getSettings() As settings
Dim sets As settings
With sets ' retrieve values here
.root = "foo"
.path = "bar"
.name_first = "Don"
.name_last = "Knuth"
.overwrite_Prompt = False
End With
' return a single struct, vb6/vba-style
getSettings = sets
End Function
Vous pouvez essayer de renvoyer une collection VBA.
Tant que vous traitez avec des valeurs de paire, telles que "Version = 1.31", vous pouvez stocker l'identifiant en tant que clé ("Version") et la valeur réelle (1.31) en tant qu'élément.
Dim c As New Collection
Dim item as Variant
Dim key as String
key = "Version"
item = 1.31
c.Add item, key
'Then return c
Accéder aux valeurs après c'est un jeu d'enfant:
c.Item("Version") 'Returns 1.31
or
c("Version") '.Item is the default member
Est-ce que ça fait du sens?
Idées:
Vous pouvez également utiliser un tableau variant comme résultat pour renvoyer une séquence de valeurs arbitraires:
Function f(i As Integer, s As String) As Variant()
f = Array(i + 1, "ate my " + s, Array(1#, 2#, 3#))
End Function
Sub test()
result = f(2, "hat")
i1 = result(0)
s1 = result(1)
a1 = result(2)
End Sub
Laide et sujet aux bogues parce que votre appelant a besoin de savoir ce qui est retourné pour utiliser le résultat, mais utile néanmoins.
Une fonction renvoie une valeur, mais elle peut "sortir" un nombre quelconque de valeurs. Un exemple de code:
Function Test (ByVal Input1 As Integer, ByVal Input2 As Integer, _
ByRef Output1 As Integer, ByRef Output2 As Integer) As Integer
Output1 = Input1 + Input2
Output2 = Input1 - Input2
Test = Output1 + Output2
End Function
Sub Test2()
Dim Ret As Integer, Input1 As Integer, Input2 As Integer, _
Output1 As integer, Output2 As Integer
Input1 = 1
Input2 = 2
Ret = Test(Input1, Input2, Output1, Output2)
Sheet1.Range("A1") = Ret ' 2
Sheet1.Range("A2") = Output1 ' 3
Sheet1.Range("A3") = Output2 '-1
End Sub
Pas élégant, mais si vous n'utilisez pas votre méthode de manière superposée, vous pouvez également utiliser des variables globales, définies par l'instruction Public au début de votre code, avant le Subs .. valeur publique, elle sera conservée tout au long de votre code dans toutes les sous-fonctions et fonctions.
Je retourne toujours plus d’un résultat d’une fonction en retournant toujours un ArrayList
. En utilisant un ArrayList
, je ne peux renvoyer qu'un seul élément, constitué de plusieurs valeurs multiples, mélangeant entre Strings
et Integers
.
Une fois que j'ai retourné la ArrayList
dans mon sous-dossier principal, j'utilise simplement ArrayList.Item(i).ToString
où i
est l'index de la valeur que je veux renvoyer de la ArrayList
Un exemple:
Public Function Set_Database_Path()
Dim Result As ArrayList = New ArrayList
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Open File Dialog"
fd.InitialDirectory = "C:\"
fd.RestoreDirectory = True
fd.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"
fd.FilterIndex = 2
fd.Multiselect = False
If fd.ShowDialog() = DialogResult.OK Then
Dim Database_Location = Path.GetFullPath(fd.FileName)
Dim Database_Connection_Var = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=""" & Database_Location & """"
Result.Add(Database_Connection_Var)
Result.Add(Database_Location)
Return (Result)
Else
Return (Nothing)
End If
End Function
Et appelez ensuite la fonction comme ceci:
Private Sub Main_Load()
Dim PathArray As ArrayList
PathArray = Set_Database_Path()
My.Settings.Database_Connection_String = PathArray.Item(0).ToString
My.Settings.FilePath = PathArray.Item(1).ToString
My.Settings.Save()
End Sub
vous pouvez renvoyer deux valeurs ou plus à une fonction de VBA ou à tout autre utilitaire Visual Basic, mais vous devez utiliser la méthode du pointeur appelée Byref Voir mon exemple ci-dessous. Je vais faire une fonction pour ajouter et soustraire 2 valeurs dire 5,6
sub Macro1
' now you call the function this way
dim o1 as integer, o2 as integer
AddSubtract 5, 6, o1, o2
msgbox o2
msgbox o1
end sub
function AddSubtract(a as integer, b as integer, ByRef sum as integer, ByRef dif as integer)
sum = a + b
dif = b - 1
end function
vous pouvez connecter toutes les données dont vous avez besoin du fichier à une seule chaîne, et dans la feuille Excel, séparez-les avec du texte en colonne .
Sub CP()
Dim ToolFile As String
Cells(3, 2).Select
For i = 0 To 5
r = ActiveCell.Row
ToolFile = Cells(r, 7).Value
On Error Resume Next
ActiveCell.Value = CP_getdatta(ToolFile)
'seperate data by "-"
Selection.TextToColumns Destination:=Range("C3"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:="-", FieldInfo:=Array(Array(1, 1), Array(2, 1)), TrailingMinusNumbers:=True
Cells(r + 1, 2).Select
Next
End Sub
Function CP_getdatta(ToolFile As String) As String
Workbooks.Open Filename:=ToolFile, UpdateLinks:=False, ReadOnly:=True
Range("A56000").Select
Selection.End(xlUp).Select
x = CStr(ActiveCell.Value)
ActiveCell.Offset(0, 20).Select
Selection.End(xlToLeft).Select
While IsNumeric(ActiveCell.Value) = False
ActiveCell.Offset(0, -1).Select
Wend
' combine data to 1 string
CP_getdatta = CStr(x & "-" & ActiveCell.Value)
ActiveWindow.Close False
End Function