Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: VB funktion palautusarvoksi olio taulukko?

Pietu82 [19.10.2009 13:40:50]

#

Hei. Olen keskinkertainen koodarinalku, joka haluaa ratkoa kaikenlaista työkamaa lähinnä vba:n ja autocadin avulla. Erääseen ongelmaan olen törmännyt jota en osaa ratkaista, nimittäin olio-arvoisen taulukon palauttamista funktiosta. Myöskään en ole löytänyt mistään valmista ratkaisua. Seuraavanlainen "pseudo-koodi" ei ainakaan toimi. Tietääköhän joku, onko dynaamisen kokoista object-arrayta edes mahdollista palauttaa funktiosta?

Ei toimi:

Dim oliot() As Object

Set oliot() = palautaOliot("parametrejä")

Function palautaOliot(parametreja As String) As Object()
    for i=0 To 3
       palautaOliot(i) = New Object
    next i
end function

Ei tietenkään toimi, mutta voisiko toimia variant-tyyppisellä palautusarvona, siis jos funktion määrittelyssä olisi As Object():n tilalla As Variant?

Mod. lisäsi kooditagit

Grez [19.10.2009 14:53:22]

#

Toimii. Äkkiähän olisit itsekin sen testannut.

Pietu82 [19.10.2009 16:34:21]

#

Ehkä en ole aivan perillä näistä visual basicin versioista. Käytössäni on vba joka toimii autocad 2010 sisällä. Edellä oleva koodi ei mielestäni toimi siinä. Ainoa toimiva tapa mielestäni on VBA:ssa tehdä kaikki liittyvät muuttujat variant-tyyppisiksi, alla olevan koodin mukaisesti. (Toimiva ratkaisu, muttei kovin elegantti)

Sub olionPalautus()
    Dim oliot As Variant
    oliot = palautaOliot("parametrejä")
End Sub

Function palautaOliot(parametreja As String) As Variant
    Dim k As Integer
    Dim olioita(0 To 2) As Variant
    For k = 0 To 2
        olioita(k) = New excel.Application
    Next k

    palautaOliot = olioita
End Function

Olen käsittänyt, että hyvä ohjelmoija ei käytä variant-tietotyyppiä juurikaan. Sen käyttäminen on kuitenkin VBA:ssa näköjään varsin tarpeellista. Tietääkö kukaan, onko tämä olioiden toiminta sitten jotenkin "parempaa" jossain muussa visual basic-ympäristössä?

Grez [19.10.2009 17:12:15]

#

Minulla kyllä toimii tuo koodisi suoraan VBA:ssa joka sisältyy uusimpaan Exceliin (VBA 6.5.1040)

Ainakin VB.Netillä onnistuu Object-taulukon palautus suoraan. VBA:ssakin onnistuisi jos se ymmärtäisi syntaksin oikein.

Pietu82 [19.10.2009 17:59:39]

#

No, jos minä ajan alla olevan koodin (VBA 6.5.1024), tulee virheilmoitus, "Compile error: can't assign to array"

Sub oliot()
    Dim oliot() As Object
    Set oliot() = palautaOliot("parametrejä")
End Sub


Function palautaOliot(parametreja As String) As Object()
    For i = 0 To 3
        palautaOliot(i) = New Excel.Application
    Next i
End Function

Onpa outoa, että toisilla toimii, toisilla ei. Toisaalta visual basicin tyyppipakotus ei toimi myöskään vba:ssa, joten en ihmettelisi vaikka muutenkaan ei oikein toimi. Esim. jos oliot taulukko on variant-tyyppinen, VBA:ssa siitä ei saa myöhemmin pakotettua object-tyyppistä.. Vai saako jotenkin kikkailemalla?

Grez [19.10.2009 20:20:57]

#

No sama virhe minullakin tulee tuosta, mutta ei se ole sama koodi kuin edellisessä viestissäsi.

Tuo Can't assign to array ei liity mitenkään siihen, mitä funktio palauttaa, vaan ainoastaan siihen että et voi sijoittaa taulukkoa toiseen taulukkoon tuolla tavalla. Avain sama vaikka olisit tehnyt sen funktion palauttaman taulukon paikallisesti.

Sitten tuosta palautaOliot funktiosta tulisi myös virheilmoitus "Function call on left-hand side of assignment must return variant or Object" ja tämä johtuu tuosta mitä sanoin, että VBA ei ymmärrä tuossa tapauksessa kirjoittamaasi syntaksia oikein (siis niinkuin olet sen tarkoittanut) vaan tulkitsee palautaOliot(i) kohdassa että funktio kutsuisi itseään.

Itse asiassa, saahan tuon palauttamaan objektitaulukon kun vähän käskee.

Function palautaOliot(parametreja As String) As Object()
    ReDim palautaOliot(3)
    Dim i As Long
    For i = 0 To 3
        PutInObjectArray palautaOliot, i, New Excel.Application
    Next i
End Function
Private Sub PutInObjectArray(ObjectArray() As Object, Index As Long, MyObject As Object)
    Set ObjectArray(Index) = MyObject
End Sub

Ja tästä päästäänkin sitten siihen, että olisi paljon helpompaa vaan antaa se taulukko parametrina kutsuvasta funktiosta.

Sub Oliot()
    Dim res As Variant
    Dim Oliot() As Object
    palautaOliot "parametrejä", Oliot
End Sub
Sub palautaOliot(parametreja As String, Oliot() As Object)
    ReDim Oliot(3)
    Dim i As Long
    For i = 0 To 3
        Set Oliot(i) = New Excel.Application
    Next i
End Sub

Pietu82 [19.10.2009 22:52:08]

#

Mahtavaa. Kiitos! En ole ennen uskaltautunut kyselemään tällaisia pieniä koodijuttuja, mutta täytyy sanoa että kyllä olis kannattanut, eikä hakata päätä seinään.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta