web-dev-qa-db-fra.com

Renvoyer plusieurs valeurs d'une fonction, d'un sous-type ou d'un type?

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?

29
Kenny Bones

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
48
Michael Paulukonis

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?

17
Oneide

Idées:

  1. Utiliser passe par référence (ByRef)
  2. Construisez un type défini par l'utilisateur pour contenir les éléments que vous souhaitez renvoyer et les renvoyer.
  3. Similaire à 2 - construit une classe pour représenter les informations retournées et renvoie des objets de cette classe ...
12
Martin Milan

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.

8
dlm

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
3
Givi

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.

2
robotik

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).ToStringi 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
1
SilverShotBee

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
1

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
0
Nirr