2011-03-17 15 views
25

तो मैं सोच रहा था, मैं एक समारोह, उप या VBA में टाइप से कई मान कैसे वापस कर सकता हूं? मुझे यह मुख्य उप मिला है जो कई कार्यों से डेटा एकत्र करना है, लेकिन एक फ़ंक्शन केवल एक मान को वापस कर सकता है। तो मैं एकाधिक को एक सब में कैसे वापस कर सकता हूं?किसी फ़ंक्शन, उप या प्रकार से एकाधिक मान लौटाएं?

उत्तर

41

आप, आप आवेदन की संरचना पर पुनर्विचार करने की अगर तुम सच में, सच एक चाहते हैं चाहते हो सकता है कई मान वापस करने के लिए विधि।

या तो चीजों को तोड़ दें, इसलिए अलग-अलग विधियां अलग-अलग मान लौटती हैं, या तार्किक समूह को समझती हैं और उस डेटा को पकड़ने के लिए ऑब्जेक्ट का निर्माण करती हैं जो बदले में वापस आ सकती है।

' 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 
+0

मैं एक आईएनआई फ़ाइल में संग्रहीत कई सेटिंग्स के मान वापस करने की कोशिश कर रहा हूं। मैं उनमें से प्रत्येक के लिए एक समारोह लिख सकता था, लेकिन मैंने सोचा कि एक बनाना बेहतर होगा। या अधिक कुशल। यकीन नहीं है कि यह हालांकि होगा। –

+0

आप गलत तरीके से सोच रहे हैं। एक विधि एक चीज देता है। क्या यह एक चीज परमाणु मूल्य है (32, "सी: \ रूट", सत्य, आदि), या यह एक वस्तु है जिसमें एकाधिक मान हैं ({चौड़ाई: 32, पथ: "सी: \ रूट", प्रॉम्प्टफॉर ओवरराइट: सत्य})। आप एक प्रोग्रामर हैं - आपको इन चीजों के बारे में सोचना होगा, और तदनुसार अपने आवेदन को डिजाइन करना होगा। –

+0

मैं एक डिजाइनर और सामान्य आईटी-तकनीशियन हूं और मैं बस प्रोग्रामिंग सीखने की कोशिश कर रहा हूं। वीबीए माइक्रोसॉफ्ट ऑफिस अनुप्रयोगों के कारण है और ऐसी चीजें हैं जिन्हें मैं अभी तक नहीं जानता हूं। जिन मूल्यों को मैं वापस करने का प्रयास कर रहा हूं वह केवल आईएनआई फ़ाइल से मूल स्ट्रिंग मान हैं। कुछ भी फैंसी या कुछ नहीं और उन्हें तारों के रूप में भी वापस किया जा सकता है। –

12

विचार: पास

  1. उपयोग संदर्भ द्वारा (ByRef)
  2. बिल्ड एक उपयोगकर्ता निर्धारित प्रकार सामान वापस करना चाहते रखें, और लौटने कि करने के लिए।
  3. इसी प्रकार से 2 - एक वर्ग का निर्माण जानकारी लौटे प्रतिनिधित्व करते हैं, और उस वर्ग की वस्तुओं लौटने के लिए ...
+0

क्या आपके पास दूसरे विचार के कोई उदाहरण हैं? मुझे लगता है कि मुझे वही चाहिए जो मुझे चाहिए। –

+4

@ केनी, 'टाइप' कथन के लिए मदद देखें। यह आपको शुरू करना चाहिए। – jtolle

15

आप एक वीबीए संग्रह वापस करने का प्रयास कर सकते हैं।

जब तक आप "संस्करण = 1.31" जैसे जोड़ी मानों से निपटते हैं, तो आप पहचानकर्ता को एक कुंजी ("संस्करण") और वास्तविक मान (1.31) के रूप में आइटम के रूप में स्टोर कर सकते हैं।

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 

मूल्यों को एक्सेस करना उसके बाद यह एक हवा है:

c.Item("Version") 'Returns 1.31 
or 
c("Version") '.Item is the default member 

यह मतलब है?

8

तुम भी मनमाने ढंग से मूल्यों का एक अनुक्रम वापस जाने के लिए वापसी परिणाम के रूप में एक प्रकार सरणी का उपयोग कर सकते हैं:

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 

बदसूरत और बग का खतरा है क्योंकि आपके फोन करने वाले को पता है कि परिणाम का उपयोग करने के लिए लौट जा रहा है की जरूरत है, लेकिन कभी-कभी फिर भी उपयोगी।

2

सुरुचिपूर्ण नहीं है, लेकिन यदि आप अपनी विधि का उपयोग ओवरलैपली से नहीं करते हैं तो आप सब्सक्रिप्शन से पहले अपने कोड की शुरुआत में सार्वजनिक कथन द्वारा परिभाषित वैश्विक चर का भी उपयोग कर सकते हैं। आपको सावधान रहना होगा, एक बार जब आप सार्वजनिक मूल्य बदल लेते हैं, तो यह आपके सभी कोड को सभी सब्स और फ़ंक्शंस में आयोजित किया जाएगा।

2

एक फ़ंक्शन एक मान देता है, लेकिन यह किसी भी संख्या में "आउटपुट" कर सकता है। एक नमूना कोड:

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 
0

आप सभी डेटा आप एक ही स्ट्रिंग के लिए फ़ाइल से जरूरत से कनेक्ट कर सकता है, और एक्सेल शीट में यह स्तंभ के लिए पाठ के साथ अलग। यहाँ एक उदाहरण मैं एक ही मुद्दे के लिए किया है, का आनंद लें:

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 
1

आप VBA या किसी अन्य दृश्य बुनियादी सामान में एक समारोह के लिए 2 या अधिक मान लौट सकते हैं लेकिन आप ByRef बुलाया सूचक विधि का उपयोग करने की जरूरत है। नीचे मेरा उदाहरण देखें।मैं 2 मान का कहना है कि 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

मैं हमेशा एक समारोह से एक से अधिक परिणाम लौटने हमेशा एक ArrayList वापस लौट कर दृष्टिकोण जोड़ने और घटाने के लिए एक समारोह कर देगा। ArrayList का उपयोग करके मैं केवल एक आइटम लौटा सकता हूं, जिसमें कई एकाधिक मान शामिल हैं, Strings और Integers के बीच मिश्रण।

है एक बार मैं ArrayList मेरी मुख्य उप में लौट आए, मैं बस ArrayList.Item(i).ToString जहां i मूल्य के सूचकांक मैं ArrayList

एक उदाहरण से लौटना चाहते है का उपयोग करें:

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 

और फिर इस तरह के फ़ंक्शन को कॉल करें:

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